mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-02 07:28:21 +00:00
socket: fix close shutdown properly
This commit is contained in:
@@ -4,7 +4,6 @@
|
|||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/sock.h>
|
|
||||||
|
|
||||||
static scache_t *filecache;
|
static scache_t *filecache;
|
||||||
#define FILE_HOLD(f) __atomic_add_fetch(&(f)->refcount, 1, __ATOMIC_SEQ_CST)
|
#define FILE_HOLD(f) __atomic_add_fetch(&(f)->refcount, 1, __ATOMIC_SEQ_CST)
|
||||||
@@ -180,11 +179,6 @@ int fd_close(int fd) {
|
|||||||
MUTEX_RELEASE(&proc->fdmutex);
|
MUTEX_RELEASE(&proc->fdmutex);
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
if (file->vnode && file->vnode->type == V_TYPE_SOCKET) {
|
|
||||||
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
|
|
||||||
socket->ops->shutdown(socket, SOCKET_SHUTDOWN_RW);
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE_RELEASE(file);
|
FILE_RELEASE(file);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ int sockfs_open(vnode_t **node, int flags, cred_t *cred) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int sockfs_close(vnode_t *node, int flags, cred_t *cred) {
|
int sockfs_close(vnode_t *node, int flags, cred_t *cred) {
|
||||||
return ENOSYS; // not needed
|
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(node);
|
||||||
|
|
||||||
|
return socket->ops->shutdown ? socket->ops->shutdown(socket, SOCKET_SHUTDOWN_RW) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sockfs_read(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *bytes_read, cred_t *cred) {
|
int sockfs_read(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *bytes_read, cred_t *cred) {
|
||||||
|
|||||||
@@ -3,11 +3,13 @@
|
|||||||
|
|
||||||
#include <kernel/net.h>
|
#include <kernel/net.h>
|
||||||
#include <kernel/vfs.h>
|
#include <kernel/vfs.h>
|
||||||
|
#include <kernel/file.h>
|
||||||
#include <mutex.h>
|
#include <mutex.h>
|
||||||
#include <kernel/poll.h>
|
#include <kernel/poll.h>
|
||||||
#include <kernel/usercopy.h>
|
#include <kernel/usercopy.h>
|
||||||
#include <kernel/iovec.h>
|
#include <kernel/iovec.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#define SOCKET_STATE_UNBOUND 0
|
#define SOCKET_STATE_UNBOUND 0
|
||||||
#define SOCKET_STATE_BOUND 1
|
#define SOCKET_STATE_BOUND 1
|
||||||
@@ -92,6 +94,26 @@ typedef struct {
|
|||||||
#define SOCKET_TYPE_LOCAL_SEQPACKET 3
|
#define SOCKET_TYPE_LOCAL_SEQPACKET 3
|
||||||
#define SOCKFS_SOCKET_FROM_NODE(nodep) (((socketnode_t *)(nodep))->socket)
|
#define SOCKFS_SOCKET_FROM_NODE(nodep) (((socketnode_t *)(nodep))->socket)
|
||||||
|
|
||||||
|
static inline int sockfd_get(int fd, vnode_t **vnodep, int *fileflags) {
|
||||||
|
file_t *file = fd_get(fd);
|
||||||
|
if (file == NULL)
|
||||||
|
return EBADF;
|
||||||
|
|
||||||
|
if (file->vnode->type != V_TYPE_SOCKET) {
|
||||||
|
fd_release(file);
|
||||||
|
return ENOTSOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
vnode_t *vnode = file->vnode;
|
||||||
|
VOP_HOLD(vnode);
|
||||||
|
if (fileflags)
|
||||||
|
*fileflags = file->flags;
|
||||||
|
fd_release(file);
|
||||||
|
|
||||||
|
*vnodep = vnode;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool socket_nonblocking(socket_t *socket, uintmax_t flags) {
|
static inline bool socket_nonblocking(socket_t *socket, uintmax_t flags) {
|
||||||
return socket->nonblocking || (flags & V_FFLAGS_NONBLOCKING);
|
return socket->nonblocking || (flags & V_FFLAGS_NONBLOCKING);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,18 +15,13 @@ syscallret_t syscall_accept(context_t *, int oldfd, abisockaddr_t *abisockaddr,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_t *oldfile = fd_get(oldfd);
|
vnode_t *servernode;
|
||||||
if (oldfile == NULL) {
|
int fileflags;
|
||||||
ret.errno = EBADF;
|
ret.errno = sockfd_get(oldfd, &servernode, &fileflags);
|
||||||
|
if (ret.errno)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
if (oldfile->vnode->type != V_TYPE_SOCKET) {
|
socket_t *server = SOCKFS_SOCKET_FROM_NODE(servernode);
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_t *server = SOCKFS_SOCKET_FROM_NODE(oldfile->vnode);
|
|
||||||
|
|
||||||
if (server->ops->accept == NULL) {
|
if (server->ops->accept == NULL) {
|
||||||
ret.errno = ENOTSUP;
|
ret.errno = ENOTSUP;
|
||||||
@@ -39,18 +34,18 @@ syscallret_t syscall_accept(context_t *, int oldfd, abisockaddr_t *abisockaddr,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
vnode_t *vnode;
|
vnode_t *clientnode;
|
||||||
ret.errno = sockfs_newsocket(&vnode, client);
|
ret.errno = sockfs_newsocket(&clientnode, client);
|
||||||
if (ret.errno) {
|
if (ret.errno) {
|
||||||
client->ops->destroy(client);
|
client->ops->destroy(client);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_t addr = {0};
|
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) {
|
if (ret.errno) {
|
||||||
// socket gets deleted by node cleanup
|
// socket gets deleted by node cleanup
|
||||||
VOP_RELEASE(vnode);
|
VOP_RELEASE(clientnode);
|
||||||
goto cleanup;
|
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);
|
ret.errno = fd_new(acceptflags & O_CLOEXEC, &newfile, &newfd);
|
||||||
if (ret.errno) {
|
if (ret.errno) {
|
||||||
// socket gets deleted by node cleanup
|
// socket gets deleted by node cleanup
|
||||||
VOP_RELEASE(vnode);
|
VOP_RELEASE(clientnode);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
newfile->vnode = vnode;
|
newfile->vnode = clientnode;
|
||||||
newfile->flags = FILE_READ | FILE_WRITE | (acceptflags & (O_NONBLOCK));
|
newfile->flags = FILE_READ | FILE_WRITE | (acceptflags & (O_NONBLOCK));
|
||||||
newfile->offset = 0;
|
newfile->offset = 0;
|
||||||
newfile->mode = 0777;
|
newfile->mode = 0777;
|
||||||
@@ -88,7 +83,7 @@ syscallret_t syscall_accept(context_t *, int oldfd, abisockaddr_t *abisockaddr,
|
|||||||
ret.ret = newfd;
|
ret.ret = newfd;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
fd_release(oldfile);
|
VOP_RELEASE(servernode);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,16 +24,10 @@ syscallret_t syscall_bind(context_t *, int fd, void *uaddr, size_t addrlen) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_t *file = fd_get(fd);
|
vnode_t *vnode = NULL;
|
||||||
if (file == NULL) {
|
ret.errno = sockfd_get(fd, &vnode, NULL);
|
||||||
ret.errno = EBADF;
|
if (ret.errno)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->vnode->type != V_TYPE_SOCKET) {
|
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.errno = usercopy_fromuser(addr, uaddr, addrlen);
|
ret.errno = usercopy_fromuser(addr, uaddr, addrlen);
|
||||||
if (ret.errno)
|
if (ret.errno)
|
||||||
@@ -44,15 +38,14 @@ syscallret_t syscall_bind(context_t *, int fd, void *uaddr, size_t addrlen) {
|
|||||||
if (ret.errno)
|
if (ret.errno)
|
||||||
goto cleanup;
|
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.errno = socket->ops->bind(socket, &sockaddr, ¤t_thread()->proc->cred);
|
||||||
ret.ret = ret.errno ? -1 : 0;
|
ret.ret = ret.errno ? -1 : 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (file)
|
if (vnode)
|
||||||
fd_release(file);
|
VOP_RELEASE(vnode);
|
||||||
|
|
||||||
free(addr);
|
free(addr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,16 +25,11 @@ syscallret_t syscall_connect(context_t *, int fd, abisockaddr_t *uaddr, size_t a
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_t *file = fd_get(fd);
|
vnode_t *vnode = NULL;
|
||||||
if (file == NULL) {
|
int fileflags;
|
||||||
ret.errno = EBADF;
|
ret.errno = sockfd_get(fd, &vnode, &fileflags);
|
||||||
|
if (ret.errno)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->vnode->type != V_TYPE_SOCKET) {
|
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.errno = usercopy_fromuser(addr, uaddr, addrlen);
|
ret.errno = usercopy_fromuser(addr, uaddr, addrlen);
|
||||||
if (ret.errno)
|
if (ret.errno)
|
||||||
@@ -45,15 +40,14 @@ syscallret_t syscall_connect(context_t *, int fd, abisockaddr_t *uaddr, size_t a
|
|||||||
if (ret.errno)
|
if (ret.errno)
|
||||||
goto cleanup;
|
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;
|
ret.ret = ret.errno ? -1 : 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (file)
|
if (vnode)
|
||||||
fd_release(file);
|
VOP_RELEASE(vnode);
|
||||||
|
|
||||||
free(addr);
|
free(addr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,19 +11,13 @@ syscallret_t syscall_getpeername(context_t *, int fd, void *uaddr, int *uaddrlen
|
|||||||
if (ret.errno)
|
if (ret.errno)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
file_t *file = fd_get(fd);
|
vnode_t *vnode;
|
||||||
if (file == NULL) {
|
ret.errno = sockfd_get(fd, &vnode, NULL);
|
||||||
ret.errno = EBADF;
|
if (ret.errno)
|
||||||
goto cleanup;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->vnode->type != V_TYPE_SOCKET) {
|
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
sockaddr_t sockaddr;
|
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);
|
ret.errno = socket->ops->getpeername(socket, &sockaddr);
|
||||||
if (ret.errno)
|
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;
|
ret.ret = ret.errno ? -1 : 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (file)
|
VOP_RELEASE(vnode);
|
||||||
fd_release(file);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,19 +11,13 @@ syscallret_t syscall_getsockname(context_t *, int fd, void *uaddr, int *uaddrlen
|
|||||||
if (ret.errno)
|
if (ret.errno)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
file_t *file = fd_get(fd);
|
vnode_t *vnode;
|
||||||
if (file == NULL) {
|
ret.errno = sockfd_get(fd, &vnode, NULL);
|
||||||
ret.errno = EBADF;
|
if (ret.errno)
|
||||||
goto cleanup;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->vnode->type != V_TYPE_SOCKET) {
|
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
sockaddr_t sockaddr;
|
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);
|
ret.errno = socket->ops->getname(socket, &sockaddr);
|
||||||
if (ret.errno)
|
if (ret.errno)
|
||||||
@@ -42,8 +36,7 @@ syscallret_t syscall_getsockname(context_t *, int fd, void *uaddr, int *uaddrlen
|
|||||||
ret.ret = 0;
|
ret.ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (file)
|
VOP_RELEASE(vnode);
|
||||||
fd_release(file);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,18 +14,12 @@ syscallret_t syscall_getsockopt(context_t *, int fd, int level, int optname, voi
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_t *file = fd_get(fd);
|
vnode_t *vnode;
|
||||||
if (file == NULL) {
|
ret.errno = sockfd_get(fd, &vnode, NULL);
|
||||||
ret.errno = EBADF;
|
if (ret.errno)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->vnode->type != V_TYPE_SOCKET) {
|
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
|
|
||||||
|
|
||||||
MUTEX_ACQUIRE(&socket->mutex);
|
MUTEX_ACQUIRE(&socket->mutex);
|
||||||
if (level == SOL_SOCKET) {
|
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);
|
MUTEX_RELEASE(&socket->mutex);
|
||||||
|
|
||||||
cleanup:
|
|
||||||
ret.ret = ret.errno ? -1 : 0;
|
ret.ret = ret.errno ? -1 : 0;
|
||||||
|
|
||||||
fd_release(file);
|
VOP_RELEASE(vnode);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,24 +7,17 @@ syscallret_t syscall_listen(context_t *, int fd, int backlog) {
|
|||||||
.ret = -1
|
.ret = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
file_t *file = fd_get(fd);
|
vnode_t *vnode;
|
||||||
if (file == NULL) {
|
ret.errno = sockfd_get(fd, &vnode, NULL);
|
||||||
ret.errno = EBADF;
|
if (ret.errno)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->vnode->type != V_TYPE_SOCKET) {
|
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
|
|
||||||
|
|
||||||
ret.errno = socket->ops->listen ? socket->ops->listen(socket, backlog) : EOPNOTSUPP;
|
ret.errno = socket->ops->listen ? socket->ops->listen(socket, backlog) : EOPNOTSUPP;
|
||||||
ret.ret = ret.errno ? -1 : 0;
|
ret.ret = ret.errno ? -1 : 0;
|
||||||
|
|
||||||
cleanup:
|
VOP_RELEASE(vnode);
|
||||||
fd_release(file);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ syscallret_t syscall_recvmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
|
|||||||
if (ret.errno)
|
if (ret.errno)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
file_t *file = NULL;
|
|
||||||
size_t buffersize = iovec_size(msghdr.iov, msghdr.iovcount);
|
size_t buffersize = iovec_size(msghdr.iov, msghdr.iovcount);
|
||||||
if (buffersize == 0) {
|
if (buffersize == 0) {
|
||||||
sock_freemsghdr(&msghdr);
|
sock_freemsghdr(&msghdr);
|
||||||
@@ -36,19 +35,14 @@ syscallret_t syscall_recvmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = fd_get(fd);
|
vnode_t *vnode = NULL;
|
||||||
if (file == NULL) {
|
int fileflags;
|
||||||
ret.errno = EBADF;
|
ret.errno = sockfd_get(fd, &vnode, &fileflags);
|
||||||
|
if (ret.errno)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->vnode->type != V_TYPE_SOCKET) {
|
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
sockaddr_t sockaddr;
|
sockaddr_t sockaddr;
|
||||||
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
|
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
|
||||||
|
|
||||||
uintmax_t recvflags = 0;
|
uintmax_t recvflags = 0;
|
||||||
if (flags & MSG_PEEK)
|
if (flags & MSG_PEEK)
|
||||||
@@ -68,7 +62,7 @@ syscallret_t syscall_recvmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
|
|||||||
.addr = &sockaddr,
|
.addr = &sockaddr,
|
||||||
.iovec_iterator = &iovec_iterator,
|
.iovec_iterator = &iovec_iterator,
|
||||||
.count = buffersize,
|
.count = buffersize,
|
||||||
.flags = fileflagstovnodeflags(file->flags) | recvflags,
|
.flags = fileflagstovnodeflags(fileflags) | recvflags,
|
||||||
.donecount = 0,
|
.donecount = 0,
|
||||||
.ctrl = msghdr.msgctrl,
|
.ctrl = msghdr.msgctrl,
|
||||||
.ctrllen = msghdr.ctrllen,
|
.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;
|
ret.ret = ret.errno ? -1 : desc.donecount;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (file)
|
if (vnode)
|
||||||
fd_release(file);
|
VOP_RELEASE(vnode);
|
||||||
|
|
||||||
sock_freemsghdr(&msghdr);
|
sock_freemsghdr(&msghdr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,9 @@
|
|||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
|
|
||||||
syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags) {
|
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))
|
if (flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL))
|
||||||
printf("sendmsg: unknown %x\n", flags);
|
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)
|
if (ret.errno)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
file_t *file = NULL;
|
|
||||||
size_t buffersize = iovec_size(msghdr.iov, msghdr.iovcount);
|
size_t buffersize = iovec_size(msghdr.iov, msghdr.iovcount);
|
||||||
if (buffersize == 0) {
|
if (buffersize == 0) {
|
||||||
sock_freemsghdr(&msghdr);
|
sock_freemsghdr(&msghdr);
|
||||||
@@ -31,16 +32,11 @@ syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = fd_get(fd);
|
vnode_t *vnode = NULL;
|
||||||
if (file == NULL) {
|
int fileflags;
|
||||||
ret.errno = EBADF;
|
ret.errno = sockfd_get(fd, &vnode, &fileflags);
|
||||||
|
if (ret.errno)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->vnode->type != V_TYPE_SOCKET) {
|
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
sockaddr_t sockaddr;
|
sockaddr_t sockaddr;
|
||||||
if (msghdr.addr) {
|
if (msghdr.addr) {
|
||||||
@@ -49,7 +45,7 @@ syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
|
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
|
||||||
|
|
||||||
int sendflags = 0;
|
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,
|
.addr = msghdr.addr ? &sockaddr : NULL,
|
||||||
.iovec_iterator = &iovec_iterator,
|
.iovec_iterator = &iovec_iterator,
|
||||||
.count = buffersize,
|
.count = buffersize,
|
||||||
.flags = fileflagstovnodeflags(file->flags) | sendflags,
|
.flags = fileflagstovnodeflags(fileflags) | sendflags,
|
||||||
.donecount = 0,
|
.donecount = 0,
|
||||||
.ctrl = msghdr.msgctrl,
|
.ctrl = msghdr.msgctrl,
|
||||||
.ctrllen = msghdr.ctrllen,
|
.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;
|
ret.ret = ret.errno ? -1 : desc.donecount;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (file)
|
if (vnode)
|
||||||
fd_release(file);
|
VOP_RELEASE(vnode);
|
||||||
|
|
||||||
sock_freemsghdr(&msghdr);
|
sock_freemsghdr(&msghdr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,18 +10,12 @@ syscallret_t syscall_setsockopt(context_t *, int fd, int level, int optname, voi
|
|||||||
.ret = -1
|
.ret = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
file_t *file = fd_get(fd);
|
vnode_t *vnode;
|
||||||
if (file == NULL) {
|
ret.errno = sockfd_get(fd, &vnode, NULL);
|
||||||
ret.errno = EBADF;
|
if (ret.errno)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->vnode->type != V_TYPE_SOCKET) {
|
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
|
|
||||||
|
|
||||||
MUTEX_ACQUIRE(&socket->mutex);
|
MUTEX_ACQUIRE(&socket->mutex);
|
||||||
if (level == SOL_SOCKET) {
|
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);
|
MUTEX_RELEASE(&socket->mutex);
|
||||||
|
|
||||||
cleanup:
|
|
||||||
ret.ret = ret.errno ? -1 : 0;
|
ret.ret = ret.errno ? -1 : 0;
|
||||||
|
|
||||||
fd_release(file);
|
VOP_RELEASE(vnode);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,24 +20,16 @@ syscallret_t syscall_shutdown(context_t *, int fd, int how) {
|
|||||||
|
|
||||||
++how; // convert to internal meaning
|
++how; // convert to internal meaning
|
||||||
|
|
||||||
file_t *file = fd_get(fd);
|
vnode_t *vnode;
|
||||||
if (file == NULL) {
|
ret.errno = sockfd_get(fd, &vnode, NULL);
|
||||||
ret.errno = EBADF;
|
if (ret.errno)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->vnode->type != V_TYPE_SOCKET) {
|
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(vnode);
|
||||||
ret.errno = ENOTSOCK;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
|
|
||||||
|
|
||||||
ret.errno = socket->ops->shutdown(socket, how);
|
ret.errno = socket->ops->shutdown(socket, how);
|
||||||
ret.ret = ret.errno ? -1 : 0;
|
ret.ret = ret.errno ? -1 : 0;
|
||||||
|
|
||||||
cleanup:
|
VOP_RELEASE(vnode);
|
||||||
|
|
||||||
fd_release(file);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
name=astral
|
name=astral
|
||||||
revision=22
|
revision=23
|
||||||
from_source=astral
|
from_source=astral
|
||||||
imagedeps="build-essential nasm"
|
imagedeps="build-essential nasm"
|
||||||
hostdeps="xgcc xbinutils limine"
|
hostdeps="xgcc xbinutils limine"
|
||||||
|
|||||||
Reference in New Issue
Block a user