Add recvmsg(2) and sendmsg(2).

This commit is contained in:
Jonas 'Sortie' Termansen 2014-01-16 20:46:56 +01:00
parent c5fa54aa08
commit 708bcb4735
5 changed files with 62 additions and 10 deletions

View File

@ -163,6 +163,8 @@
#define SYSCALL_SIGPENDING 135
#define SYSCALL_SIGPROCMASK 136
#define SYSCALL_SIGSUSPEND 137
#define SYSCALL_MAX_NUM 138 /* index of highest constant + 1 */
#define SYSCALL_SENDMSG 138
#define SYSCALL_RECVMSG 139
#define SYSCALL_MAX_NUM 140 /* index of highest constant + 1 */
#endif

View File

@ -22,6 +22,7 @@
*******************************************************************************/
#include <sys/socket.h>
#include <sys/types.h>
#include <assert.h>
@ -968,6 +969,47 @@ static int sys_mkpartition(int fd, off_t start, off_t length, int flags)
return CurrentProcess()->GetDTable()->Allocate(partition_desc, fdflags);
}
static ssize_t sys_sendmsg(int fd, const struct msghdr* user_msg, int flags)
{
struct msghdr msg;
if ( !CopyFromUser(&msg, user_msg, sizeof(msg)) )
return -1;
// TODO: MSG_DONTWAIT and MSG_NOSIGNAL aren't actually supported here!
if ( flags & ~(MSG_EOR | MSG_DONTWAIT | MSG_NOSIGNAL) )
return errno = EINVAL, -1;
if ( msg.msg_name )
return errno = EINVAL, -1;
if ( msg.msg_control && msg.msg_controllen )
return errno = EINVAL, -1;
return sys_writev(fd, msg.msg_iov, msg.msg_iovlen);
}
static ssize_t sys_recvmsg(int fd, struct msghdr* user_msg, int flags)
{
struct msghdr msg;
if ( !CopyFromUser(&msg, user_msg, sizeof(msg)) )
return -1;
if ( flags & ~(MSG_CMSG_CLOEXEC | MSG_DONTWAIT) )
return errno = EINVAL, -1;
if ( msg.msg_name )
return errno = EINVAL, -1;
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
if ( !desc )
return -1;
// TODO: This is not atomic.
int old_flags = desc->GetFlags();
desc->SetFlags(old_flags | O_NONBLOCK);
ssize_t result = sys_readv(fd, msg.msg_iov, msg.msg_iovlen);
desc->SetFlags(old_flags);
msg.msg_flags = 0;
if ( !CopyToUser(&user_msg->msg_flags, &msg.msg_flags, sizeof(msg.msg_flags)) )
return -1;
return result;
}
void Init()
{
Syscall::Register(SYSCALL_ACCEPT4, (void*) sys_accept4);
@ -1011,8 +1053,10 @@ void Init()
Syscall::Register(SYSCALL_READLINKAT, (void*) sys_readlinkat);
Syscall::Register(SYSCALL_READ, (void*) sys_read);
Syscall::Register(SYSCALL_READV, (void*) sys_readv);
Syscall::Register(SYSCALL_RECVMSG, (void*) sys_recvmsg);
Syscall::Register(SYSCALL_RECV, (void*) sys_recv);
Syscall::Register(SYSCALL_RENAMEAT, (void*) sys_renameat);
Syscall::Register(SYSCALL_SENDMSG, (void*) sys_sendmsg);
Syscall::Register(SYSCALL_SEND, (void*) sys_send);
Syscall::Register(SYSCALL_SETTERMMODE, (void*) sys_settermmode);
Syscall::Register(SYSCALL_SYMLINKAT, (void*) sys_symlinkat);

View File

@ -137,6 +137,8 @@ struct linger
#define MSG_PEEK (1<<5)
#define MSG_TRUNC (1<<6)
#define MSG_WAITALL (1<<7)
#define MSG_DONTWAIT (1<<8)
#define MSG_CMSG_CLOEXEC (1<<9)
#define AF_UNSPEC 0
#define AF_INET 1

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013.
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
This file is part of the Sortix C Library.
@ -18,17 +18,19 @@
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
sys/socket/recvmsg.cpp
Receive a message from a socket.
Receive a message on a socket.
*******************************************************************************/
#include <sys/socket.h>
#include <sys/syscall.h>
#include <errno.h>
#include <stdio.h>
extern "C" ssize_t recvmsg(int, struct msghdr*, int)
DEFN_SYSCALL3(ssize_t, sys_recvmsg, SYSCALL_RECVMSG, int, struct msghdr*, int);
extern "C" ssize_t recvmsg(int fd, struct msghdr* msg, int flags)
{
fprintf(stderr, "%s is not implemented yet.\n", __func__);
return errno = ENOSYS, -1;
return sys_recvmsg(fd, msg, flags);
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013.
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
This file is part of the Sortix C Library.
@ -23,12 +23,14 @@
*******************************************************************************/
#include <sys/socket.h>
#include <sys/syscall.h>
#include <errno.h>
#include <stdio.h>
extern "C" ssize_t sendmsg(int, const struct msghdr*, int)
DEFN_SYSCALL3(ssize_t, sys_sendmsg, SYSCALL_SENDMSG, int, const struct msghdr*, int);
extern "C" ssize_t sendmsg(int fd, const struct msghdr* msg, int flags)
{
fprintf(stderr, "%s is not implemented yet.\n", __func__);
return errno = ENOSYS, -1;
return sys_sendmsg(fd, msg, flags);
}