From 8f5003814e0c210423eae3914ce0fe76ce359c19 Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Fri, 4 Oct 2019 15:38:29 +0900 Subject: [PATCH] Add soclose() and sofree() functions --- kernel/core/socket.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ kernel/core/socket.h | 3 +++ 2 files changed, 66 insertions(+) diff --git a/kernel/core/socket.c b/kernel/core/socket.c index 51dd1b8..d5528e4 100644 --- a/kernel/core/socket.c +++ b/kernel/core/socket.c @@ -164,3 +164,66 @@ gtfo: return(ret_val); } + +int soclose(int sockfd) +{ + int ret_val; + + ret_val = -EINVAL; + + if(sockfd >= 0 && sockfd < (sizeof(_sockets) / sizeof(_sockets[0]))) { + struct socket *so; + + ret_val = -EBADF; + so = _sockets[sockfd]; + + /* + * `so' may be SOCKET_PREALLOC, if it is currently being + * allocated by a different thread - in which case we must + * leave it alone. + */ + if(so && so != SOCKET_PREALLOC) { + /* + * Reduce the socket's refcount and free it if + * there are no more references to it. + */ + so->so_refs--; + + if(!so->so_refs) { + ret_val = sofree(sockfd); + } else { + ret_val = 0; + } + } + } + + return(ret_val); +} + +int sofree(int sockfd) +{ + int ret_val; + + ret_val = -EINVAL; + + /* + * The same checks should already have been performed by the caller, but + * better safe than sorry. + */ + if(sockfd >= 0 && sockfd < (sizeof(_sockets) / sizeof(_sockets[0]))) { + struct socket *so; + + ret_val = -EBADF; + so = _sockets[sockfd]; + + if(so && so != SOCKET_PREALLOC) { + _sockets[sockfd] = NULL; + _nsockets--; + + /* TODO: PRU_DETACH */ + kfree(so); + } + } + + return(ret_val); +} diff --git a/kernel/core/socket.h b/kernel/core/socket.h index a36681a..a5eed13 100644 --- a/kernel/core/socket.h +++ b/kernel/core/socket.h @@ -8,6 +8,7 @@ struct socket { u16_t so_type; + u16_t so_refs; /* that's all for now */ #if 0 u16_t so_options; @@ -20,5 +21,7 @@ struct socket { }; int socreate(int, int, int); +int soclose(int); +int sofree(int); #endif /* __SOCKET_H */ -- 2.47.3