mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
socket: fix close shutdown properly
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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, ¤t_thread()->proc->cred);
|
||||
ret.ret = ret.errno ? -1 : 0;
|
||||
|
||||
cleanup:
|
||||
if (file)
|
||||
fd_release(file);
|
||||
|
||||
if (vnode)
|
||||
VOP_RELEASE(vnode);
|
||||
free(addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -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), ¤t_thread()->proc->cred) : EOPNOTSUPP;
|
||||
ret.errno = socket->ops->connect ? socket->ops->connect(socket, &sockaddr, fileflagstovnodeflags(fileflags), ¤t_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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user