diff options
author | Ian Moffett <ian@osmora.org> | 2025-07-31 15:59:58 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-07-31 16:02:21 -0400 |
commit | 862607845cd43ca11e19f2364f2f967836712098 (patch) | |
tree | 6631cfbecacf55c560b34cae9618fd1cbb689a09 | |
parent | 88dbb581d441ad63edaea9ff7866109feac4d69e (diff) |
kernel: Add SYS_connect syscall
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | sys/include/sys/socket.h | 1 | ||||
-rw-r--r-- | sys/include/sys/syscall.h | 1 | ||||
-rw-r--r-- | sys/kern/kern_socket.c | 41 | ||||
-rw-r--r-- | sys/kern/kern_syscall.c | 1 |
4 files changed, 43 insertions, 1 deletions
diff --git a/sys/include/sys/socket.h b/sys/include/sys/socket.h index a921fa8..c82ae4e 100644 --- a/sys/include/sys/socket.h +++ b/sys/include/sys/socket.h @@ -163,6 +163,7 @@ struct ksocket { scret_t sys_socket(struct syscall_args *scargs); scret_t sys_bind(struct syscall_args *scargs); +scret_t sys_connect(struct syscall_args *scargs); scret_t sys_recv(struct syscall_args *scargs); scret_t sys_send(struct syscall_args *scargs); diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h index d79a697..9798d80 100644 --- a/sys/include/sys/syscall.h +++ b/sys/include/sys/syscall.h @@ -65,6 +65,7 @@ #define SYS_send 24 #define SYS_sendmsg 25 #define SYS_recvmsg 26 +#define SYS_connect 27 #if defined(_KERNEL) /* Syscall return value and arg type */ diff --git a/sys/kern/kern_socket.c b/sys/kern/kern_socket.c index 29fc7c1..1717f5a 100644 --- a/sys/kern/kern_socket.c +++ b/sys/kern/kern_socket.c @@ -763,11 +763,50 @@ sys_sendmsg(struct syscall_args *scargs) msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &msg_iov; - retval = sendmsg(socket, &msg, flags); + + for (;;) { + retval = sendmsg(socket, &msg, flags); + if (retval == 0) { + break; + } + sched_yield(); + } uio_copyin_clean(&msg_iov, msg.msg_iovlen); return retval; } +/* + * connnect(3) syscall + * + * arg0: sockfd + * arg1: address + * arg2: len + */ +scret_t +sys_connect(struct syscall_args *scargs) +{ + char buf[256]; + struct sockaddr *u_addr = (void *)scargs->arg1; + struct sockaddr *sockaddr; + int error; + int sockfd = scargs->arg0; + socklen_t len = scargs->arg2; + + if (len >= sizeof(buf)) { + pr_error("sys_connect: address too big\n"); + return -E2BIG; + } + + error = copyin(u_addr, buf, len); + if (error < 0) { + pr_error("sys_connect: bad 'address'\n"); + return error; + } + + sockaddr = (struct sockaddr *)buf; + return connect(sockfd, sockaddr, len); +} + static struct vops socket_vops = { .read = NULL, .write = NULL, diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c index 7b037aa..576b7aa 100644 --- a/sys/kern/kern_syscall.c +++ b/sys/kern/kern_syscall.c @@ -67,6 +67,7 @@ scret_t(*g_sctab[])(struct syscall_args *) = { sys_send, /* SYS_send */ sys_sendmsg, /* SYS_sendmsg */ sys_recvmsg, /* SYS_recvmsg */ + sys_connect, /* SYS_connect */ }; const size_t MAX_SYSCALLS = NELEM(g_sctab); |