socket: fix close shutdown properly

This commit is contained in:
Matheus
2026-07-07 16:49:21 -03:00
parent 196698c059
commit f46d85fe6d
15 changed files with 103 additions and 158 deletions
+12 -17
View File
@@ -15,18 +15,13 @@ syscallret_t syscall_accept(context_t *, int oldfd, abisockaddr_t *abisockaddr,
return ret;
}
file_t *oldfile = fd_get(oldfd);
if (oldfile == NULL) {
ret.errno = EBADF;
vnode_t *servernode;
int fileflags;
ret.errno = sockfd_get(oldfd, &servernode, &fileflags);
if (ret.errno)
return ret;
}
if (oldfile->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
socket_t *server = SOCKFS_SOCKET_FROM_NODE(oldfile->vnode);
socket_t *server = SOCKFS_SOCKET_FROM_NODE(servernode);
if (server->ops->accept == NULL) {
ret.errno = ENOTSUP;
@@ -39,18 +34,18 @@ syscallret_t syscall_accept(context_t *, int oldfd, abisockaddr_t *abisockaddr,
goto cleanup;
}
vnode_t *vnode;
ret.errno = sockfs_newsocket(&vnode, client);
vnode_t *clientnode;
ret.errno = sockfs_newsocket(&clientnode, client);
if (ret.errno) {
client->ops->destroy(client);
goto cleanup;
}
sockaddr_t addr = {0};
ret.errno = server->ops->accept(server, client, &addr, fileflagstovnodeflags(oldfile->flags));
ret.errno = server->ops->accept(server, client, &addr, fileflagstovnodeflags(fileflags));
if (ret.errno) {
// socket gets deleted by node cleanup
VOP_RELEASE(vnode);
VOP_RELEASE(clientnode);
goto cleanup;
}
@@ -60,11 +55,11 @@ syscallret_t syscall_accept(context_t *, int oldfd, abisockaddr_t *abisockaddr,
ret.errno = fd_new(acceptflags & O_CLOEXEC, &newfile, &newfd);
if (ret.errno) {
// socket gets deleted by node cleanup
VOP_RELEASE(vnode);
VOP_RELEASE(clientnode);
goto cleanup;
}
newfile->vnode = vnode;
newfile->vnode = clientnode;
newfile->flags = FILE_READ | FILE_WRITE | (acceptflags & (O_NONBLOCK));
newfile->offset = 0;
newfile->mode = 0777;
@@ -88,7 +83,7 @@ syscallret_t syscall_accept(context_t *, int oldfd, abisockaddr_t *abisockaddr,
ret.ret = newfd;
cleanup:
fd_release(oldfile);
VOP_RELEASE(servernode);
return ret;
}
+6 -13
View File
@@ -24,16 +24,10 @@ syscallret_t syscall_bind(context_t *, int fd, void *uaddr, size_t addrlen) {
return ret;
}
file_t *file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
vnode_t *vnode = NULL;
ret.errno = sockfd_get(fd, &vnode, NULL);
if (ret.errno)
goto cleanup;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
ret.errno = usercopy_fromuser(addr, uaddr, addrlen);
if (ret.errno)
@@ -44,15 +38,14 @@ syscallret_t syscall_bind(context_t *, int fd, void *uaddr, size_t addrlen) {
if (ret.errno)
goto cleanup;
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
ret.errno = socket->ops->bind(socket, &sockaddr, &current_thread()->proc->cred);
ret.ret = ret.errno ? -1 : 0;
cleanup:
if (file)
fd_release(file);
if (vnode)
VOP_RELEASE(vnode);
free(addr);
return ret;
}
+8 -14
View File
@@ -25,16 +25,11 @@ syscallret_t syscall_connect(context_t *, int fd, abisockaddr_t *uaddr, size_t a
return ret;
}
file_t *file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
vnode_t *vnode = NULL;
int fileflags;
ret.errno = sockfd_get(fd, &vnode, &fileflags);
if (ret.errno)
goto cleanup;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
ret.errno = usercopy_fromuser(addr, uaddr, addrlen);
if (ret.errno)
@@ -45,15 +40,14 @@ syscallret_t syscall_connect(context_t *, int fd, abisockaddr_t *uaddr, size_t a
if (ret.errno)
goto cleanup;
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
ret.errno = socket->ops->connect ? socket->ops->connect(socket, &sockaddr, fileflagstovnodeflags(file->flags), &current_thread()->proc->cred) : EOPNOTSUPP;
ret.errno = socket->ops->connect ? socket->ops->connect(socket, &sockaddr, fileflagstovnodeflags(fileflags), &current_thread()->proc->cred) : EOPNOTSUPP;
ret.ret = ret.errno ? -1 : 0;
cleanup:
if (file)
fd_release(file);
if (vnode)
VOP_RELEASE(vnode);
free(addr);
return ret;
}
+6 -13
View File
@@ -11,19 +11,13 @@ syscallret_t syscall_getpeername(context_t *, int fd, void *uaddr, int *uaddrlen
if (ret.errno)
return ret;
file_t *file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
goto cleanup;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
vnode_t *vnode;
ret.errno = sockfd_get(fd, &vnode, NULL);
if (ret.errno)
return ret;
sockaddr_t sockaddr;
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
ret.errno = socket->ops->getpeername(socket, &sockaddr);
if (ret.errno)
@@ -39,8 +33,7 @@ syscallret_t syscall_getpeername(context_t *, int fd, void *uaddr, int *uaddrlen
ret.ret = ret.errno ? -1 : 0;
cleanup:
if (file)
fd_release(file);
VOP_RELEASE(vnode);
return ret;
}
+6 -13
View File
@@ -11,19 +11,13 @@ syscallret_t syscall_getsockname(context_t *, int fd, void *uaddr, int *uaddrlen
if (ret.errno)
return ret;
file_t *file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
goto cleanup;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
vnode_t *vnode;
ret.errno = sockfd_get(fd, &vnode, NULL);
if (ret.errno)
return ret;
sockaddr_t sockaddr;
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
ret.errno = socket->ops->getname(socket, &sockaddr);
if (ret.errno)
@@ -42,8 +36,7 @@ syscallret_t syscall_getsockname(context_t *, int fd, void *uaddr, int *uaddrlen
ret.ret = 0;
cleanup:
if (file)
fd_release(file);
VOP_RELEASE(vnode);
return ret;
}
+5 -12
View File
@@ -14,18 +14,12 @@ syscallret_t syscall_getsockopt(context_t *, int fd, int level, int optname, voi
return ret;
}
file_t *file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
vnode_t *vnode;
ret.errno = sockfd_get(fd, &vnode, NULL);
if (ret.errno)
return ret;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
MUTEX_ACQUIRE(&socket->mutex);
if (level == SOL_SOCKET) {
@@ -59,9 +53,8 @@ syscallret_t syscall_getsockopt(context_t *, int fd, int level, int optname, voi
MUTEX_RELEASE(&socket->mutex);
cleanup:
ret.ret = ret.errno ? -1 : 0;
fd_release(file);
VOP_RELEASE(vnode);
return ret;
}
+5 -12
View File
@@ -7,24 +7,17 @@ syscallret_t syscall_listen(context_t *, int fd, int backlog) {
.ret = -1
};
file_t *file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
vnode_t *vnode;
ret.errno = sockfd_get(fd, &vnode, NULL);
if (ret.errno)
return ret;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
ret.errno = socket->ops->listen ? socket->ops->listen(socket, backlog) : EOPNOTSUPP;
ret.ret = ret.errno ? -1 : 0;
cleanup:
fd_release(file);
VOP_RELEASE(vnode);
return ret;
}
+8 -15
View File
@@ -21,7 +21,6 @@ syscallret_t syscall_recvmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
if (ret.errno)
return ret;
file_t *file = NULL;
size_t buffersize = iovec_size(msghdr.iov, msghdr.iovcount);
if (buffersize == 0) {
sock_freemsghdr(&msghdr);
@@ -36,19 +35,14 @@ syscallret_t syscall_recvmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
return ret;
}
file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
vnode_t *vnode = NULL;
int fileflags;
ret.errno = sockfd_get(fd, &vnode, &fileflags);
if (ret.errno)
goto cleanup;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
sockaddr_t sockaddr;
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
uintmax_t recvflags = 0;
if (flags & MSG_PEEK)
@@ -68,7 +62,7 @@ syscallret_t syscall_recvmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
.addr = &sockaddr,
.iovec_iterator = &iovec_iterator,
.count = buffersize,
.flags = fileflagstovnodeflags(file->flags) | recvflags,
.flags = fileflagstovnodeflags(fileflags) | recvflags,
.donecount = 0,
.ctrl = msghdr.msgctrl,
.ctrllen = msghdr.ctrllen,
@@ -120,9 +114,8 @@ syscallret_t syscall_recvmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
ret.ret = ret.errno ? -1 : desc.donecount;
cleanup:
if (file)
fd_release(file);
if (vnode)
VOP_RELEASE(vnode);
sock_freemsghdr(&msghdr);
return ret;
}
+11 -16
View File
@@ -6,7 +6,9 @@
#include <kernel/alloc.h>
syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags) {
syscallret_t ret;
syscallret_t ret = {
.ret = -1
};
if (flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL))
printf("sendmsg: unknown %x\n", flags);
@@ -16,7 +18,6 @@ syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
if (ret.errno)
return ret;
file_t *file = NULL;
size_t buffersize = iovec_size(msghdr.iov, msghdr.iovcount);
if (buffersize == 0) {
sock_freemsghdr(&msghdr);
@@ -31,16 +32,11 @@ syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
return ret;
}
file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
goto cleanup;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
vnode_t *vnode = NULL;
int fileflags;
ret.errno = sockfd_get(fd, &vnode, &fileflags);
if (ret.errno)
goto cleanup;
}
sockaddr_t sockaddr;
if (msghdr.addr) {
@@ -49,7 +45,7 @@ syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
goto cleanup;
}
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
int sendflags = 0;
@@ -64,7 +60,7 @@ syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
.addr = msghdr.addr ? &sockaddr : NULL,
.iovec_iterator = &iovec_iterator,
.count = buffersize,
.flags = fileflagstovnodeflags(file->flags) | sendflags,
.flags = fileflagstovnodeflags(fileflags) | sendflags,
.donecount = 0,
.ctrl = msghdr.msgctrl,
.ctrllen = msghdr.ctrllen,
@@ -77,9 +73,8 @@ syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
ret.ret = ret.errno ? -1 : desc.donecount;
cleanup:
if (file)
fd_release(file);
if (vnode)
VOP_RELEASE(vnode);
sock_freemsghdr(&msghdr);
return ret;
}
+5 -12
View File
@@ -10,18 +10,12 @@ syscallret_t syscall_setsockopt(context_t *, int fd, int level, int optname, voi
.ret = -1
};
file_t *file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
vnode_t *vnode;
ret.errno = sockfd_get(fd, &vnode, NULL);
if (ret.errno)
return ret;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
MUTEX_ACQUIRE(&socket->mutex);
if (level == SOL_SOCKET) {
@@ -65,10 +59,9 @@ syscallret_t syscall_setsockopt(context_t *, int fd, int level, int optname, voi
MUTEX_RELEASE(&socket->mutex);
cleanup:
ret.ret = ret.errno ? -1 : 0;
fd_release(file);
VOP_RELEASE(vnode);
return ret;
}
+5 -13
View File
@@ -20,24 +20,16 @@ syscallret_t syscall_shutdown(context_t *, int fd, int how) {
++how; // convert to internal meaning
file_t *file = fd_get(fd);
if (file == NULL) {
ret.errno = EBADF;
vnode_t *vnode;
ret.errno = sockfd_get(fd, &vnode, NULL);
if (ret.errno)
return ret;
}
if (file->vnode->type != V_TYPE_SOCKET) {
ret.errno = ENOTSOCK;
goto cleanup;
}
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
ret.errno = socket->ops->shutdown(socket, how);
ret.ret = ret.errno ? -1 : 0;
cleanup:
fd_release(file);
VOP_RELEASE(vnode);
return ret;
}