From 729b025b19bbf2244f5343caf3ac4e0bf492d7cb Mon Sep 17 00:00:00 2001 From: Matheus Date: Sat, 22 Oct 2022 23:41:11 -0300 Subject: [PATCH] sockets: actually use socklen_t --- src/fs/vfs.c | 33 +++++++++++++++++++---- src/include/kernel/socket.h | 10 ++++--- src/include/kernel/unsocket.h | 5 ++-- src/sys/mm/vmm.c | 36 ++++++++++++++----------- src/sys/socket.c | 20 ++++++++++---- src/sys/syscalls/accept.c | 2 +- src/sys/syscalls/bind.c | 2 +- src/sys/syscalls/poll.c | 4 +++ src/sys/unsocket.c | 50 ++++++++++++++++++++++++++++------- 9 files changed, 120 insertions(+), 42 deletions(-) diff --git a/src/fs/vfs.c b/src/fs/vfs.c index 90095df1..098b5c09 100644 --- a/src/fs/vfs.c +++ b/src/fs/vfs.c @@ -8,6 +8,7 @@ #include #include #include +#include #define VFS_MAX_LOOP 5 @@ -129,7 +130,10 @@ int vfs_poll(vnode_t* node, pollfd* fd){ return devman_poll(node->st.st_rdev, fd); case TYPE_FIFO: return pipe_poll(node->objdata, fd); + case TYPE_SOCKET: + return socket_poll(node->objdata, fd); default: + printf("Tried to poll an object of type %lu\n", GETTYPE(node->st.st_mode)); _panic("Unsupported poll", NULL); } @@ -242,11 +246,21 @@ int vfs_map(vnode_t* node, void* addr, size_t len, size_t offset, size_t mmuflag spinlock_acquire(&lock); int err; - + if(GETTYPE(node->st.st_mode) == TYPE_CHARDEV){ err = devman_map(node->st.st_rdev, addr, len, offset, mmuflags); + ++node->refcount; + goto _back; } - else _panic("Normal file mapping not supported!", 0); + + if(GETTYPE(node->st.st_mode) != TYPE_REGULAR){ + err = EACCES; + goto _back; + } + + ++node->refcount; + + _back: spinlock_release(&lock); @@ -572,9 +586,12 @@ int vfs_resolvepath(vnode_t** result, dirnode_t** resultparent, dirnode_t* ref, linkname[size] = '\0'; - printf("reading link: %s\n", linkname); + proc_t* proc = arch_getcls()->thread->proc; - error = vfs_resolvepath(&iterator, NULL, iterator, linkname, namebuff, true, maxloop-1); // XXX this might break some parent stuff when following links + dirnode_t* root = proc ? proc->root : vfs_root(); + vnode_t* ref = linkname[0] == '/' ? root : iterator; + + error = vfs_resolvepath(&iterator, NULL, ref, linkname, namebuff, true, maxloop-1); // XXX this might break some parent stuff when following links free(linkname); @@ -641,8 +658,14 @@ int vfs_resolvepath(vnode_t** result, dirnode_t** resultparent, dirnode_t* ref, return error; linkname[size] = '\0'; + + proc_t* proc = arch_getcls()->thread->proc; - error = vfs_resolvepath(&iterator, NULL, iterator->vnode.parent, linkname, namebuff, true, maxloop-1); // XXX this might break some parent stuff when following links + dirnode_t* root = proc ? proc->root : vfs_root(); + vnode_t* ref = linkname[0] == '/' ? root : iterator->vnode.parent; + + + error = vfs_resolvepath(&iterator, NULL, ref, linkname, namebuff, true, maxloop-1); // XXX this might break some parent stuff when following links free(linkname); diff --git a/src/include/kernel/socket.h b/src/include/kernel/socket.h index 8b52ad91..cb4eb1cc 100644 --- a/src/include/kernel/socket.h +++ b/src/include/kernel/socket.h @@ -17,6 +17,8 @@ #define SOCK_STREAM 1 #define AF_UNIX 1 +typedef unsigned socklen_t; + typedef struct _socket_t{ int lock; int family; @@ -59,10 +61,10 @@ static inline socket_t* socket_popfrombacklog(socket_t* listener){ return sock; } -int socket_connect(struct _socket_t* sock, void* addr, size_t addrlen); +int socket_connect(struct _socket_t* sock, void* addr, socklen_t addrlen); int socket_new(socket_t** returnptr, int family, int type, int protocol); -int socket_bind(struct _socket_t* sock, void* addr, size_t addrlen); +int socket_bind(struct _socket_t* sock, void* addr, socklen_t addrlen); int socket_listen(struct _socket_t* sock, int backlog); -int socket_accept(socket_t** peer, socket_t* sock, void* addr, size_t* addrlen); -int socket_send(socket_t* socket, void* buff, size_t len, int flags, int* error); +int socket_accept(socket_t** peer, socket_t* sock, void* addr, socklen_t* addrlen); +int socket_send(socket_t* socket, void* buff, socklen_t len, int flags, int* error); #endif diff --git a/src/include/kernel/unsocket.h b/src/include/kernel/unsocket.h index 9623c139..dc5a7cb9 100644 --- a/src/include/kernel/unsocket.h +++ b/src/include/kernel/unsocket.h @@ -9,8 +9,9 @@ typedef struct { } sockaddr_un; struct _socket_t; +typedef unsigned socklen_t; int unsocket_new(struct _socket_t** returnptr, int type, int protocol); -int unsocket_bind(struct _socket_t* sock, sockaddr_un* addr, size_t addrlen); -int unsocket_send(struct _socket_t* socket, void* buff, size_t len, int flags, int* error); +int unsocket_bind(struct _socket_t* sock, sockaddr_un* addr, socklen_t addrlen); +int unsocket_send(struct _socket_t* socket, void* buff, socklen_t len, int flags, int* error); #endif diff --git a/src/sys/mm/vmm.c b/src/sys/mm/vmm.c index 6d26c116..79536f39 100644 --- a/src/sys/mm/vmm.c +++ b/src/sys/mm/vmm.c @@ -187,7 +187,7 @@ static bool setmap(vmm_mapping** mapstart, void* addr, size_t pagec, size_t mmuf return false; } - // unallocate entries inbetween + // unallocate entries inbetween TODO sync file vmm_mapping* loopmap = map->next; @@ -225,7 +225,7 @@ static bool setmap(vmm_mapping** mapstart, void* addr, size_t pagec, size_t mmuf } - // do we need to split? + // do we need to split? TODO add more file refs if(map->start != newmap->start && map->end != newmap->end){ vmm_mapping* splitmap = allocatefirst(); @@ -324,7 +324,8 @@ static bool unmap(vmm_mapping** mapstart, void* addr, size_t pagec){ vmm_mapping *map = *mapstart; void* savedaddr = addr; arch_mmu_tableptr context = arch_getcls()->context->context; - + int err; + for(size_t page = 0; page < pagec; ++page, addr += PAGE_SIZE){ map = findmappingfromaddr(map, addr); switch(map->type){ @@ -337,7 +338,10 @@ static bool unmap(vmm_mapping** mapstart, void* addr, size_t pagec){ break; case VMM_TYPE_FILE: - _panic("File mappings not supported!", 0); + vfs_write(&err, map->data, addr, PAGE_SIZE, map->offset + page*PAGE_SIZE); + void* paddr = arch_mmu_getphysicaladdr(context, addr); + pmm_free(paddr, 1); + arch_mmu_unmap(context, addr); default: continue; @@ -397,9 +401,7 @@ int vmm_fork(vmm_context* oldctx, vmm_context* newctx){ vmm_mapping* mapping = oldctx->userstart; while(mapping){ - - if(mapping->type == VMM_TYPE_FILE) - _panic("File mappings not supported yet!", NULL); + size_t pagesize =((uintptr_t)mapping->end - (uintptr_t)mapping->start + 1) / PAGE_SIZE; @@ -407,6 +409,10 @@ int vmm_fork(vmm_context* oldctx, vmm_context* newctx){ goto _fail; + + if(mapping->type == VMM_TYPE_FILE) + ++((vnode_t*)mapping->data)->refcount; + if(mapping->type == VMM_TYPE_ANON){ @@ -656,9 +662,6 @@ bool vmm_dealwithrequest(void* addr, long error, bool user){ goto done; } - if(map->type == VMM_TYPE_FILE) - _panic("File mappings are not supported (yet)", 0); - size_t goodmmuflags = 1; if(error & ARCH_MMU_ERROR_WRITE) @@ -680,9 +683,6 @@ bool vmm_dealwithrequest(void* addr, long error, bool user){ // allocate a page addr = (size_t)addr & ~(0xFFF); - - //printf("Demand paging %p\n", addr); - cls_t* cls = arch_getcls(); @@ -696,9 +696,15 @@ bool vmm_dealwithrequest(void* addr, long error, bool user){ goto done; } - status = true; - memset(addr, 0, PAGE_SIZE); + + if(map->type == VMM_TYPE_FILE){ // TODO check for errors? + int err; + size_t offset = addr - map->start; + vfs_read(&err, map->data, addr, PAGE_SIZE, map->offset + offset); + } + + status = true; done: diff --git a/src/sys/socket.c b/src/sys/socket.c index c30b783d..15b433b7 100644 --- a/src/sys/socket.c +++ b/src/sys/socket.c @@ -3,6 +3,7 @@ #include #include #include +#include int socket_new(struct _socket_t** returnptr, int family, int type, int protocol){ @@ -18,7 +19,7 @@ int socket_new(struct _socket_t** returnptr, int family, int type, int protocol) // TODO move around locks and tests -int socket_bind(struct _socket_t* sock, void* addr, size_t addrlen){ +int socket_bind(struct _socket_t* sock, void* addr, socklen_t addrlen){ if(sock->addrlen) return EINVAL; @@ -64,7 +65,7 @@ int socket_listen(struct _socket_t* sock, int backlog){ } -int socket_connect(struct _socket_t* sock, void* addr, size_t addrlen){ +int socket_connect(struct _socket_t* sock, void* addr, socklen_t addrlen){ switch(sock->family){ case AF_UNIX: @@ -75,7 +76,7 @@ int socket_connect(struct _socket_t* sock, void* addr, size_t addrlen){ } -int socket_accept(socket_t** peer, socket_t* sock, void* addr, size_t* addrlen){ +int socket_accept(socket_t** peer, socket_t* sock, void* addr, socklen_t* addrlen){ switch(sock->family){ case AF_UNIX: return unsocket_accept(peer, sock, addr, addrlen); @@ -84,7 +85,7 @@ int socket_accept(socket_t** peer, socket_t* sock, void* addr, size_t* addrlen){ } } -int socket_send(socket_t* socket, void* buff, size_t len, int flags, int* count){ +int socket_send(socket_t* socket, void* buff, socklen_t len, int flags, int* count){ switch(socket->family){ case AF_UNIX: return unsocket_send(socket, buff, len, flags, count); @@ -93,7 +94,7 @@ int socket_send(socket_t* socket, void* buff, size_t len, int flags, int* count) } } -int socket_recv(socket_t* socket, void* buff, size_t len, int flags, int* count){ +int socket_recv(socket_t* socket, void* buff, socklen_t len, int flags, int* count){ switch(socket->family){ case AF_UNIX: return unsocket_recv(socket, buff, len, flags, count); @@ -101,3 +102,12 @@ int socket_recv(socket_t* socket, void* buff, size_t len, int flags, int* count) return EINVAL; } } + +int socket_poll(socket_t* socket, pollfd* fd){ + switch(socket->family){ + case AF_UNIX: + return unsocket_poll(socket, fd); + default: + return EINVAL; + } +} diff --git a/src/sys/syscalls/accept.c b/src/sys/syscalls/accept.c index a052e8b8..1eb89831 100644 --- a/src/sys/syscalls/accept.c +++ b/src/sys/syscalls/accept.c @@ -6,7 +6,7 @@ extern fs_t kerneltmpfs; -syscallret syscall_accept(int sockfd, void* addr, size_t* addrlen){ +syscallret syscall_accept(int sockfd, void* addr, socklen_t* addrlen){ syscallret retv; retv.ret = -1; diff --git a/src/sys/syscalls/bind.c b/src/sys/syscalls/bind.c index 65677044..37e74089 100644 --- a/src/sys/syscalls/bind.c +++ b/src/sys/syscalls/bind.c @@ -6,7 +6,7 @@ #include #include -syscallret syscall_bind(int sockfd, void* addr, size_t addrlen){ +syscallret syscall_bind(int sockfd, void* addr, socklen_t addrlen){ syscallret retv; retv.ret = -1; diff --git a/src/sys/syscalls/poll.c b/src/sys/syscalls/poll.c index 9558efe0..8702bb08 100644 --- a/src/sys/syscalls/poll.c +++ b/src/sys/syscalls/poll.c @@ -4,6 +4,7 @@ #include #include #include +#include #define MAXNFDS 4096 @@ -78,6 +79,9 @@ syscallret syscall_poll(pollfd *fds, size_t nfds, int timeoutms){ // TODO check for signal or timeout if(timeoutms == 0) break; + arch_interrupt_disable(); + sched_yield(); + arch_interrupt_enable(); } diff --git a/src/sys/unsocket.c b/src/sys/unsocket.c index 1e14be05..e4e27960 100644 --- a/src/sys/unsocket.c +++ b/src/sys/unsocket.c @@ -7,6 +7,7 @@ #include #include #include +#include int unsocket_new(socket_t** returnptr, int type, int protocol){ @@ -33,7 +34,7 @@ int unsocket_new(socket_t** returnptr, int type, int protocol){ } -int unsocket_bind(struct _socket_t* sock, sockaddr_un* addr, size_t addrlen){ +int unsocket_bind(struct _socket_t* sock, sockaddr_un* addr, socklen_t addrlen){ // copy address @@ -80,7 +81,7 @@ int unsocket_bind(struct _socket_t* sock, sockaddr_un* addr, size_t addrlen){ } -int unsocket_connect(struct _socket_t* sock, void* addr, size_t addrlen){ +int unsocket_connect(struct _socket_t* sock, void* addr, socklen_t addrlen){ // copy address @@ -175,18 +176,17 @@ int unsocket_connect(struct _socket_t* sock, void* addr, size_t addrlen){ } -int unsocket_accept(socket_t** peer, socket_t* sock, void* addr, size_t* addrlen){ +int unsocket_accept(socket_t** peer, socket_t* sock, void* addr, socklen_t* addrlen){ // TODO abort - size_t len = *addrlen; + socklen_t len = *addrlen; int err = 0; if(*addrlen > sizeof(sockaddr_un)) return EINVAL; - spinlock_acquire(&sock->lock); if(sock->state != SOCKET_STATE_LISTENING){ @@ -202,8 +202,6 @@ int unsocket_accept(socket_t** peer, socket_t* sock, void* addr, size_t* addrlen spinlock_acquire(&sock->lock); } - // TODO put peer name here - *peer = socket_popfrombacklog(sock); spinlock_release(&sock->lock); @@ -214,7 +212,7 @@ int unsocket_accept(socket_t** peer, socket_t* sock, void* addr, size_t* addrlen } -int unsocket_send(socket_t* socket, void* buff, size_t len, int flags, int* error){ +int unsocket_send(socket_t* socket, void* buff, socklen_t len, int flags, int* error){ if(flags){ // right now no flags are supported *error = EOPNOTSUPP; @@ -266,7 +264,9 @@ int unsocket_send(socket_t* socket, void* buff, size_t len, int flags, int* erro } -int unsocket_recv(socket_t* socket, void* buff, size_t len, int flags, int* error){ +// TODO check for broken + +int unsocket_recv(socket_t* socket, void* buff, socklen_t len, int flags, int* error){ if(flags){ // right now no flags are supported *error = EOPNOTSUPP; @@ -314,3 +314,35 @@ int unsocket_recv(socket_t* socket, void* buff, size_t len, int flags, int* erro return readc; } + +int unsocket_poll(socket_t* socket, pollfd* fd){ + spinlock_acquire(&socket->lock); + + // TODO outgoing connect finished + + switch(socket->state){ + case SOCKET_STATE_LISTENING: + if(fd->events & POLLIN && socket->backlogend) + fd->revents |= POLLIN; + + break; + case SOCKET_STATE_CONNECTED: + + if(!socket->peer) + fd->revents |= POLLHUP; + + if(fd->events & POLLIN && socket->buffer.write != socket->buffer.read) + fd->revents |= POLLIN; + + if(fd->events & POLLOUT && socket->buffer.write != socket->buffer.read + socket->buffer.size) + fd->revents |= POLLOUT; + + break; + default: + return 0; + } + + spinlock_release(&socket->lock); + return 0; +} +