lib: fdtable: Add callback for close() calls
Do not route close() calls via ioctl() as that is error prone and quite pointless. Instead create a callback for close() in fdtable and use it directly. Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
4f34d90c8c
commit
2ed6b6a8ed
12 changed files with 108 additions and 64 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue