From 305ec62a6b1fc2aee8ecb1a8c34f09492114ba28 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Sat, 15 Jun 2024 11:44:44 -0400 Subject: [PATCH] posix: device_io: implement pselect() Implement pselect() as it's required by POSIX_DEVICE_IO Signed-off-by: Chris Friedt --- include/zephyr/net/socket_select.h | 7 +++++-- include/zephyr/posix/sys/select.h | 2 ++ include/zephyr/sys/fdtable.h | 2 +- lib/os/zvfs/zvfs_select.c | 12 +++++++----- lib/posix/options/device_io.c | 13 ++++++++++++- tests/posix/headers/src/sys_select_h.c | 2 +- 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/include/zephyr/net/socket_select.h b/include/zephyr/net/socket_select.h index 877bd863a6b8..3eaa9aacfcfe 100644 --- a/include/zephyr/net/socket_select.h +++ b/include/zephyr/net/socket_select.h @@ -51,9 +51,12 @@ typedef struct zvfs_fd_set zsock_fd_set; static inline int zsock_select(int nfds, zsock_fd_set *readfds, zsock_fd_set *writefds, zsock_fd_set *exceptfds, struct zsock_timeval *timeout) { - struct timeval; + struct timespec to = { + .tv_sec = (timeout == NULL) ? 0 : timeout->tv_sec, + .tv_nsec = (long)((timeout == NULL) ? 0 : timeout->tv_usec * NSEC_PER_USEC)}; - return zvfs_select(nfds, readfds, writefds, exceptfds, (struct timeval *)timeout); + return zvfs_select(nfds, (struct zvfs_fd_set *)readfds, (struct zvfs_fd_set *)writefds, + (struct zvfs_fd_set *)exceptfds, (timeout == NULL) ? NULL : &to, NULL); } /** Number of file descriptors which can be added to zsock_fd_set */ diff --git a/include/zephyr/posix/sys/select.h b/include/zephyr/posix/sys/select.h index e10eeb237ee0..78d900f5316b 100644 --- a/include/zephyr/posix/sys/select.h +++ b/include/zephyr/posix/sys/select.h @@ -20,6 +20,8 @@ extern "C" { struct timeval; +int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + const struct timespec *timeout, const void *sigmask); int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout); void FD_CLR(int fd, fd_set *fdset); int FD_ISSET(int fd, fd_set *fdset); diff --git a/include/zephyr/sys/fdtable.h b/include/zephyr/sys/fdtable.h index 86e254a05d7d..871878eb53e0 100644 --- a/include/zephyr/sys/fdtable.h +++ b/include/zephyr/sys/fdtable.h @@ -223,7 +223,7 @@ struct timespec; __syscall int zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, struct zvfs_fd_set *ZRESTRICT writefds, struct zvfs_fd_set *ZRESTRICT errorfds, - const struct timeval *ZRESTRICT timeout); + const struct timespec *ZRESTRICT timeout, const void *ZRESTRICT sigmask); /** * Request codes for fd_op_vtable.ioctl(). diff --git a/lib/os/zvfs/zvfs_select.c b/lib/os/zvfs/zvfs_select.c index 36a8457db0fc..2788e3c9318f 100644 --- a/lib/os/zvfs/zvfs_select.c +++ b/lib/os/zvfs/zvfs_select.c @@ -77,7 +77,7 @@ void ZVFS_FD_SET(int fd, struct zvfs_fd_set *set) int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, struct zvfs_fd_set *ZRESTRICT writefds, struct zvfs_fd_set *ZRESTRICT exceptfds, - const struct timeval *ZRESTRICT timeout) + const struct timespec *ZRESTRICT timeout, const void *ZRESTRICT sigmask) { struct zvfs_pollfd pfds[CONFIG_ZVFS_POLL_MAX]; k_timeout_t poll_timeout; @@ -142,7 +142,8 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, if (timeout == NULL) { poll_timeout = K_FOREVER; } else { - poll_timeout = K_USEC(timeout->tv_sec * USEC_PER_SEC + timeout->tv_usec); + poll_timeout = + K_USEC(timeout->tv_sec * USEC_PER_SEC + timeout->tv_nsec / NSEC_PER_USEC); } res = zvfs_poll_internal(pfds, num_pfds, poll_timeout); @@ -220,10 +221,11 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, struct zvfs_fd_set *ZRESTRICT writefds, struct zvfs_fd_set *ZRESTRICT exceptfds, - const struct timeval *ZRESTRICT timeout) + const struct timespec *ZRESTRICT timeout, + const void *ZRESTRICT sigmask) { struct zvfs_fd_set *readfds_copy = NULL, *writefds_copy = NULL, *exceptfds_copy = NULL; - struct timeval *to = NULL; + struct timespec *to = NULL; int ret = -1; if (readfds) { @@ -261,7 +263,7 @@ static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } } - ret = z_impl_zvfs_select(nfds, readfds_copy, writefds_copy, exceptfds_copy, to); + ret = z_impl_zvfs_select(nfds, readfds_copy, writefds_copy, exceptfds_copy, to, sigmask); if (ret >= 0) { if (readfds_copy) { diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index eaae1c69c79e..d15b5da2a91a 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -71,6 +71,12 @@ ssize_t pread(int fd, void *buf, size_t count, off_t offset) return zvfs_read(fd, buf, count, (size_t *)&off); } +int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + const struct timespec *timeout, const void *sigmask) +{ + return zvfs_select(nfds, readfds, writefds, exceptfds, timeout, sigmask); +} + ssize_t pwrite(int fd, void *buf, size_t count, off_t offset) { size_t off = (size_t)offset; @@ -93,7 +99,12 @@ FUNC_ALIAS(read, _read, ssize_t); int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { - return zvfs_select(nfds, readfds, writefds, exceptfds, timeout); + struct timespec to = { + .tv_sec = (timeout == NULL) ? 0 : timeout->tv_sec, + .tv_nsec = (long)((timeout == NULL) ? 0 : timeout->tv_usec * NSEC_PER_USEC)}; + + return zvfs_select(nfds, readfds, writefds, exceptfds, (timeout == NULL) ? NULL : &to, + NULL); } ssize_t write(int fd, const void *buf, size_t sz) diff --git a/tests/posix/headers/src/sys_select_h.c b/tests/posix/headers/src/sys_select_h.c index 49fd4dc8ed5f..ad1014c5b446 100644 --- a/tests/posix/headers/src/sys_select_h.c +++ b/tests/posix/headers/src/sys_select_h.c @@ -30,7 +30,7 @@ ZTEST(posix_headers, test_sys_select_h) FD_SET(0, &fds); FD_ZERO(&fds); - /* zassert_not_null(pselect); */ /* not implemented */ + zassert_not_null(pselect); zassert_not_null(select); } }