diff options
author | Ian Moffett <ian@osmora.org> | 2025-08-04 20:22:39 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-08-04 20:25:14 -0400 |
commit | b5a44ff2933b71347f79273da8fc99f24b3c595b (patch) | |
tree | 6a7dd3151c6f1eeb320f2e12c350fcf6c51258c1 /sys/kern | |
parent | 24b4eaa97c0ba3c45406ac293a35d78c5342aac8 (diff) |
kernel & libc: Add POSIX setsockopt syscall
This commit implements the POSIX setsockopt syscall so that user
programs may be able to configure sockets they have created.
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_socket.c | 49 | ||||
-rw-r--r-- | sys/kern/kern_syscall.c | 1 |
2 files changed, 50 insertions, 0 deletions
diff --git a/sys/kern/kern_socket.c b/sys/kern/kern_socket.c index 0b10d0c..edaf32d 100644 --- a/sys/kern/kern_socket.c +++ b/sys/kern/kern_socket.c @@ -953,6 +953,55 @@ sys_connect(struct syscall_args *scargs) return connect(sockfd, sockaddr, len); } +/* + * POSIX setsockopt(3) syscall + * + * arg0: sockfd + * arg1: level + * arg2: name + * arg3: data + * arg4: len + */ +scret_t +sys_setsockopt(struct syscall_args *scargs) +{ + int sockfd = scargs->arg0; + int level = scargs->arg1; + int name = scargs->arg2; + void *u_data = (void *)scargs->arg3; + socklen_t len = scargs->arg4; + void *data; + size_t exp_len; + int retval; + + /* Verify that the name is correct */ + if (name >= _SO_MAX) { + return -EINVAL; + } + + /* Clamp length as needed */ + exp_len = sockopt_lentab[name]; + if (len > exp_len) { + len = exp_len; + } + + data = dynalloc(len); + if (data == NULL) { + return -ENOMEM; + } + + /* Grab data from userland */ + retval = copyin(u_data, data, len); + if (retval < 0) { + dynfree(data); + return retval; + } + + retval = setsockopt(sockfd, level, name, data, len); + dynfree(data); + return retval; +} + static struct vops socket_vops = { .read = NULL, .write = NULL, diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c index 576b7aa..ba70b12 100644 --- a/sys/kern/kern_syscall.c +++ b/sys/kern/kern_syscall.c @@ -68,6 +68,7 @@ scret_t(*g_sctab[])(struct syscall_args *) = { sys_sendmsg, /* SYS_sendmsg */ sys_recvmsg, /* SYS_recvmsg */ sys_connect, /* SYS_connect */ + sys_setsockopt, /* SYS_setsockopt */ }; const size_t MAX_SYSCALLS = NELEM(g_sctab); |