syscalls: getsockopt

This commit is contained in:
Matheus
2026-04-01 17:22:22 -03:00
parent d20c86f70d
commit ea8da40128
5 changed files with 96 additions and 5 deletions
+3 -1
View File
@@ -101,6 +101,7 @@ extern syscall_readv
extern syscall_yield
extern syscall_fstatvfs
extern syscall_fstatvfsat
extern syscall_getsockopt
syscalltab:
dq syscall_print
dq syscall_mmap
@@ -204,7 +205,8 @@ dq syscall_readv
dq syscall_yield
dq syscall_fstatvfs
dq syscall_fstatvfsat
syscallcount equ 102
dq syscall_getsockopt
syscallcount equ 103
section .text
global arch_syscall_entry
; on entry:
+3 -1
View File
@@ -8,7 +8,7 @@
void arch_interrupt_disable();
void arch_interrupt_enable();
#define SYSCALL_COUNT 102
#define SYSCALL_COUNT 103
#define LOGSTR(x) arch_e9_puts(x)
static char *name[] = {
@@ -114,6 +114,7 @@ static char *name[] = {
"yield",
"fstatvfs",
"fstatvfsat",
"getsockopt",
};
static char *args[] = {
@@ -219,6 +220,7 @@ static char *args[] = {
"N/A", // yield
"fd %d ustat %p", // fstatvfs
"dirfd %d path %s ustat %p flags %d", // fstatvfsat
"fd %d level %d optname %d optval %p optlen %p", // getsockopt
};
#endif
+22 -2
View File
@@ -98,9 +98,29 @@ typedef struct {
#define MSG_WAITALL 0x100
#define MSG_NOSIGNAL 0x4000
#define SO_BROADCAST 6
#define TCP_NODELAY 1
#define TCP_KEEPIDLE 4
#define TCP_KEEPINTVL 5
#define IP_TOS 1
#define SO_DEBUG 1
#define SO_REUSEADDR 2
#define SO_TYPE 3
#define SO_ERROR 4
#define SO_DONTROUTE 5
#define SO_BROADCAST 6
#define SO_SNDBUF 7
#define SO_RCVBUF 8
#define SO_KEEPALIVE 9
#define SO_OOBINLINE 10
#define SO_LINGER 13
#define SO_RCVLOWAT 18
#define SO_SNDLOWAT 19
#define SO_BINDTODEVICE 25
#define SO_KEEPALIVE 9
#define SO_ACCEPTCONN 30
#define SO_PROTOCOL 38
#define SO_DOMAIN 39
#define SOL_SOCKET 1
+2 -1
View File
@@ -73,7 +73,8 @@ typedef struct socketops_t {
int (*getpeername)(socket_t *socket, sockaddr_t *addr);
size_t (*datacount)(socket_t *socket);
void (*destroy)(socket_t *socket);
int (*setopt)(socket_t *socket, int optname, void *buffer, size_t len, cred_t *cred);
int (*setopt)(socket_t *socket, int layer, int optname, void *buffer, socklen_t len, cred_t *cred);
int (*getopt)(socket_t *socket, int layer, int optname, void *buffer, socklen_t *len, cred_t *cred);
int (*shutdown)(socket_t *socket, int how);
} socketops_t;
+66
View File
@@ -0,0 +1,66 @@
#include <kernel/syscalls.h>
#include <kernel/sock.h>
#include <kernel/abi.h>
#include <kernel/file.h>
#include <errno.h>
syscallret_t syscall_getsockopt(context_t *, int fd, int level, int optname, void *val, socklen_t *len) {
syscallret_t ret = {
.ret = -1
};
if (!IS_USER_ADDRESS(val) || !IS_USER_ADDRESS(len)) {
ret.errno = EFAULT;
}
file_t *file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
return ret;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
MUTEX_ACQUIRE(&socket->mutex);
if (level == SOL_SOCKET) {
// handle some general cases
switch (optname) {
case SO_ERROR: {
socklen_t l;
ret.errno = usercopy_fromuser(&l, len, sizeof(l));
if (ret.errno)
break;
if (l != 4) {
ret.errno = EINVAL;
break;
}
int error = socket->error;
ret.errno = usercopy_touser(val, &error, sizeof(error));
if (!ret.errno)
socket->error = 0;
break;
}
default: {
ret.errno = socket->ops->getopt ? socket->ops->getopt(socket, level, optname, val, len, &current_thread()->proc->cred) : ENOPROTOOPT;
}
}
} else {
ret.errno = socket->ops->getopt ? socket->ops->getopt(socket, level, optname, val, len, &current_thread()->proc->cred) : ENOPROTOOPT;
}
MUTEX_RELEASE(&socket->mutex);
cleanup:
ret.ret = ret.errno ? -1 : 0;
fd_release(file);
return ret;
}