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);
+}