summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-07-31 15:59:58 -0400
committerIan Moffett <ian@osmora.org>2025-07-31 16:02:21 -0400
commit862607845cd43ca11e19f2364f2f967836712098 (patch)
tree6631cfbecacf55c560b34cae9618fd1cbb689a09
parent88dbb581d441ad63edaea9ff7866109feac4d69e (diff)
kernel: Add SYS_connect syscall
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--sys/include/sys/socket.h1
-rw-r--r--sys/include/sys/syscall.h1
-rw-r--r--sys/kern/kern_socket.c41
-rw-r--r--sys/kern/kern_syscall.c1
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);