diff --git a/drivers/modem/ublox-sara-r4.c b/drivers/modem/ublox-sara-r4.c index a747b5d6279..30e23e5c2a3 100644 --- a/drivers/modem/ublox-sara-r4.c +++ b/drivers/modem/ublox-sara-r4.c @@ -1453,13 +1453,14 @@ static ssize_t offload_sendto(void *obj, const void *buf, size_t len, return ret; } +static int offload_close(void *obj) +{ + return offload_close((struct modem_socket *)obj); +} + static int offload_ioctl(void *obj, unsigned int request, va_list args) { switch (request) { - /* Handle close specifically. */ - case ZFD_IOCTL_CLOSE: - return offload_close((struct modem_socket *)obj); - case ZFD_IOCTL_POLL_PREPARE: return -EXDEV; @@ -1532,6 +1533,7 @@ static const struct socket_op_vtable offload_socket_fd_op_vtable = { .fd_vtable = { .read = offload_read, .write = offload_write, + .close = offload_close, .ioctl = offload_ioctl, }, .bind = offload_bind, diff --git a/drivers/wifi/eswifi/eswifi_socket_offload.c b/drivers/wifi/eswifi/eswifi_socket_offload.c index 9d880e6e6d9..ffb59f5e6ce 100644 --- a/drivers/wifi/eswifi/eswifi_socket_offload.c +++ b/drivers/wifi/eswifi/eswifi_socket_offload.c @@ -499,15 +499,16 @@ static int eswifi_socket_create(int family, int type, int proto) return fd; } +static int eswifi_socket_close(void *obj) +{ + return eswifi_socket_close(sd); +} + static int eswifi_socket_ioctl(void *obj, unsigned int request, va_list args) { int sd = OBJ_TO_SD(obj); switch (request) { - /* Handle close specifically. */ - case ZFD_IOCTL_CLOSE: - return eswifi_socket_close(sd); - case ZFD_IOCTL_POLL_PREPARE: return -EXDEV; @@ -547,6 +548,7 @@ static const struct socket_op_vtable eswifi_socket_fd_op_vtable = { .fd_vtable = { .read = eswifi_socket_read, .write = eswifi_socket_write, + .close = eswifi_socket_close, .ioctl = eswifi_socket_ioctl, }, .bind = eswifi_socket_bind, diff --git a/drivers/wifi/simplelink/simplelink_sockets.c b/drivers/wifi/simplelink/simplelink_sockets.c index fc3e5ad6539..cc3ee708df0 100644 --- a/drivers/wifi/simplelink/simplelink_sockets.c +++ b/drivers/wifi/simplelink/simplelink_sockets.c @@ -1124,15 +1124,16 @@ exit: return retval; } +static int simplelink_close(void *obj) +{ + return simplelink_close(sd); +} + static int simplelink_ioctl(void *obj, unsigned int request, va_list args) { int sd = OBJ_TO_SD(obj); switch (request) { - /* Handle close specifically. */ - case ZFD_IOCTL_CLOSE: - return simplelink_close(sd); - case ZFD_IOCTL_POLL_PREPARE: return -EXDEV; @@ -1174,6 +1175,7 @@ static const struct socket_op_vtable simplelink_socket_fd_op_vtable = { .fd_vtable = { .read = simplelink_read, .write = simplelink_write, + .close = simplelink_close, .ioctl = simplelink_ioctl, }, .bind = simplelink_bind, diff --git a/include/sys/fdtable.h b/include/sys/fdtable.h index 0cd4b2513d0..e1c369a4bb0 100644 --- a/include/sys/fdtable.h +++ b/include/sys/fdtable.h @@ -17,11 +17,12 @@ extern "C" { /** * File descriptor virtual method table. - * All operations beyond read/write go thru ioctl method. + * Currently all operations beyond read/write/close go thru ioctl method. */ struct fd_op_vtable { ssize_t (*read)(void *obj, void *buf, size_t sz); ssize_t (*write)(void *obj, const void *buf, size_t sz); + int (*close)(void *obj); int (*ioctl)(void *obj, unsigned int request, va_list args); }; @@ -135,8 +136,7 @@ static inline int z_fdtable_call_ioctl(const struct fd_op_vtable *vtable, void * */ enum { /* Codes below 0x100 are reserved for fcntl() codes. */ - ZFD_IOCTL_CLOSE = 0x100, - ZFD_IOCTL_FSYNC, + ZFD_IOCTL_FSYNC = 0x100, ZFD_IOCTL_LSEEK, ZFD_IOCTL_POLL_PREPARE, ZFD_IOCTL_POLL_UPDATE, diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index f36ae4f8da3..de62cd81866 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -222,7 +222,8 @@ int close(int fd) return -1; } - res = z_fdtable_call_ioctl(fdtable[fd].vtable, fdtable[fd].obj, ZFD_IOCTL_CLOSE); + res = fdtable[fd].vtable->close(fdtable[fd].obj); + z_free_fd(fd); return res; diff --git a/lib/posix/eventfd.c b/lib/posix/eventfd.c index 4b913c9900b..ab02521a59f 100644 --- a/lib/posix/eventfd.c +++ b/lib/posix/eventfd.c @@ -130,6 +130,15 @@ static ssize_t eventfd_write_op(void *obj, const void *buf, size_t sz) return sizeof(eventfd_t); } +static int eventfd_close_op(void *obj) +{ + struct eventfd *efd = (struct eventfd *)obj; + + efd->flags = 0; + + return 0; +} + static int eventfd_ioctl_op(void *obj, unsigned int request, va_list args) { struct eventfd *efd = (struct eventfd *)obj; @@ -153,10 +162,6 @@ static int eventfd_ioctl_op(void *obj, unsigned int request, va_list args) return 0; } - case ZFD_IOCTL_CLOSE: - efd->flags = 0; - return 0; - case ZFD_IOCTL_POLL_PREPARE: { struct zsock_pollfd *pfd; struct k_poll_event **pev; @@ -188,6 +193,7 @@ static int eventfd_ioctl_op(void *obj, unsigned int request, va_list args) static const struct fd_op_vtable eventfd_fd_vtable = { .read = eventfd_read_op, .write = eventfd_write_op, + .close = eventfd_close_op, .ioctl = eventfd_ioctl_op, }; diff --git a/lib/posix/fs.c b/lib/posix/fs.c index 3224a4da373..230d44dc99b 100644 --- a/lib/posix/fs.c +++ b/lib/posix/fs.c @@ -123,17 +123,23 @@ int open(const char *name, int flags, ...) return fd; } +static int fs_close_vmeth(void *obj) +{ + struct posix_fs_desc *ptr = obj; + int rc; + + rc = fs_close(&ptr->file); + posix_fs_free_obj(ptr); + + return rc; +} + static int fs_ioctl_vmeth(void *obj, unsigned int request, va_list args) { int rc = 0; struct posix_fs_desc *ptr = obj; switch (request) { - case ZFD_IOCTL_CLOSE: - rc = fs_close(&ptr->file); - posix_fs_free_obj(ptr); - break; - case ZFD_IOCTL_LSEEK: { off_t offset; int whence; @@ -202,6 +208,7 @@ static ssize_t fs_read_vmeth(void *obj, void *buffer, size_t count) static struct fd_op_vtable fs_fd_op_vtable = { .read = fs_read_vmeth, .write = fs_write_vmeth, + .close = fs_close_vmeth, .ioctl = fs_ioctl_vmeth, }; diff --git a/subsys/net/lib/sockets/socketpair.c b/subsys/net/lib/sockets/socketpair.c index fb5be1e69be..01b7849d005 100644 --- a/subsys/net/lib/sockets/socketpair.c +++ b/subsys/net/lib/sockets/socketpair.c @@ -927,14 +927,6 @@ static int spair_ioctl(void *obj, unsigned int request, va_list args) goto out; } - case ZFD_IOCTL_CLOSE: { - /* disconnect the remote endpoint */ - spair_delete(spair); - have_local_sem = false; - res = 0; - goto out; - } - case ZFD_IOCTL_POLL_PREPARE: { pfd = va_arg(args, struct zsock_pollfd *); pev = va_arg(args, struct k_poll_event **); @@ -1129,10 +1121,27 @@ static int spair_setsockopt(void *obj, int level, int optname, return -1; } +static int spair_close(void *obj) +{ + struct spair *const spair = (struct spair *)obj; + int res; + + res = k_sem_take(&spair->sem, K_FOREVER); + __ASSERT(res == 0, "failed to take local sem: %d", res); + + /* disconnect the remote endpoint */ + spair_delete(spair); + + /* Note that the semaphore released already so need to do it here */ + + return 0; +} + static const struct socket_op_vtable spair_fd_op_vtable = { .fd_vtable = { .read = spair_read, .write = spair_write, + .close = spair_close, .ioctl = spair_ioctl, }, .bind = spair_bind, diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 814ff3f3d1f..b46a5066242 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -247,18 +247,20 @@ int z_impl_zsock_close(int sock) { const struct socket_op_vtable *vtable; void *ctx = get_sock_vtable(sock, &vtable); + int ret; if (ctx == NULL) { errno = EBADF; return -1; } - z_free_fd(sock); - NET_DBG("close: ctx=%p, fd=%d", ctx, sock); - return z_fdtable_call_ioctl((const struct fd_op_vtable *)vtable, - ctx, ZFD_IOCTL_CLOSE); + ret = vtable->fd_vtable.close(ctx); + + z_free_fd(sock); + + return ret; } #ifdef CONFIG_USERSPACE @@ -1747,9 +1749,6 @@ static int sock_ioctl_vmeth(void *obj, unsigned int request, va_list args) return 0; } - case ZFD_IOCTL_CLOSE: - return zsock_close_ctx(obj); - case ZFD_IOCTL_POLL_PREPARE: { struct zsock_pollfd *pfd; struct k_poll_event **pev; @@ -1844,11 +1843,16 @@ static int sock_setsockopt_vmeth(void *obj, int level, int optname, return zsock_setsockopt_ctx(obj, level, optname, optval, optlen); } +static int sock_close_vmeth(void *obj) +{ + return zsock_close_ctx(obj); +} const struct socket_op_vtable sock_fd_op_vtable = { .fd_vtable = { .read = sock_read_vmeth, .write = sock_write_vmeth, + .close = sock_close_vmeth, .ioctl = sock_ioctl_vmeth, }, .bind = sock_bind_vmeth, diff --git a/subsys/net/lib/sockets/sockets_can.c b/subsys/net/lib/sockets/sockets_can.c index fcb9818a08f..97fcc15cdec 100644 --- a/subsys/net/lib/sockets/sockets_can.c +++ b/subsys/net/lib/sockets/sockets_can.c @@ -407,17 +407,23 @@ static int can_close_socket(struct net_context *ctx) return 0; } -static int can_sock_ioctl_vmeth(void *obj, unsigned int request, va_list args) +static int can_sock_close_vmeth(void *obj) { - if (request == ZFD_IOCTL_CLOSE) { - int ret; + int ret; - ret = can_close_socket(obj); - if (ret < 0) { - NET_DBG("Cannot detach net_context %p (%d)", obj, ret); - } + ret = can_close_socket(obj); + if (ret < 0) { + NET_DBG("Cannot detach net_context %p (%d)", obj, ret); + + errno = -ret; + ret = -1; } + return ret; +} + +static int can_sock_ioctl_vmeth(void *obj, unsigned int request, va_list args) +{ return sock_fd_op_vtable.fd_vtable.ioctl(obj, request, args); } @@ -670,6 +676,7 @@ static const struct socket_op_vtable can_sock_fd_op_vtable = { .fd_vtable = { .read = can_sock_read_vmeth, .write = can_sock_write_vmeth, + .close = can_sock_close_vmeth, .ioctl = can_sock_ioctl_vmeth, }, .bind = can_sock_bind_vmeth, diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index e9f69856fb8..a36a2668748 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -1198,7 +1198,7 @@ int ztls_close_ctx(struct net_context *ctx) err = -EBADF; } - ret = z_fdtable_call_ioctl(&sock_fd_op_vtable.fd_vtable, ctx, ZFD_IOCTL_CLOSE); + ret = sock_fd_op_vtable.fd_vtable.close(ctx); /* In case close fails, we propagate errno value set by close. * In case close succeeds, but tls_release fails, set errno @@ -1340,7 +1340,7 @@ error: __ASSERT(err == 0, "TLS context release failed"); } - err = z_fdtable_call_ioctl(&sock_fd_op_vtable.fd_vtable, child, ZFD_IOCTL_CLOSE); + err = sock_fd_op_vtable.fd_vtable.close(child); __ASSERT(err == 0, "Child socket close failed"); z_free_fd(fd); @@ -1956,9 +1956,6 @@ static int tls_sock_ioctl_vmeth(void *obj, unsigned int request, va_list args) /* Pass the call to the core socket implementation. */ return sock_fd_op_vtable.fd_vtable.ioctl(obj, request, args); - case ZFD_IOCTL_CLOSE: - return ztls_close_ctx(obj); - case ZFD_IOCTL_POLL_PREPARE: { struct zsock_pollfd *pfd; struct k_poll_event **pev; @@ -2044,11 +2041,16 @@ static int tls_sock_setsockopt_vmeth(void *obj, int level, int optname, return ztls_setsockopt_ctx(obj, level, optname, optval, optlen); } +static int tls_sock_close_vmeth(void *obj) +{ + return ztls_close_ctx(obj); +} static const struct socket_op_vtable tls_sock_fd_op_vtable = { .fd_vtable = { .read = tls_sock_read_vmeth, .write = tls_sock_write_vmeth, + .close = tls_sock_close_vmeth, .ioctl = tls_sock_ioctl_vmeth, }, .bind = tls_sock_bind_vmeth, diff --git a/subsys/net/lib/websocket/websocket.c b/subsys/net/lib/websocket/websocket.c index e24e12d3961..8bd2bfb5b0e 100644 --- a/subsys/net/lib/websocket/websocket.c +++ b/subsys/net/lib/websocket/websocket.c @@ -418,23 +418,24 @@ int websocket_disconnect(int ws_sock) return ret; } -static int websocket_ioctl_vmeth(void *obj, unsigned int request, va_list args) +static int websocket_close_vmeth(void *obj) { - if (request == ZFD_IOCTL_CLOSE) { - struct websocket_context *ctx = obj; - int ret; + struct websocket_context *ctx = obj; + int ret; - ret = websocket_disconnect(ctx->sock); - if (ret < 0) { - NET_DBG("[%p] Cannot close (%d)", obj, ret); + ret = websocket_disconnect(ctx->sock); + if (ret < 0) { + NET_DBG("[%p] Cannot close (%d)", obj, ret); - errno = -ret; - return -1; - } - - return ret; + errno = -ret; + return -1; } + return ret; +} + +static int websocket_ioctl_vmeth(void *obj, unsigned int request, va_list args) +{ return sock_fd_op_vtable.fd_vtable.ioctl(obj, request, args); } @@ -954,6 +955,7 @@ static const struct socket_op_vtable websocket_fd_op_vtable = { .fd_vtable = { .read = websocket_read_vmeth, .write = websocket_write_vmeth, + .close = websocket_close_vmeth, .ioctl = websocket_ioctl_vmeth, }, .sendto = websocket_sendto_ctx,