diff options
author | Ian Moffett <ian@osmora.org> | 2025-07-31 15:57:13 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-07-31 15:57:13 -0400 |
commit | ee8be1476f057aabeaf306d1411b44201f43b11b (patch) | |
tree | 8ff6b83cbe349c3b91313af45af528cde54155df | |
parent | 075171e3b90115647f3e4af2664488bae64ee4ca (diff) |
kernel: socket: Improve control message logic
- Zero new control buffer before usage
- Block if the control message queue is empty
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | sys/kern/kern_socket.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/sys/kern/kern_socket.c b/sys/kern/kern_socket.c index 0673353..58817c5 100644 --- a/sys/kern/kern_socket.c +++ b/sys/kern/kern_socket.c @@ -626,7 +626,7 @@ scret_t sys_recvmsg(struct syscall_args *scargs) { struct msghdr *u_msg = (void *)scargs->arg1; - void *u_control; + void *u_control, *control = NULL; size_t controllen; struct iovec msg_iov; struct msghdr msg; @@ -653,23 +653,36 @@ sys_recvmsg(struct syscall_args *scargs) controllen = msg.msg_controllen; /* Allocate a new control field to copy in */ - msg.msg_control = dynalloc(controllen); + control = dynalloc(controllen); + msg.msg_control = control; if (msg.msg_control == NULL) { uio_copyin_clean(&msg_iov, msg.msg_iovlen); return -ENOMEM; } + memset(msg.msg_control, 0, controllen); error = copyin(u_control, msg.msg_control, controllen); if (error < 0) { retval = error; goto done; } + /* + * Now wait until we get a control + * message + */ msg.msg_iov = &msg_iov; - retval = recvmsg(socket, &msg, flags); + for (;;) { + retval = recvmsg(socket, &msg, flags); + if (retval == 0) { + break; + } + + sched_yield(); + } done: uio_copyin_clean(&msg_iov, msg.msg_iovlen); - dynfree(msg.msg_control); + dynfree(control); return retval; } |