forked from Bananymous/banan-os
				
			LibC: Implement recvmsg and sendmsg
These just wrap recvfrom and sendto so ancillary data is not supported
This commit is contained in:
		
							parent
							
								
									de45b760b5
								
							
						
					
					
						commit
						31e411f8f1
					
				|  | @ -1,3 +1,6 @@ | ||||||
|  | #include <BAN/Debug.h> | ||||||
|  | 
 | ||||||
|  | #include <errno.h> | ||||||
| #include <pthread.h> | #include <pthread.h> | ||||||
| #include <sys/socket.h> | #include <sys/socket.h> | ||||||
| #include <sys/syscall.h> | #include <sys/syscall.h> | ||||||
|  | @ -33,7 +36,7 @@ int listen(int socket, int backlog) | ||||||
| 
 | 
 | ||||||
| ssize_t recv(int socket, void* __restrict buffer, size_t length, int flags) | ssize_t recv(int socket, void* __restrict buffer, size_t length, int flags) | ||||||
| { | { | ||||||
| 	pthread_testcancel(); | 	// cancellation point in recvfrom
 | ||||||
| 	return recvfrom(socket, buffer, length, flags, nullptr, nullptr); | 	return recvfrom(socket, buffer, length, flags, nullptr, nullptr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -53,7 +56,7 @@ ssize_t recvfrom(int socket, void* __restrict buffer, size_t length, int flags, | ||||||
| 
 | 
 | ||||||
| ssize_t send(int socket, const void* message, size_t length, int flags) | ssize_t send(int socket, const void* message, size_t length, int flags) | ||||||
| { | { | ||||||
| 	pthread_testcancel(); | 	// cancellation point in sendto
 | ||||||
| 	return sendto(socket, message, length, flags, nullptr, 0); | 	return sendto(socket, message, length, flags, nullptr, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -71,6 +74,74 @@ ssize_t sendto(int socket, const void* message, size_t length, int flags, const | ||||||
| 	return syscall(SYS_SENDTO, &arguments); | 	return syscall(SYS_SENDTO, &arguments); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | ssize_t	recvmsg(int socket, struct msghdr* message, int flags) | ||||||
|  | { | ||||||
|  | 	if (CMSG_FIRSTHDR(message)) | ||||||
|  | 	{ | ||||||
|  | 		dwarnln("TODO: recvmsg ancillary data"); | ||||||
|  | 		errno = ENOTSUP; | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	size_t total_recv = 0; | ||||||
|  | 
 | ||||||
|  | 	for (int i = 0; i < message->msg_iovlen; i++) | ||||||
|  | 	{ | ||||||
|  | 		const ssize_t nrecv = recvfrom( | ||||||
|  | 			socket, | ||||||
|  | 			message->msg_iov[i].iov_base, | ||||||
|  | 			message->msg_iov[i].iov_len, | ||||||
|  | 			flags, | ||||||
|  | 			static_cast<sockaddr*>(message->msg_name), | ||||||
|  | 			&message->msg_namelen | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		if (nrecv < 0) | ||||||
|  | 			return -1; | ||||||
|  | 
 | ||||||
|  | 		total_recv += nrecv; | ||||||
|  | 
 | ||||||
|  | 		if (static_cast<size_t>(nrecv) < message->msg_iov[i].iov_len) | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return total_recv; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ssize_t	sendmsg(int socket, const struct msghdr* message, int flags) | ||||||
|  | { | ||||||
|  | 	if (CMSG_FIRSTHDR(message)) | ||||||
|  | 	{ | ||||||
|  | 		dwarnln("TODO: sendmsg ancillary data"); | ||||||
|  | 		errno = ENOTSUP; | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	size_t total_sent = 0; | ||||||
|  | 
 | ||||||
|  | 	for (int i = 0; i < message->msg_iovlen; i++) | ||||||
|  | 	{ | ||||||
|  | 		const ssize_t nsend = sendto( | ||||||
|  | 			socket, | ||||||
|  | 			message->msg_iov[i].iov_base, | ||||||
|  | 			message->msg_iov[i].iov_len, | ||||||
|  | 			flags, | ||||||
|  | 			static_cast<sockaddr*>(message->msg_name), | ||||||
|  | 			message->msg_namelen | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		if (nsend < 0) | ||||||
|  | 			return -1; | ||||||
|  | 
 | ||||||
|  | 		total_sent += nsend; | ||||||
|  | 
 | ||||||
|  | 		if (static_cast<size_t>(nsend) < message->msg_iov[i].iov_len) | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return total_sent; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int socket(int domain, int type, int protocol) | int socket(int domain, int type, int protocol) | ||||||
| { | { | ||||||
| 	return syscall(SYS_SOCKET, domain, type, protocol); | 	return syscall(SYS_SOCKET, domain, type, protocol); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue