From 8180bb08e699b3dd97fa51be6d6328b25a4eac12 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:05:53 +0200 Subject: [PATCH 01/18] Revert "doc: posix: mark posis fd mgmt as supported" PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 This reverts commit e9b676a9ab4c4a977ec6507219dd983248ae630a. Signed-off-by: Alberto Escolar Piedras --- doc/services/portability/posix/aep/index.rst | 2 +- .../portability/posix/option_groups/index.rst | 28 +++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/doc/services/portability/posix/aep/index.rst b/doc/services/portability/posix/aep/index.rst index 651bc43b0cf52..b1fe34ee0d986 100644 --- a/doc/services/portability/posix/aep/index.rst +++ b/doc/services/portability/posix/aep/index.rst @@ -101,7 +101,7 @@ The *Realtime Controller System Profile* (PSE52) includes all features from PSE5 :widths: 50, 10, 50 :ref:`POSIX_C_LANG_MATH `, yes, - :ref:`POSIX_FD_MGMT `, yes, :kconfig:option:`CONFIG_POSIX_FD_MGMT` + :ref:`POSIX_FD_MGMT `,, :kconfig:option:`CONFIG_POSIX_FD_MGMT` :ref:`POSIX_FILE_SYSTEM `,, :kconfig:option:`CONFIG_POSIX_FILE_SYSTEM` .. csv-table:: PSE52 Option Requirements diff --git a/doc/services/portability/posix/option_groups/index.rst b/doc/services/portability/posix/option_groups/index.rst index 08a4b3e68fcad..f8e32b125ef83 100644 --- a/doc/services/portability/posix/option_groups/index.rst +++ b/doc/services/portability/posix/option_groups/index.rst @@ -546,26 +546,24 @@ POSIX_TIMERS POSIX_FD_MGMT ============= -.. note:: - When using Newlib, Picolibc, or other C libraries conforming to the ISO C Standard, the - C89 components of the ``POSIX_FD_MGMT`` Option Group are considered supported. +This table lists service support status in Zephyr for `POSIX_FD_MGMT`: .. csv-table:: POSIX_FD_MGMT :header: API, Supported :widths: 50,10 - dup(), yes - dup2(), yes - fcntl(), yes - fgetpos(), yes - fseek(), yes - fseeko(), yes - fsetpos(), yes - ftell(), yes - ftello(), yes - ftruncate(), yes - lseek(), yes - rewind(), yes + dup(), + dup2(), + fcntl(), + fgetpos(), + fseek(), + fseeko(), + fsetpos(), + ftell(), + ftello(), + ftruncate(),yes + lseek(), + rewind(), .. _posix_option_group_file_locking: From 7c4679e68d8f290eccc34d6d1110cf332144e6e7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:06:47 +0200 Subject: [PATCH 02/18] Revert "posix: fd_mgmt: implement dup(), dup2(), fseeko(), and ftello()" This reverts commit b18cad15b9ea1b72436da4a96444012a360e5fc8. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 40 ------------------------------- lib/posix/options/Kconfig.fd_mgmt | 2 -- lib/posix/options/fd_mgmt.c | 37 ---------------------------- 3 files changed, 79 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index 52f62f69cd0e9..0c9131d7c39d0 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -424,46 +424,6 @@ int zvfs_fileno(FILE *file) return (struct fd_entry *)file - fdtable; } -int zvfs_dup(int fd, int *newfd) -{ - int ret; - - if (_check_fd(fd) < 0) { - return -1; - } - - (void)k_mutex_lock(&fdtable_lock, K_FOREVER); - - if (newfd == NULL) { - /* dup() - just find lowest-numbered fd */ - ret = _find_fd_entry(); - } else { - /* dup2() - check if newfd is valid */ - if (_check_fd(*newfd) < 0) { - ret = -1; - } else { - if (fdtable[fd].vtable->close) { - (void)fdtable[fd].vtable->close(fdtable[fd].obj); - } - ret = *newfd; - } - } - - if (ret >= 0) { - /* Mark entry as used and initialize fields */ - if (newfd == NULL) { - (void)z_fd_ref(ret); - } - fdtable[ret] = fdtable[fd]; - k_mutex_init(&fdtable[ret].lock); - k_condvar_init(&fdtable[ret].cond); - } - - k_mutex_unlock(&fdtable_lock); - - return ret; -} - int zvfs_fstat(int fd, struct stat *buf) { if (_check_fd(fd) < 0) { diff --git a/lib/posix/options/Kconfig.fd_mgmt b/lib/posix/options/Kconfig.fd_mgmt index fee6f17848f65..329036ffbf891 100644 --- a/lib/posix/options/Kconfig.fd_mgmt +++ b/lib/posix/options/Kconfig.fd_mgmt @@ -5,8 +5,6 @@ menuconfig POSIX_FD_MGMT bool "POSIX file descriptor management [EXPERIMENTAL]" select EXPERIMENTAL - select FDTABLE - select REQUIRES_FULL_LIBC help Select 'y' here and Zephyr will provide implementations for the POSIX_FD_MGMT Option Group. This includes support for dup(), dup2(), fcntl(), fseeko(), ftello(), ftruncate(), diff --git a/lib/posix/options/fd_mgmt.c b/lib/posix/options/fd_mgmt.c index 923a133cf1f5a..c1f60aca8e490 100644 --- a/lib/posix/options/fd_mgmt.c +++ b/lib/posix/options/fd_mgmt.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -15,22 +14,10 @@ #include /* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ -int zvfs_dup(int fd, int *newfd); int zvfs_fcntl(int fd, int cmd, va_list arg); -int zvfs_fileno(FILE *file); int zvfs_ftruncate(int fd, off_t length); off_t zvfs_lseek(int fd, off_t offset, int whence); -int dup(int fd) -{ - return zvfs_dup(fd, NULL); -} - -int dup2(int oldfd, int newfd) -{ - return zvfs_dup(oldfd, &newfd); -} - int fcntl(int fd, int cmd, ...) { int ret; @@ -46,30 +33,6 @@ int fcntl(int fd, int cmd, ...) FUNC_ALIAS(fcntl, _fcntl, int); #endif /* CONFIG_POSIX_FD_MGMT_ALIAS_FCNTL */ -int fseeko(FILE *file, off_t offset, int whence) -{ - int fd; - - fd = zvfs_fileno(file); - if (fd < 0) { - return -1; - } - - return zvfs_lseek(fd, offset, whence); -} - -off_t ftello(FILE *file) -{ - int fd; - - fd = zvfs_fileno(file); - if (fd < 0) { - return -1; - } - - return zvfs_lseek(fd, 0, SEEK_CUR); -} - int ftruncate(int fd, off_t length) { return zvfs_ftruncate(fd, length); From 5d87d30e3d6f74ba7ed474487b0a3effcd8544b9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:06:52 +0200 Subject: [PATCH 03/18] Revert "doc: posix: mark posix signals supported with undefined behaviour" This reverts commit b10f1ca3a6faf58db10a57f2138802b2d7157f12. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- doc/services/portability/posix/aep/index.rst | 4 +-- .../portability/posix/option_groups/index.rst | 28 +++++++------------ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/doc/services/portability/posix/aep/index.rst b/doc/services/portability/posix/aep/index.rst index b1fe34ee0d986..bfeb92853ed73 100644 --- a/doc/services/portability/posix/aep/index.rst +++ b/doc/services/portability/posix/aep/index.rst @@ -50,8 +50,8 @@ The *Minimal Realtime System Profile* (PSE51) includes all of the :ref:`POSIX_C_LANG_JUMP `, yes, :ref:`POSIX_C_LANG_SUPPORT `, yes, - :ref:`POSIX_DEVICE_IO `,yes, :kconfig:option:`CONFIG_POSIX_DEVICE_IO` - :ref:`POSIX_SIGNALS `, yes, :kconfig:option:`CONFIG_POSIX_SIGNALS` :ref:`†` + :ref:`POSIX_DEVICE_IO `, yes, :kconfig:option:`CONFIG_POSIX_DEVICE_IO` + :ref:`POSIX_SIGNALS `,, :kconfig:option:`CONFIG_POSIX_SIGNALS` :ref:`POSIX_SINGLE_PROCESS `, yes, :kconfig:option:`CONFIG_POSIX_SINGLE_PROCESS` :ref:`XSI_THREADS_EXT `, yes, :kconfig:option:`CONFIG_XSI_THREADS_EXT` diff --git a/doc/services/portability/posix/option_groups/index.rst b/doc/services/portability/posix/option_groups/index.rst index f8e32b125ef83..cb7f7e64ce497 100644 --- a/doc/services/portability/posix/option_groups/index.rst +++ b/doc/services/portability/posix/option_groups/index.rst @@ -244,34 +244,26 @@ POSIX_SIGNALS Signal services are a basic mechanism within POSIX-based systems and are required for error and event handling. -.. note:: - As processes are not yet supported in Zephyr, the ISO C functions ``abort()``, ``signal()``, - and ``raise()``, as well as the other POSIX functions listed below, may exhibit undefined - behaviour. The POSIX functions ``kill()``, ``pause()``, ``sigaction()``, ``sigpending()``, - ``sigsuspend()``, and ``sigwait()`` are implemented to ensure that conformant applications can - link, but they are expected to fail, setting errno to ``ENOSYS`` - :ref:`†`. - .. csv-table:: POSIX_SIGNALS :header: API, Supported :widths: 50,10 - abort(),yes :ref:`†` - alarm(),yes :ref:`†` - kill(),yes :ref:`†` - pause(),yes :ref:`†` - raise(),yes :ref:`†` - sigaction(),yes :ref:`†` + abort(),yes + alarm(), + kill(), + pause(), + raise(), + sigaction(), sigaddset(),yes sigdelset(),yes sigemptyset(),yes sigfillset(),yes sigismember(),yes - signal(),yes :ref:`†` - sigpending(),yes :ref:`†` + signal(), + sigpending(), sigprocmask(),yes - sigsuspend(),yes :ref:`†` - sigwait(),yes :ref:`†` + sigsuspend(), + sigwait(), strsignal(),yes .. _posix_option_group_device_io: From 45e022bea875edaed2a6b809d2c2627c0e033e2a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:06:56 +0200 Subject: [PATCH 04/18] Revert "tests: posix: headers: add checks for posix signals option group" This reverts commit 308322e9b9a1430f334e074b335186db36a783ca. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- tests/posix/headers/src/signal_h.c | 65 +++++++++++++----------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/tests/posix/headers/src/signal_h.c b/tests/posix/headers/src/signal_h.c index 76cde3e592d91..35616e4a29e54 100644 --- a/tests/posix/headers/src/signal_h.c +++ b/tests/posix/headers/src/signal_h.c @@ -6,8 +6,6 @@ #include "_common.h" -#include - #ifdef CONFIG_POSIX_API #include #else @@ -21,17 +19,13 @@ */ ZTEST(posix_headers, test_signal_h) { - typedef void *(*my_sig_handler_t)(int signo); - - my_sig_handler_t handler; - - handler = SIG_DFL; - handler = SIG_ERR; - handler = SIG_IGN; + /* zassert_not_equal(-1, SIG_DFL); */ /* not implemented */ + /* zassert_not_equal(-1, SIG_ERR); */ /* not implemented */ /* zassert_not_equal(-1, SIG_HOLD); */ /* not implemented */ + /* zassert_not_equal(-1, SIG_IGN); */ /* not implemented */ zassert_not_equal((sig_atomic_t)-1, (sig_atomic_t)0); - zassert_not_equal((pid_t)-1, (pid_t)0); + /* zassert_not_equal((pid_t)-1, (pid_t)0); */ /* not implemented */ zassert_not_equal(-1, offsetof(struct sigevent, sigev_notify)); zassert_not_equal(-1, offsetof(struct sigevent, sigev_signo)); @@ -53,15 +47,6 @@ ZTEST(posix_headers, test_signal_h) zassert_not_equal(-1, SIG_UNBLOCK); zassert_not_equal(-1, SIG_SETMASK); - zassert_not_equal(-1, offsetof(struct sigaction, sa_handler)); - zassert_not_equal(-1, offsetof(struct sigaction, sa_mask)); - zassert_not_equal(-1, offsetof(struct sigaction, sa_flags)); - zassert_not_equal(-1, offsetof(struct sigaction, sa_sigaction)); - - zassert_not_equal(-1, offsetof(siginfo_t, si_signo)); - zassert_not_equal(-1, offsetof(siginfo_t, si_code)); - zassert_not_equal(-1, offsetof(siginfo_t, si_value)); - /* zassert_not_equal(-1, SA_NOCLDSTOP); */ /* not implemented */ /* zassert_not_equal(-1, SA_ONSTACK); */ /* not implemented */ /* zassert_not_equal(-1, SA_RESETHAND); */ /* not implemented */ @@ -132,11 +117,18 @@ ZTEST(posix_headers, test_signal_h) /* zassert_not_equal(-1, CLD_STOPPED); */ /* not implemented */ /* zassert_not_equal(-1, CLD_CONTINUED); */ /* not implemented */ - zassert_not_equal(-1, SI_USER); - zassert_not_equal(-1, SI_QUEUE); - zassert_not_equal(-1, SI_TIMER); - zassert_not_equal(-1, SI_ASYNCIO); - zassert_not_equal(-1, SI_MESGQ); + /* zassert_not_equal(-1, POLL_IN); */ /* not implemented */ + /* zassert_not_equal(-1, POLL_OUT); */ /* not implemented */ + /* zassert_not_equal(-1, POLL_MSG); */ /* not implemented */ + /* zassert_not_equal(-1, POLL_ERR); */ /* not implemented */ + /* zassert_not_equal(-1, POLL_PRI); */ /* not implemented */ + /* zassert_not_equal(-1, POLL_HUP); */ /* not implemented */ + + /* zassert_not_equal(-1, SI_USER); */ /* not implemented */ + /* zassert_not_equal(-1, SI_QUEUE); */ /* not implemented */ + /* zassert_not_equal(-1, SI_TIMER); */ /* not implemented */ + /* zassert_not_equal(-1, SI_ASYNCIO); */ /* not implemented */ + /* zassert_not_equal(-1, SI_MESGQ); */ /* not implemented */ #ifdef CONFIG_POSIX_SIGNALS zassert_true(SIGRTMIN >= 0); @@ -166,40 +158,37 @@ ZTEST(posix_headers, test_signal_h) zassert_not_equal(-1, SIGXCPU); zassert_not_equal(-1, SIGXFSZ); zassert_not_equal(((sigset_t){.sig[0] = 0}).sig[0], ((sigset_t){.sig[0] = -1}).sig[0]); - zassert_not_null(abort); - zassert_not_null(alarm); - zassert_not_null(kill); - zassert_not_null(pause); - zassert_not_null(pthread_sigmask); - zassert_not_null(raise); - zassert_not_null(sigaction); - zassert_not_null(sigaddset); - zassert_not_null(sigdelset); zassert_not_null(sigemptyset); zassert_not_null(sigfillset); + zassert_not_null(sigaddset); + zassert_not_null(sigdelset); zassert_not_null(sigismember); - zassert_not_null(signal); - zassert_not_null(sigpending); - zassert_not_null(sigprocmask); - zassert_not_null(sigsuspend); - zassert_not_null(sigwait); zassert_not_null(strsignal); + zassert_not_null(sigprocmask); + zassert_not_null(pthread_sigmask); #endif /* CONFIG_POSIX_SIGNALS */ if (IS_ENABLED(CONFIG_POSIX_API)) { + /* zassert_not_null(kill); */ /* not implemented */ /* zassert_not_null(killpg); */ /* not implemented */ /* zassert_not_null(psiginfo); */ /* not implemented */ /* zassert_not_null(psignal); */ /* not implemented */ /* zassert_not_null(pthread_kill); */ /* not implemented */ + /* zassert_not_null(raise); */ /* not implemented */ + /* zassert_not_null(sigaction); */ /* not implemented */ /* zassert_not_null(sigaltstack); */ /* not implemented */ /* zassert_not_null(sighold); */ /* not implemented */ /* zassert_not_null(sigignore); */ /* not implemented */ /* zassert_not_null(siginterrupt); */ /* not implemented */ + /* zassert_not_null(signal); */ /* not implemented */ /* zassert_not_null(sigpause); */ /* not implemented */ + /* zassert_not_null(sigpending); */ /* not implemented */ /* zassert_not_null(sigqueue); */ /* not implemented */ /* zassert_not_null(sigrelse); */ /* not implemented */ /* zassert_not_null(sigset); */ /* not implemented */ + /* zassert_not_null(sigsuspend); */ /* not implemented */ /* zassert_not_null(sigtimedwait); */ /* not implemented */ + /* zassert_not_null(sigwait); */ /* not implemented */ /* zassert_not_null(sigwaitinfo); */ /* not implemented */ } } From 331695123daac1faf1fbb04f5e9416c415bc7e38 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:00 +0200 Subject: [PATCH 05/18] Revert "posix: add stubs for signal.h functions that need process support" This reverts commit b2243af32d326fe641301063dc39e45258423299. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- include/zephyr/posix/signal.h | 32 ----------------- lib/libc/Kconfig | 1 - lib/posix/options/Kconfig.signal | 7 ---- lib/posix/options/signal.c | 59 -------------------------------- 4 files changed, 99 deletions(-) diff --git a/include/zephyr/posix/signal.h b/include/zephyr/posix/signal.h index 7a1efdbd449ce..165050f2ded92 100644 --- a/include/zephyr/posix/signal.h +++ b/include/zephyr/posix/signal.h @@ -77,16 +77,6 @@ typedef struct { #define SIG_UNBLOCK 2 #endif -#define SIG_DFL ((void *)0) -#define SIG_IGN ((void *)1) -#define SIG_ERR ((void *)-1) - -#define SI_USER 1 -#define SI_QUEUE 2 -#define SI_TIMER 3 -#define SI_ASYNCIO 4 -#define SI_MESGQ 5 - typedef int sig_atomic_t; /* Atomic entity type (ANSI) */ union sigval { @@ -102,34 +92,12 @@ struct sigevent { int sigev_signo; }; -typedef struct { - int si_signo; - int si_code; - union sigval si_value; -} siginfo_t; - -struct sigaction { - void (*sa_handler)(int signno); - sigset_t sa_mask; - int sa_flags; - void (*sa_sigaction)(int signo, siginfo_t *info, void *context); -}; - -unsigned int alarm(unsigned int seconds); -int kill(pid_t pid, int sig); -int pause(void); -int raise(int signo); -int sigaction(int sig, const struct sigaction *ZRESTRICT act, struct sigaction *ZRESTRICT oact); -int sigpending(sigset_t *set); -int sigsuspend(const sigset_t *sigmask); -int sigwait(const sigset_t *ZRESTRICT set, int *ZRESTRICT signo); char *strsignal(int signum); int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set, int signo); int sigdelset(sigset_t *set, int signo); int sigismember(const sigset_t *set, int signo); -void (*signal(int signo, void (*)(int signo)))(int signo); int sigprocmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT oset); int pthread_sigmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT oset); diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 7a509fb06e594..6607f62c521f0 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -105,7 +105,6 @@ config NEWLIB_LIBC imply POSIX_FD_MGMT_ALIAS_LSEEK imply POSIX_FILE_SYSTEM_ALIAS_FSTAT imply POSIX_MULTI_PROCESS_ALIAS_GETPID - imply POSIX_SIGNALS_ALIAS_KILL help Build with newlib library. The newlib library is expected to be part of the SDK in this case. diff --git a/lib/posix/options/Kconfig.signal b/lib/posix/options/Kconfig.signal index 1e84a55de598d..4507302e3f32d 100644 --- a/lib/posix/options/Kconfig.signal +++ b/lib/posix/options/Kconfig.signal @@ -24,7 +24,6 @@ endif # POSIX_REALTIME_SIGNALS config POSIX_SIGNALS bool "POSIX signals [EXPERIMENTAL]" select EXPERIMENTAL - select POSIX_MULTI_PROCESS help Enable support for POSIX signals. @@ -37,12 +36,6 @@ config POSIX_SIGNAL_STRING_DESC Use full description for the strsignal API. Will use 256 bytes of ROM. -# These options are intended to be used for compatibility with external POSIX -# implementations such as those in Newlib or Picolibc. - -config POSIX_SIGNALS_ALIAS_KILL - bool - endif endmenu # "Signal support" diff --git a/lib/posix/options/signal.c b/lib/posix/options/signal.c index 84171fde0f07e..cb282f69bdc86 100644 --- a/lib/posix/options/signal.c +++ b/lib/posix/options/signal.c @@ -118,62 +118,3 @@ int sigprocmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT oset errno = ENOSYS; return -1; } - -/* - * The functions below are provided so that conformant POSIX applications and libraries can still - * link. - */ - -unsigned int alarm(unsigned int seconds) -{ - ARG_UNUSED(seconds); - return 0; -} - -int kill(pid_t pid, int sig) -{ - ARG_UNUSED(pid); - ARG_UNUSED(sig); - errno = ENOSYS; - return -1; -} -#ifdef CONFIG_POSIX_SIGNALS_ALIAS_KILL -FUNC_ALIAS(kill, _kill, int); -#endif /* CONFIG_POSIX_SIGNALS_ALIAS_KILL */ - -int pause(void) -{ - errno = ENOSYS; - return -1; -} - -int sigaction(int sig, const struct sigaction *ZRESTRICT act, struct sigaction *ZRESTRICT oact) -{ - ARG_UNUSED(sig); - ARG_UNUSED(act); - ARG_UNUSED(oact); - errno = ENOSYS; - return -1; -} - -int sigpending(sigset_t *set) -{ - ARG_UNUSED(set); - errno = ENOSYS; - return -1; -} - -int sigsuspend(const sigset_t *sigmask) -{ - ARG_UNUSED(sigmask); - errno = ENOSYS; - return -1; -} - -int sigwait(const sigset_t *ZRESTRICT set, int *ZRESTRICT sig) -{ - ARG_UNUSED(set); - ARG_UNUSED(sig); - errno = ENOSYS; - return -1; -} From 5f251dd6e3b608e0f12f1f834895cfa6c7b8ce4e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:06 +0200 Subject: [PATCH 06/18] Revert "posix: procN: add missing alias for getpid()" This reverts commit be086f174c9bd8c0b62d48e5ff08b2a483b2985d. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/posix/options/multi_process.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/posix/options/multi_process.c b/lib/posix/options/multi_process.c index ab697a66c0c72..221dc04ae1ad9 100644 --- a/lib/posix/options/multi_process.c +++ b/lib/posix/options/multi_process.c @@ -21,6 +21,3 @@ pid_t getpid(void) return 42; } -#ifdef CONFIG_POSIX_MULTI_PROCESS_ALIAS_GETPID -FUNC_ALIAS(getpid, _getpid, pid_t); -#endif /* CONFIG_POSIX_MULTI_PROCESS_ALIAS_GETPID */ From 0e01cdf002842f605708d78b33e96538cbec150f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:10 +0200 Subject: [PATCH 07/18] Revert "posix: kconfig: remove select y from non-user-selectable help" This reverts commit b82b5b0734c30490368e21627423f10036487343. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/posix/options/Kconfig.device_io | 10 +++++----- lib/posix/options/Kconfig.fd_mgmt | 6 +++--- lib/posix/options/Kconfig.fs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index f50165bd330ea..80447326b375e 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -27,27 +27,27 @@ if POSIX_DEVICE_IO config POSIX_DEVICE_IO_ALIAS_CLOSE bool help - When selected via Kconfig, Zephyr will provide an alias for close() as _close(). + Select 'y' here and Zephyr will provide an alias for close() as _close(). config POSIX_DEVICE_IO_ALIAS_OPEN bool help - When selected via Kconfig, Zephyr will provide an alias for open() as _open(). + Select 'y' here and Zephyr will provide an alias for open() as _open(). config POSIX_DEVICE_IO_ALIAS_READ bool help - When selected via Kconfig, Zephyr will provide an alias for read() as _read(). + Select 'y' here and Zephyr will provide an alias for read() as _read(). config POSIX_DEVICE_IO_ALIAS_WRITE bool help - When selected via Kconfig, Zephyr will provide an alias for write() as _write(). + Select 'y' here and Zephyr will provide an alias for write() as _write(). config POSIX_DEVICE_IO_STDIN_STDOUT_STDERR bool help - When selected via Kconfig, Zephyr will provide the stdin, stdout, and stderr variables. + Select 'y' here and Zephyr will provide the stdin, stdout, and stderr variables. Some libc's that implement the POSIX API may already have declared these variables. However, it should be noted that they are a part of POSIX and not a part of ISO C. diff --git a/lib/posix/options/Kconfig.fd_mgmt b/lib/posix/options/Kconfig.fd_mgmt index 329036ffbf891..ca16539560148 100644 --- a/lib/posix/options/Kconfig.fd_mgmt +++ b/lib/posix/options/Kconfig.fd_mgmt @@ -21,16 +21,16 @@ if POSIX_FD_MGMT config POSIX_FD_MGMT_ALIAS_FCNTL bool help - When selected via Kconfig, Zephyr will provide an alias for fcntl() as _fcntl(). + Select 'y' here and Zephyr will provide an alias for fcntl() as _fcntl(). config POSIX_FD_MGMT_ALIAS_FTRUNCATE bool help - When selected via Kconfig, Zephyr will provide an alias for ftruncate() as _ftruncate(). + Select 'y' here and Zephyr will provide an alias for ftruncate() as _ftruncate(). config POSIX_FD_MGMT_ALIAS_LSEEK bool help - When selected via Kconfig, Zephyr will provide an alias for lseek() as _lseek(). + Select 'y' here and Zephyr will provide an alias for lseek() as _lseek(). endif # POSIX_FD_MGMT diff --git a/lib/posix/options/Kconfig.fs b/lib/posix/options/Kconfig.fs index bc492e5dc7a03..663d706e3fb80 100644 --- a/lib/posix/options/Kconfig.fs +++ b/lib/posix/options/Kconfig.fs @@ -15,6 +15,6 @@ if POSIX_FILE_SYSTEM config POSIX_FILE_SYSTEM_ALIAS_FSTAT bool help - When selected via Kconfig, Zephyr will provide an alias for fstat() as _fstat(). + Select 'y' here and Zephyr will provide an alias for fstat() as _fstat(). endif # POSIX_FILE_SYSTEM From 27690c86936012894a7091a21bfdff8530097058 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:14 +0200 Subject: [PATCH 08/18] Revert "doc: posix: mark posix device io as complete" This reverts commit d9855da483226348a76dc4f0461fd9c9738c098d. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- doc/services/portability/posix/aep/index.rst | 2 +- .../portability/posix/option_groups/index.rst | 58 +++++++++---------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/doc/services/portability/posix/aep/index.rst b/doc/services/portability/posix/aep/index.rst index bfeb92853ed73..aeb591f2ab0a4 100644 --- a/doc/services/portability/posix/aep/index.rst +++ b/doc/services/portability/posix/aep/index.rst @@ -50,7 +50,7 @@ The *Minimal Realtime System Profile* (PSE51) includes all of the :ref:`POSIX_C_LANG_JUMP `, yes, :ref:`POSIX_C_LANG_SUPPORT `, yes, - :ref:`POSIX_DEVICE_IO `, yes, :kconfig:option:`CONFIG_POSIX_DEVICE_IO` + :ref:`POSIX_DEVICE_IO `,, :kconfig:option:`CONFIG_POSIX_DEVICE_IO` :ref:`POSIX_SIGNALS `,, :kconfig:option:`CONFIG_POSIX_SIGNALS` :ref:`POSIX_SINGLE_PROCESS `, yes, :kconfig:option:`CONFIG_POSIX_SINGLE_PROCESS` :ref:`XSI_THREADS_EXT `, yes, :kconfig:option:`CONFIG_XSI_THREADS_EXT` diff --git a/doc/services/portability/posix/option_groups/index.rst b/doc/services/portability/posix/option_groups/index.rst index cb7f7e64ce497..e67523ae3d7c5 100644 --- a/doc/services/portability/posix/option_groups/index.rst +++ b/doc/services/portability/posix/option_groups/index.rst @@ -271,10 +271,6 @@ required for error and event handling. POSIX_DEVICE_IO =============== -.. note:: - When using Newlib, Picolibc, or other C libraries conforming to the ISO C Standard, the - C89 components of the ``POSIX_DEVICE_IO`` Option Group are considered supported. - .. csv-table:: POSIX_DEVICE_IO :header: API, Supported :widths: 50,10 @@ -285,48 +281,48 @@ POSIX_DEVICE_IO FD_ZERO(),yes clearerr(),yes close(),yes - fclose(),yes - fdopen(), yes - feof(),yes - ferror(),yes - fflush(),yes - fgetc(),yes - fgets(),yes - fileno(), yes - fopen(),yes + fclose(), + fdopen(), + feof(), + ferror(), + fflush(), + fgetc(), + fgets(), + fileno(), + fopen(), fprintf(),yes fputc(),yes fputs(),yes - fread(),yes - freopen(),yes - fscanf(),yes + fread(), + freopen(), + fscanf(), fwrite(),yes - getc(),yes - getchar(),yes - gets(),yes + getc(), + getchar(), + gets(), open(),yes perror(),yes poll(),yes printf(),yes - pread(),yes - pselect(),yes + pread(), + pselect(), putc(),yes putchar(),yes puts(),yes - pwrite(),yes + pwrite(), read(),yes - scanf(),yes + scanf(), select(),yes - setbuf(),yes - setvbuf(),yes - stderr,yes - stdin,yes - stdout,yes - ungetc(),yes + setbuf(), + setvbuf(), + stderr, + stdin, + stdout, + ungetc(), vfprintf(),yes - vfscanf(),yes + vfscanf(), vprintf(),yes - vscanf(),yes + vscanf(), write(),yes .. _posix_option_group_barriers: From 0e800d98354d1e48d01d833b673e5659f02e8539 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:18 +0200 Subject: [PATCH 09/18] Revert "posix: device_io: use mode argument correctly in open()" This reverts commit 499a6339764b51f2ebde2081c33fc1936be9b8dd. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- include/zephyr/posix/fcntl.h | 9 +-- lib/posix/options/device_io.c | 23 +++----- lib/posix/options/fs.c | 75 ++++++++++++------------- tests/posix/fs/src/test_fs_dir.c | 2 +- tests/posix/fs/src/test_fs_file.c | 2 +- tests/posix/fs/src/test_fs_open_flags.c | 4 +- tests/posix/fs/src/test_fs_stat.c | 2 +- 7 files changed, 50 insertions(+), 67 deletions(-) diff --git a/include/zephyr/posix/fcntl.h b/include/zephyr/posix/fcntl.h index 9aeef0caa6fbc..9689d1ae8c3fb 100644 --- a/include/zephyr/posix/fcntl.h +++ b/include/zephyr/posix/fcntl.h @@ -8,13 +8,9 @@ #define ZEPHYR_POSIX_FCNTL_H_ #ifdef CONFIG_PICOLIBC -#define O_CREAT 0x0040 -#define O_TRUNC 0x0200 -#define O_APPEND 0x0400 +#define O_CREAT 0x0040 #else -#define O_APPEND 0x0008 -#define O_CREAT 0x0200 -#define O_TRUNC 0x0400 +#define O_CREAT 0x0200 #endif #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) @@ -23,6 +19,7 @@ #define O_WRONLY 01 #define O_RDWR 02 +#define O_APPEND 0x0400 #define O_EXCL 0x0800 #define O_NONBLOCK 0x4000 diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index 6fea22d01545d..a504545ba0346 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -17,28 +16,28 @@ int zvfs_close(int fd); FILE *zvfs_fdopen(int fd, const char *mode); int zvfs_fileno(FILE *file); -int zvfs_open(const char *name, int flags, int mode); +int zvfs_open(const char *name, int flags); ssize_t zvfs_read(int fd, void *buf, size_t sz, size_t *from_offset); ssize_t zvfs_write(int fd, const void *buf, size_t sz, size_t *from_offset); void FD_CLR(int fd, struct zvfs_fd_set *fdset) { - return ZVFS_FD_CLR(fd, fdset); + return ZVFS_FD_CLR(fd, (struct zvfs_fd_set *)fdset); } int FD_ISSET(int fd, struct zvfs_fd_set *fdset) { - return ZVFS_FD_ISSET(fd, fdset); + return ZVFS_FD_ISSET(fd, (struct zvfs_fd_set *)fdset); } void FD_SET(int fd, struct zvfs_fd_set *fdset) { - ZVFS_FD_SET(fd, fdset); + ZVFS_FD_SET(fd, (struct zvfs_fd_set *)fdset); } void FD_ZERO(fd_set *fdset) { - ZVFS_FD_ZERO(fdset); + ZVFS_FD_ZERO((struct zvfs_fd_set *)fdset); } int close(int fd) @@ -61,16 +60,8 @@ int fileno(FILE *file) int open(const char *name, int flags, ...) { - int mode = 0; - va_list args; - - if ((flags & O_CREAT) != 0) { - va_start(args, flags); - mode = va_arg(args, int); - va_end(args); - } - - return zvfs_open(name, flags, mode); + /* FIXME: necessarily need to check for O_CREAT and unpack ... if set */ + return zvfs_open(name, flags); } #ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_OPEN FUNC_ALIAS(open, _open, int); diff --git a/lib/posix/options/fs.c b/lib/posix/options/fs.c index a9d07b73293b2..a8bf1fb620fcd 100644 --- a/lib/posix/options/fs.c +++ b/lib/posix/options/fs.c @@ -59,22 +59,37 @@ static inline void posix_fs_free_obj(struct posix_fs_desc *ptr) ptr->used = false; } -int zvfs_open(const char *name, int flags, int mode) +static int posix_mode_to_zephyr(int mf) +{ + int mode = (mf & O_CREAT) ? FS_O_CREATE : 0; + + mode |= (mf & O_APPEND) ? FS_O_APPEND : 0; + + switch (mf & O_ACCMODE) { + case O_RDONLY: + mode |= FS_O_READ; + break; + case O_WRONLY: + mode |= FS_O_WRITE; + break; + case O_RDWR: + mode |= FS_O_RDWR; + break; + default: + break; + } + + return mode; +} + +int zvfs_open(const char *name, int flags) { int rc, fd; struct posix_fs_desc *ptr = NULL; - int zflags = 0; - - if ((flags & O_ACCMODE) == O_RDONLY) { - zflags |= FS_O_READ; - } else if ((flags & O_ACCMODE) == O_WRONLY) { - zflags |= FS_O_WRITE; - } else if ((flags & O_ACCMODE) == O_RDWR) { - zflags |= FS_O_RDWR; - } + int zmode = posix_mode_to_zephyr(flags); - if ((flags & O_APPEND) != 0) { - zflags |= FS_O_APPEND; + if (zmode < 0) { + return zmode; } fd = zvfs_reserve_fd(); @@ -84,44 +99,24 @@ int zvfs_open(const char *name, int flags, int mode) ptr = posix_fs_alloc_obj(false); if (ptr == NULL) { - rc = -EMFILE; - goto out_err; + zvfs_free_fd(fd); + errno = EMFILE; + return -1; } fs_file_t_init(&ptr->file); - if (flags & O_CREAT) { - flags &= ~O_CREAT; + rc = fs_open(&ptr->file, name, zmode); - rc = fs_open(&ptr->file, name, FS_O_CREATE | (mode & O_ACCMODE)); - if (rc < 0) { - goto out_err; - } - rc = fs_close(&ptr->file); - if (rc < 0) { - goto out_err; - } - } - - rc = fs_open(&ptr->file, name, zflags); if (rc < 0) { - goto out_err; - } - - zvfs_finalize_fd(fd, ptr, &fs_fd_op_vtable); - - goto out; - -out_err: - if (ptr != NULL) { posix_fs_free_obj(ptr); + zvfs_free_fd(fd); + errno = -rc; + return -1; } - zvfs_free_fd(fd); - errno = -rc; - return -1; + zvfs_finalize_fd(fd, ptr, &fs_fd_op_vtable); -out: return fd; } diff --git a/tests/posix/fs/src/test_fs_dir.c b/tests/posix/fs/src/test_fs_dir.c index dd3a89c6dc577..b0908cb1586cb 100644 --- a/tests/posix/fs/src/test_fs_dir.c +++ b/tests/posix/fs/src/test_fs_dir.c @@ -27,7 +27,7 @@ static int test_mkdir(void) return res; } - res = open(TEST_DIR_FILE, O_CREAT | O_RDWR, 0770); + res = open(TEST_DIR_FILE, O_CREAT | O_RDWR); if (res < 0) { TC_PRINT("Failed opening file [%d]\n", res); diff --git a/tests/posix/fs/src/test_fs_file.c b/tests/posix/fs/src/test_fs_file.c index c6f2edd66895c..9614412a07a58 100644 --- a/tests/posix/fs/src/test_fs_file.c +++ b/tests/posix/fs/src/test_fs_file.c @@ -16,7 +16,7 @@ static int test_file_open(void) { int res; - res = open(TEST_FILE, O_CREAT | O_RDWR, 0660); + res = open(TEST_FILE, O_CREAT | O_RDWR); if (res < 0) { TC_ERROR("Failed opening file: %d, errno=%d\n", res, errno); /* FIXME: restructure tests as per #46897 */ diff --git a/tests/posix/fs/src/test_fs_open_flags.c b/tests/posix/fs/src/test_fs_open_flags.c index 7c35145343b75..1187b1c3e5757 100644 --- a/tests/posix/fs/src/test_fs_open_flags.c +++ b/tests/posix/fs/src/test_fs_open_flags.c @@ -60,7 +60,7 @@ static int test_file_open_flags(void) /* 2 Create file for read only, attempt to read, attempt to write */ TC_PRINT("Open on non-existent file, flags = O_CREAT | O_WRONLY\n"); - fd = open(THE_FILE, O_CREAT | O_WRONLY, 0440); + fd = open(THE_FILE, O_CREAT | O_WRONLY); if (fd < 0) { TC_PRINT("Expected success; fd = %d, errno = %d\n", fd, errno); return TC_FAIL; @@ -236,7 +236,7 @@ static int test_file_open_flags(void) TC_PRINT("Attempt write to file opened with O_APPEND | O_RDWR\n"); /* Clean start */ unlink(THE_FILE); - fd = open(THE_FILE, O_CREAT | O_WRONLY, 0440); + fd = open(THE_FILE, O_CREAT | O_WRONLY); if (fd < 0) { TC_PRINT("Expected success, fd = %d, errno = %d\n", fd, errno); return TC_FAIL; diff --git a/tests/posix/fs/src/test_fs_stat.c b/tests/posix/fs/src/test_fs_stat.c index 0031596dcef15..14167d3f7756c 100644 --- a/tests/posix/fs/src/test_fs_stat.c +++ b/tests/posix/fs/src/test_fs_stat.c @@ -21,7 +21,7 @@ static void create_file(const char *filename, uint32_t size) { int fh; - fh = open(filename, O_CREAT | O_WRONLY, 0440); + fh = open(filename, O_CREAT | O_WRONLY); zassert(fh >= 0, "Failed creating test file"); uint8_t filling[FILL_SIZE]; From 7edf2377cacf6932d943190bd76ec5e28420158c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:21 +0200 Subject: [PATCH 10/18] Revert "posix: device_io: implement fileno()" This reverts commit 48dff5562cc62e2bdeb048ed777321cc8a42df2d. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 10 ---------- lib/posix/options/device_io.c | 6 ------ 2 files changed, 16 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index 0c9131d7c39d0..acf1cf75a92b9 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -414,16 +414,6 @@ FILE *zvfs_fdopen(int fd, const char *mode) return (FILE *)&fdtable[fd]; } -int zvfs_fileno(FILE *file) -{ - if (!IS_ARRAY_ELEMENT(fdtable, file)) { - errno = EBADF; - return -1; - } - - return (struct fd_entry *)file - fdtable; -} - int zvfs_fstat(int fd, struct stat *buf) { if (_check_fd(fd) < 0) { diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index a504545ba0346..0de6293ca8469 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -15,7 +15,6 @@ /* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ int zvfs_close(int fd); FILE *zvfs_fdopen(int fd, const char *mode); -int zvfs_fileno(FILE *file); int zvfs_open(const char *name, int flags); ssize_t zvfs_read(int fd, void *buf, size_t sz, size_t *from_offset); ssize_t zvfs_write(int fd, const void *buf, size_t sz, size_t *from_offset); @@ -53,11 +52,6 @@ FILE *fdopen(int fd, const char *mode) return zvfs_fdopen(fd, mode); } -int fileno(FILE *file) -{ - return zvfs_fileno(file); -} - int open(const char *name, int flags, ...) { /* FIXME: necessarily need to check for O_CREAT and unpack ... if set */ From 40d287144edd54088c269ed4f2f3d53f2581bf94 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:24 +0200 Subject: [PATCH 11/18] Revert "posix: device_io: implement fdopen()" This reverts commit 581a0f56e6f0b3d41b5eee5c165c657b3e95c4d2. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 11 ----------- lib/posix/options/device_io.c | 7 ------- 2 files changed, 18 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index acf1cf75a92b9..6edf98066e19c 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -403,17 +403,6 @@ int zvfs_close(int fd) return res; } -FILE *zvfs_fdopen(int fd, const char *mode) -{ - ARG_UNUSED(mode); - - if (_check_fd(fd) < 0) { - return NULL; - } - - return (FILE *)&fdtable[fd]; -} - int zvfs_fstat(int fd, struct stat *buf) { if (_check_fd(fd) < 0) { diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index 0de6293ca8469..d15b5da2a91ac 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -5,7 +5,6 @@ */ #include -#include #include #include @@ -14,7 +13,6 @@ /* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ int zvfs_close(int fd); -FILE *zvfs_fdopen(int fd, const char *mode); int zvfs_open(const char *name, int flags); ssize_t zvfs_read(int fd, void *buf, size_t sz, size_t *from_offset); ssize_t zvfs_write(int fd, const void *buf, size_t sz, size_t *from_offset); @@ -47,11 +45,6 @@ int close(int fd) FUNC_ALIAS(close, _close, int); #endif -FILE *fdopen(int fd, const char *mode) -{ - return zvfs_fdopen(fd, mode); -} - int open(const char *name, int flags, ...) { /* FIXME: necessarily need to check for O_CREAT and unpack ... if set */ From 75b4255c246ee76e77f372fcbae0d23f315be051 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:30 +0200 Subject: [PATCH 12/18] Revert "posix: device_io: implement pselect()" This reverts commit 305ec62a6b1fc2aee8ecb1a8c34f09492114ba28. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- 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, 10 insertions(+), 28 deletions(-) diff --git a/include/zephyr/net/socket_select.h b/include/zephyr/net/socket_select.h index 3eaa9aacfcfe8..877bd863a6b82 100644 --- a/include/zephyr/net/socket_select.h +++ b/include/zephyr/net/socket_select.h @@ -51,12 +51,9 @@ 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 timespec to = { - .tv_sec = (timeout == NULL) ? 0 : timeout->tv_sec, - .tv_nsec = (long)((timeout == NULL) ? 0 : timeout->tv_usec * NSEC_PER_USEC)}; + struct timeval; - return zvfs_select(nfds, (struct zvfs_fd_set *)readfds, (struct zvfs_fd_set *)writefds, - (struct zvfs_fd_set *)exceptfds, (timeout == NULL) ? NULL : &to, NULL); + return zvfs_select(nfds, readfds, writefds, exceptfds, (struct timeval *)timeout); } /** 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 78d900f5316b2..e10eeb237ee0d 100644 --- a/include/zephyr/posix/sys/select.h +++ b/include/zephyr/posix/sys/select.h @@ -20,8 +20,6 @@ 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 37b25d57c75eb..f9f48d9b55b71 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 timespec *ZRESTRICT timeout, const void *ZRESTRICT sigmask); + const struct timeval *ZRESTRICT timeout); /** * Request codes for fd_op_vtable.ioctl(). diff --git a/lib/os/zvfs/zvfs_select.c b/lib/os/zvfs/zvfs_select.c index 2788e3c9318ff..36a8457db0fc8 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 timespec *ZRESTRICT timeout, const void *ZRESTRICT sigmask) + const struct timeval *ZRESTRICT timeout) { struct zvfs_pollfd pfds[CONFIG_ZVFS_POLL_MAX]; k_timeout_t poll_timeout; @@ -142,8 +142,7 @@ 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_nsec / NSEC_PER_USEC); + poll_timeout = K_USEC(timeout->tv_sec * USEC_PER_SEC + timeout->tv_usec); } res = zvfs_poll_internal(pfds, num_pfds, poll_timeout); @@ -221,11 +220,10 @@ 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 timespec *ZRESTRICT timeout, - const void *ZRESTRICT sigmask) + const struct timeval *ZRESTRICT timeout) { struct zvfs_fd_set *readfds_copy = NULL, *writefds_copy = NULL, *exceptfds_copy = NULL; - struct timespec *to = NULL; + struct timeval *to = NULL; int ret = -1; if (readfds) { @@ -263,7 +261,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, sigmask); + ret = z_impl_zvfs_select(nfds, readfds_copy, writefds_copy, exceptfds_copy, to); if (ret >= 0) { if (readfds_copy) { diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index d15b5da2a91ac..eaae1c69c79e1 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -71,12 +71,6 @@ 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; @@ -99,12 +93,7 @@ FUNC_ALIAS(read, _read, ssize_t); int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *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); + return zvfs_select(nfds, readfds, writefds, exceptfds, timeout); } 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 ad1014c5b446d..49fd4dc8ed5f8 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); + /* zassert_not_null(pselect); */ /* not implemented */ zassert_not_null(select); } } From 8e85ac8c4f65926195af6ab37d9d433c65d6933a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:07:33 +0200 Subject: [PATCH 13/18] Revert "net: sockets: move select() implementation to zvfs" This reverts commit 49ac1912b29d858af6059901c2eb291e17e34a49. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- include/zephyr/net/socket_select.h | 42 +++---- include/zephyr/posix/sys/select.h | 14 +-- include/zephyr/sys/fdtable.h | 19 +-- lib/os/zvfs/CMakeLists.txt | 1 - lib/os/zvfs/Kconfig | 5 - lib/posix/options/Kconfig.device_io | 1 - lib/posix/options/device_io.c | 24 +--- subsys/net/lib/sockets/CMakeLists.txt | 2 + subsys/net/lib/sockets/Kconfig | 1 - .../net/lib/sockets/sockets_select.c | 108 +++++++++--------- tests/posix/headers/prj.conf | 1 - tests/posix/headers/src/sys_select_h.c | 10 +- 12 files changed, 82 insertions(+), 146 deletions(-) rename lib/os/zvfs/zvfs_select.c => subsys/net/lib/sockets/sockets_select.c (60%) diff --git a/include/zephyr/net/socket_select.h b/include/zephyr/net/socket_select.h index 877bd863a6b82..5fca2950d6a59 100644 --- a/include/zephyr/net/socket_select.h +++ b/include/zephyr/net/socket_select.h @@ -19,18 +19,17 @@ * @{ */ -#include - #include #include -#include #ifdef __cplusplus extern "C" { #endif /** Socket file descriptor set. */ -typedef struct zvfs_fd_set zsock_fd_set; +typedef struct zsock_fd_set { + uint32_t bitset[(CONFIG_ZVFS_OPEN_MAX + 31) / 32]; +} zsock_fd_set; /** * @brief Legacy function to poll multiple sockets for events @@ -48,16 +47,13 @@ typedef struct zvfs_fd_set zsock_fd_set; * it may conflict with generic POSIX ``select()`` function). * @endrst */ -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; - - return zvfs_select(nfds, readfds, writefds, exceptfds, (struct timeval *)timeout); -} +__syscall int zsock_select(int nfds, zsock_fd_set *readfds, + zsock_fd_set *writefds, + zsock_fd_set *exceptfds, + struct zsock_timeval *timeout); /** Number of file descriptors which can be added to zsock_fd_set */ -#define ZSOCK_FD_SETSIZE ZVFS_FD_SETSIZE +#define ZSOCK_FD_SETSIZE (sizeof(((zsock_fd_set *)0)->bitset) * 8) /** * @brief Initialize (clear) fd_set @@ -71,10 +67,7 @@ static inline int zsock_select(int nfds, zsock_fd_set *readfds, zsock_fd_set *wr * if :kconfig:option:`CONFIG_POSIX_API` is defined. * @endrst */ -static inline void ZSOCK_FD_ZERO(zsock_fd_set *set) -{ - ZVFS_FD_ZERO(set); -} +void ZSOCK_FD_ZERO(zsock_fd_set *set); /** * @brief Check whether socket is a member of fd_set @@ -88,10 +81,7 @@ static inline void ZSOCK_FD_ZERO(zsock_fd_set *set) * if :kconfig:option:`CONFIG_POSIX_API` is defined. * @endrst */ -static inline int ZSOCK_FD_ISSET(int fd, zsock_fd_set *set) -{ - return ZVFS_FD_ISSET(fd, set); -} +int ZSOCK_FD_ISSET(int fd, zsock_fd_set *set); /** * @brief Remove socket from fd_set @@ -105,10 +95,7 @@ static inline int ZSOCK_FD_ISSET(int fd, zsock_fd_set *set) * if :kconfig:option:`CONFIG_POSIX_API` is defined. * @endrst */ -static inline void ZSOCK_FD_CLR(int fd, zsock_fd_set *set) -{ - ZVFS_FD_CLR(fd, set); -} +void ZSOCK_FD_CLR(int fd, zsock_fd_set *set); /** * @brief Add socket to fd_set @@ -122,10 +109,7 @@ static inline void ZSOCK_FD_CLR(int fd, zsock_fd_set *set) * if :kconfig:option:`CONFIG_POSIX_API` is defined. * @endrst */ -static inline void ZSOCK_FD_SET(int fd, zsock_fd_set *set) -{ - ZVFS_FD_SET(fd, set); -} +void ZSOCK_FD_SET(int fd, zsock_fd_set *set); /** @cond INTERNAL_HIDDEN */ @@ -169,6 +153,8 @@ static inline void FD_SET(int fd, zsock_fd_set *set) } #endif +#include + /** * @} */ diff --git a/include/zephyr/posix/sys/select.h b/include/zephyr/posix/sys/select.h index e10eeb237ee0d..fc61c018e249f 100644 --- a/include/zephyr/posix/sys/select.h +++ b/include/zephyr/posix/sys/select.h @@ -13,18 +13,16 @@ extern "C" { #endif -#undef fd_set #define fd_set zsock_fd_set - -#define FD_SETSIZE ZVFS_FD_SETSIZE +#define FD_SETSIZE ZSOCK_FD_SETSIZE +#define FD_ZERO ZSOCK_FD_ZERO +#define FD_SET ZSOCK_FD_SET +#define FD_CLR ZSOCK_FD_CLR +#define FD_ISSET ZSOCK_FD_ISSET struct timeval; -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); -void FD_SET(int fd, fd_set *fdset); -void FD_ZERO(fd_set *fdset); +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); #ifdef __cplusplus } diff --git a/include/zephyr/sys/fdtable.h b/include/zephyr/sys/fdtable.h index f9f48d9b55b71..c2a6705ca9518 100644 --- a/include/zephyr/sys/fdtable.h +++ b/include/zephyr/sys/fdtable.h @@ -8,7 +8,6 @@ #include #include - /* FIXME: For native_posix ssize_t, off_t. */ #include #include @@ -208,23 +207,9 @@ struct zvfs_pollfd { __syscall int zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout); -struct zvfs_fd_set { +struct zsock_fd_set { uint32_t bitset[(CONFIG_ZVFS_OPEN_MAX + 31) / 32]; }; - -#define ZVFS_FD_SETSIZE (sizeof(((struct zvfs_fd_set *)0)->bitset) * 8) - -void ZVFS_FD_CLR(int fd, struct zvfs_fd_set *fdset); -int ZVFS_FD_ISSET(int fd, struct zvfs_fd_set *fdset); -void ZVFS_FD_SET(int fd, struct zvfs_fd_set *fdset); -void ZVFS_FD_ZERO(struct zvfs_fd_set *fdset); - -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); - /** * Request codes for fd_op_vtable.ioctl(). * @@ -254,6 +239,4 @@ enum { } #endif -#include - #endif /* ZEPHYR_INCLUDE_SYS_FDTABLE_H_ */ diff --git a/lib/os/zvfs/CMakeLists.txt b/lib/os/zvfs/CMakeLists.txt index d855d1005efc6..ef0dde4513bed 100644 --- a/lib/os/zvfs/CMakeLists.txt +++ b/lib/os/zvfs/CMakeLists.txt @@ -3,4 +3,3 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_ZVFS_EVENTFD zvfs_eventfd.c) zephyr_library_sources_ifdef(CONFIG_ZVFS_POLL zvfs_poll.c) -zephyr_library_sources_ifdef(CONFIG_ZVFS_SELECT zvfs_select.c) diff --git a/lib/os/zvfs/Kconfig b/lib/os/zvfs/Kconfig index df107c24c626d..40cba2cd9c9f4 100644 --- a/lib/os/zvfs/Kconfig +++ b/lib/os/zvfs/Kconfig @@ -49,11 +49,6 @@ config ZVFS_POLL_MAX help Maximum number of entries supported for poll() call. -config ZVFS_SELECT - bool "ZVFS select" - help - Enable support for zvfs_select(). - endif # ZVFS_POLL endif # ZVFS diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index 80447326b375e..9a4bbd60f4591 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -10,7 +10,6 @@ config POSIX_DEVICE_IO select REQUIRES_FULL_LIBC select ZVFS select ZVFS_POLL - select ZVFS_SELECT help Select 'y' here and Zephyr will provide an implementation of the POSIX_DEVICE_IO Option Group such as FD_CLR(), FD_ISSET(), FD_SET(), FD_ZERO(), close(), fdopen(), fileno(), open(), diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index eaae1c69c79e1..7b638c84976e7 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -10,6 +10,7 @@ #include #include #include +#include /* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ int zvfs_close(int fd); @@ -17,26 +18,6 @@ int zvfs_open(const char *name, int flags); ssize_t zvfs_read(int fd, void *buf, size_t sz, size_t *from_offset); ssize_t zvfs_write(int fd, const void *buf, size_t sz, size_t *from_offset); -void FD_CLR(int fd, struct zvfs_fd_set *fdset) -{ - return ZVFS_FD_CLR(fd, (struct zvfs_fd_set *)fdset); -} - -int FD_ISSET(int fd, struct zvfs_fd_set *fdset) -{ - return ZVFS_FD_ISSET(fd, (struct zvfs_fd_set *)fdset); -} - -void FD_SET(int fd, struct zvfs_fd_set *fdset) -{ - ZVFS_FD_SET(fd, (struct zvfs_fd_set *)fdset); -} - -void FD_ZERO(fd_set *fdset) -{ - ZVFS_FD_ZERO((struct zvfs_fd_set *)fdset); -} - int close(int fd) { return zvfs_close(fd); @@ -93,7 +74,8 @@ 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); + /* TODO: create zvfs_select() and dispatch to subsystems based on file type */ + return zsock_select(nfds, readfds, writefds, exceptfds, (struct zsock_timeval *)timeout); } ssize_t write(int fd, const void *buf, size_t sz) diff --git a/subsys/net/lib/sockets/CMakeLists.txt b/subsys/net/lib/sockets/CMakeLists.txt index 8e8b156260222..253cb4a182f8c 100644 --- a/subsys/net/lib/sockets/CMakeLists.txt +++ b/subsys/net/lib/sockets/CMakeLists.txt @@ -2,6 +2,7 @@ zephyr_syscall_header( ${ZEPHYR_BASE}/include/zephyr/net/socket.h + ${ZEPHYR_BASE}/include/zephyr/net/socket_select.h ) zephyr_library_include_directories(.) @@ -9,6 +10,7 @@ zephyr_library_include_directories(.) zephyr_library_sources( getaddrinfo.c sockets.c + sockets_select.c ) if(NOT CONFIG_NET_SOCKETS_OFFLOAD) diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index 43331d7141390..b767a05cba5ed 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -7,7 +7,6 @@ menuconfig NET_SOCKETS bool "BSD Sockets compatible API" select ZVFS select ZVFS_POLL - select ZVFS_SELECT help Provide BSD Sockets like API on top of native Zephyr networking API. diff --git a/lib/os/zvfs/zvfs_select.c b/subsys/net/lib/sockets/sockets_select.c similarity index 60% rename from lib/os/zvfs/zvfs_select.c rename to subsys/net/lib/sockets/sockets_select.c index 36a8457db0fc8..49d61a2d28c65 100644 --- a/lib/os/zvfs/zvfs_select.c +++ b/subsys/net/lib/sockets/sockets_select.c @@ -4,12 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - #include #include #include #include +#include "sockets_internal.h" /* Get size, in elements, of an array within a struct. */ #define STRUCT_MEMBER_ARRAY_SIZE(type, field) ARRAY_SIZE(((type *)0)->field) @@ -21,12 +20,7 @@ bit_mask = 1 << b_idx; \ } -/** Number of file descriptors which can be added to zsock_fd_set */ -#define ZVFS_FD_SETSIZE (sizeof(((struct zvfs_fd_set *)0)->bitset) * 8) - -int zvfs_poll_internal(struct zvfs_pollfd *fds, int nfds, k_timeout_t timeout); - -void ZVFS_FD_ZERO(struct zvfs_fd_set *set) +void ZSOCK_FD_ZERO(zsock_fd_set *set) { int i; @@ -35,11 +29,11 @@ void ZVFS_FD_ZERO(struct zvfs_fd_set *set) } } -int ZVFS_FD_ISSET(int fd, struct zvfs_fd_set *set) +int ZSOCK_FD_ISSET(int fd, zsock_fd_set *set) { uint32_t word_idx, bit_mask; - if (fd < 0 || fd >= ZVFS_FD_SETSIZE) { + if (fd < 0 || fd >= ZSOCK_FD_SETSIZE) { return 0; } @@ -48,11 +42,11 @@ int ZVFS_FD_ISSET(int fd, struct zvfs_fd_set *set) return (set->bitset[word_idx] & bit_mask) != 0U; } -void ZVFS_FD_CLR(int fd, struct zvfs_fd_set *set) +void ZSOCK_FD_CLR(int fd, zsock_fd_set *set) { uint32_t word_idx, bit_mask; - if (fd < 0 || fd >= ZVFS_FD_SETSIZE) { + if (fd < 0 || fd >= ZSOCK_FD_SETSIZE) { return; } @@ -61,11 +55,11 @@ void ZVFS_FD_CLR(int fd, struct zvfs_fd_set *set) set->bitset[word_idx] &= ~bit_mask; } -void ZVFS_FD_SET(int fd, struct zvfs_fd_set *set) +void ZSOCK_FD_SET(int fd, zsock_fd_set *set) { uint32_t word_idx, bit_mask; - if (fd < 0 || fd >= ZVFS_FD_SETSIZE) { + if (fd < 0 || fd >= ZSOCK_FD_SETSIZE) { return; } @@ -74,19 +68,17 @@ void ZVFS_FD_SET(int fd, struct zvfs_fd_set *set) set->bitset[word_idx] |= bit_mask; } -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) +int z_impl_zsock_select(int nfds, zsock_fd_set *readfds, zsock_fd_set *writefds, + zsock_fd_set *exceptfds, struct zsock_timeval *timeout) { - struct zvfs_pollfd pfds[CONFIG_ZVFS_POLL_MAX]; + struct zsock_pollfd pfds[CONFIG_NET_SOCKETS_POLL_MAX]; k_timeout_t poll_timeout; int i, res; int num_pfds = 0; int num_selects = 0; int fd_no = 0; - for (i = 0; i < STRUCT_MEMBER_ARRAY_SIZE(struct zvfs_fd_set, bitset); i++) { + for (i = 0; i < STRUCT_MEMBER_ARRAY_SIZE(zsock_fd_set, bitset); i++) { uint32_t bit_mask = 1U; uint32_t read_mask = 0U, write_mask = 0U, except_mask = 0U; uint32_t ored_mask; @@ -119,15 +111,15 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } if (read_mask & bit_mask) { - events |= ZVFS_POLLIN; + events |= ZSOCK_POLLIN; } if (write_mask & bit_mask) { - events |= ZVFS_POLLOUT; + events |= ZSOCK_POLLOUT; } if (except_mask & bit_mask) { - events |= ZVFS_POLLPRI; + events |= ZSOCK_POLLPRI; } pfds[num_pfds].fd = fd_no; @@ -142,24 +134,25 @@ 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 * 1000000UL + timeout->tv_usec); } - res = zvfs_poll_internal(pfds, num_pfds, poll_timeout); + res = zsock_poll_internal(pfds, num_pfds, poll_timeout); if (res == -1) { return -1; } if (readfds != NULL) { - ZVFS_FD_ZERO(readfds); + ZSOCK_FD_ZERO(readfds); } if (writefds != NULL) { - ZVFS_FD_ZERO(writefds); + ZSOCK_FD_ZERO(writefds); } if (exceptfds != NULL) { - ZVFS_FD_ZERO(exceptfds); + ZSOCK_FD_ZERO(exceptfds); } for (i = 0; i < num_pfds && res > 0; i++) { @@ -176,21 +169,21 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, * So, unlike poll(), a single invalid fd aborts the entire * select(). */ - if (revents & ZVFS_POLLNVAL) { + if (revents & ZSOCK_POLLNVAL) { errno = EBADF; return -1; } - if (revents & ZVFS_POLLIN) { + if (revents & ZSOCK_POLLIN) { if (readfds != NULL) { - ZVFS_FD_SET(fd, readfds); + ZSOCK_FD_SET(fd, readfds); num_selects++; } } - if (revents & ZVFS_POLLOUT) { + if (revents & ZSOCK_POLLOUT) { if (writefds != NULL) { - ZVFS_FD_SET(fd, writefds); + ZSOCK_FD_SET(fd, writefds); num_selects++; } } @@ -198,14 +191,14 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, /* It's unclear if HUP/ERR belong here. At least not ignore * them. Zephyr doesn't use HUP and barely use ERR so far. */ - if (revents & (ZVFS_POLLPRI | ZVFS_POLLHUP | ZVFS_POLLERR)) { + if (revents & (ZSOCK_POLLPRI | ZSOCK_POLLHUP | ZSOCK_POLLERR)) { if (exceptfds != NULL) { - ZVFS_FD_SET(fd, exceptfds); + ZSOCK_FD_SET(fd, exceptfds); num_selects++; } if (writefds != NULL) { - ZVFS_FD_SET(fd, writefds); + ZSOCK_FD_SET(fd, writefds); num_selects++; } } @@ -217,18 +210,19 @@ int z_impl_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } #ifdef CONFIG_USERSPACE -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) +static int z_vrfy_zsock_select(int nfds, zsock_fd_set *readfds, + zsock_fd_set *writefds, + zsock_fd_set *exceptfds, + struct zsock_timeval *timeout) { - struct zvfs_fd_set *readfds_copy = NULL, *writefds_copy = NULL, *exceptfds_copy = NULL; - struct timeval *to = NULL; + zsock_fd_set *readfds_copy = NULL, *writefds_copy = NULL, + *exceptfds_copy = NULL; + struct zsock_timeval *timeval = NULL; int ret = -1; if (readfds) { - readfds_copy = - k_usermode_alloc_from_copy((void *)readfds, sizeof(struct zvfs_fd_set)); + readfds_copy = k_usermode_alloc_from_copy((void *)readfds, + sizeof(zsock_fd_set)); if (!readfds_copy) { errno = ENOMEM; goto out; @@ -236,8 +230,8 @@ static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } if (writefds) { - writefds_copy = - k_usermode_alloc_from_copy((void *)writefds, sizeof(struct zvfs_fd_set)); + writefds_copy = k_usermode_alloc_from_copy((void *)writefds, + sizeof(zsock_fd_set)); if (!writefds_copy) { errno = ENOMEM; goto out; @@ -245,8 +239,8 @@ static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } if (exceptfds) { - exceptfds_copy = - k_usermode_alloc_from_copy((void *)exceptfds, sizeof(struct zvfs_fd_set)); + exceptfds_copy = k_usermode_alloc_from_copy((void *)exceptfds, + sizeof(zsock_fd_set)); if (!exceptfds_copy) { errno = ENOMEM; goto out; @@ -254,39 +248,41 @@ static int z_vrfy_zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds, } if (timeout) { - to = k_usermode_alloc_from_copy((void *)timeout, sizeof(*to)); - if (!to) { + timeval = k_usermode_alloc_from_copy((void *)timeout, + sizeof(struct zsock_timeval)); + if (!timeval) { errno = ENOMEM; goto out; } } - ret = z_impl_zvfs_select(nfds, readfds_copy, writefds_copy, exceptfds_copy, to); + ret = z_impl_zsock_select(nfds, readfds_copy, writefds_copy, + exceptfds_copy, timeval); if (ret >= 0) { if (readfds_copy) { k_usermode_to_copy((void *)readfds, readfds_copy, - sizeof(struct zvfs_fd_set)); + sizeof(zsock_fd_set)); } if (writefds_copy) { k_usermode_to_copy((void *)writefds, writefds_copy, - sizeof(struct zvfs_fd_set)); + sizeof(zsock_fd_set)); } if (exceptfds_copy) { k_usermode_to_copy((void *)exceptfds, exceptfds_copy, - sizeof(struct zvfs_fd_set)); + sizeof(zsock_fd_set)); } } out: - k_free(to); + k_free(timeval); k_free(readfds_copy); k_free(writefds_copy); k_free(exceptfds_copy); return ret; } -#include +#include #endif diff --git a/tests/posix/headers/prj.conf b/tests/posix/headers/prj.conf index e5c34983aeaf2..374baf4cbdfa6 100644 --- a/tests/posix/headers/prj.conf +++ b/tests/posix/headers/prj.conf @@ -22,4 +22,3 @@ CONFIG_POSIX_TIMERS=y CONFIG_POSIX_MESSAGE_PASSING=y CONFIG_EVENTFD=y CONFIG_POSIX_C_LIB_EXT=y -CONFIG_POSIX_DEVICE_IO=y diff --git a/tests/posix/headers/src/sys_select_h.c b/tests/posix/headers/src/sys_select_h.c index 49fd4dc8ed5f8..5cca45419712d 100644 --- a/tests/posix/headers/src/sys_select_h.c +++ b/tests/posix/headers/src/sys_select_h.c @@ -22,14 +22,12 @@ ZTEST(posix_headers, test_sys_select_h) fd_set fds = {0}; zassert_not_equal(-1, FD_SETSIZE); + FD_CLR(0, &fds); + FD_ISSET(0, &fds); + FD_SET(0, &fds); + FD_ZERO(&fds); if (IS_ENABLED(CONFIG_POSIX_DEVICE_IO)) { - - FD_CLR(0, &fds); - FD_ISSET(0, &fds); - FD_SET(0, &fds); - FD_ZERO(&fds); - /* zassert_not_null(pselect); */ /* not implemented */ zassert_not_null(select); } From d5023a6c95c62979a122e0aa18a9f96a89d98b8b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:10:33 +0200 Subject: [PATCH 14/18] Revert "net: sockets: move poll implementation to zvfs" This reverts commit 93973e2ead9bc1e8e1bcf05d46cc292a05b49fdd. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- include/zephyr/net/socket.h | 5 +- include/zephyr/net/socket_poll.h | 8 +- include/zephyr/sys/fdtable.h | 18 -- lib/os/CMakeLists.txt | 3 - lib/os/zvfs/CMakeLists.txt | 1 - lib/os/zvfs/Kconfig | 20 +- lib/os/zvfs/zvfs_poll.c | 212 ------------------ lib/posix/options/Kconfig.device_io | 3 +- lib/posix/options/device_io.c | 3 +- subsys/net/lib/sockets/Kconfig | 7 +- subsys/net/lib/sockets/sockets.c | 218 +++++++++++++++++++ subsys/tracing/ctf/tracing_ctf.h | 6 +- tests/net/lib/coap_client/src/stubs.c | 4 +- tests/net/lib/lwm2m/lwm2m_engine/prj.conf | 2 - tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c | 4 +- 15 files changed, 239 insertions(+), 275 deletions(-) delete mode 100644 lib/os/zvfs/zvfs_poll.c diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index a1df517d0f2eb..9af729faecd85 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -625,10 +625,7 @@ static inline int zsock_ioctl_wrapper(int sock, unsigned long request, ...) * it may conflict with generic POSIX ``poll()`` function). * @endrst */ -static inline int zsock_poll(struct zsock_pollfd *fds, int nfds, int timeout) -{ - return zvfs_poll(fds, nfds, timeout); -} +__syscall int zsock_poll(struct zsock_pollfd *fds, int nfds, int timeout); /** * @brief Get various socket options diff --git a/include/zephyr/net/socket_poll.h b/include/zephyr/net/socket_poll.h index 934ca3ce6f162..97e03804311ab 100644 --- a/include/zephyr/net/socket_poll.h +++ b/include/zephyr/net/socket_poll.h @@ -7,8 +7,6 @@ #ifndef ZEPHYR_INCLUDE_NET_SOCKET_POLL_H_ #define ZEPHYR_INCLUDE_NET_SOCKET_POLL_H_ -#include - /* Setting for pollfd to avoid circular inclusion */ /** @@ -27,7 +25,11 @@ extern "C" { * * An array of these descriptors is passed as an argument to poll(). */ -#define zsock_pollfd zvfs_pollfd +struct zsock_pollfd { + int fd; /**< Socket descriptor */ + short events; /**< Requested events */ + short revents; /**< Returned events */ +}; #ifdef __cplusplus } diff --git a/include/zephyr/sys/fdtable.h b/include/zephyr/sys/fdtable.h index c2a6705ca9518..785df8d42e0fc 100644 --- a/include/zephyr/sys/fdtable.h +++ b/include/zephyr/sys/fdtable.h @@ -27,13 +27,6 @@ #define ZVFS_MODE_IFLNK 0120000 #define ZVFS_MODE_IFSOCK 0140000 -#define ZVFS_POLLIN BIT(0) -#define ZVFS_POLLPRI BIT(1) -#define ZVFS_POLLOUT BIT(2) -#define ZVFS_POLLERR BIT(3) -#define ZVFS_POLLHUP BIT(4) -#define ZVFS_POLLNVAL BIT(5) - #ifdef __cplusplus extern "C" { #endif @@ -199,17 +192,6 @@ static inline int zvfs_fdtable_call_ioctl(const struct fd_op_vtable *vtable, voi return res; } -struct zvfs_pollfd { - int fd; - short events; - short revents; -}; - -__syscall int zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout); - -struct zsock_fd_set { - uint32_t bitset[(CONFIG_ZVFS_OPEN_MAX + 31) / 32]; -}; /** * Request codes for fd_op_vtable.ioctl(). * diff --git a/lib/os/CMakeLists.txt b/lib/os/CMakeLists.txt index 80f5f16f5d791..4ce50ad418292 100644 --- a/lib/os/CMakeLists.txt +++ b/lib/os/CMakeLists.txt @@ -12,9 +12,6 @@ zephyr_sources( ) zephyr_sources_ifdef(CONFIG_FDTABLE fdtable.c) -zephyr_syscall_header_ifdef(CONFIG_FDTABLE - ${ZEPHYR_BASE}/include/zephyr/sys/fdtable.h -) zephyr_sources_ifdef(CONFIG_CBPRINTF_COMPLETE cbprintf_complete.c) zephyr_sources_ifdef(CONFIG_CBPRINTF_NANO cbprintf_nano.c) diff --git a/lib/os/zvfs/CMakeLists.txt b/lib/os/zvfs/CMakeLists.txt index ef0dde4513bed..ca191a4d3ad7a 100644 --- a/lib/os/zvfs/CMakeLists.txt +++ b/lib/os/zvfs/CMakeLists.txt @@ -2,4 +2,3 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_ZVFS_EVENTFD zvfs_eventfd.c) -zephyr_library_sources_ifdef(CONFIG_ZVFS_POLL zvfs_poll.c) diff --git a/lib/os/zvfs/Kconfig b/lib/os/zvfs/Kconfig index 40cba2cd9c9f4..7f50ff52befc2 100644 --- a/lib/os/zvfs/Kconfig +++ b/lib/os/zvfs/Kconfig @@ -16,7 +16,7 @@ if ZVFS config ZVFS_EVENTFD bool "ZVFS event file descriptor support" - imply ZVFS_POLL + select POLL help Enable support for ZVFS event file descriptors. An eventfd can be used as an event wait/notify mechanism together with POSIX calls @@ -33,22 +33,4 @@ config ZVFS_EVENTFD_MAX endif # ZVFS_EVENTFD -config ZVFS_POLL - bool "ZVFS poll" - select POLL - help - Enable support for zvfs_poll(). - -if ZVFS_POLL - -config ZVFS_POLL_MAX - int "Max number of supported zvfs_poll() entries" - default 6 if WIFI_NM_WPA_SUPPLICANT - default 4 if SHELL_BACKEND_TELNET - default 3 - help - Maximum number of entries supported for poll() call. - -endif # ZVFS_POLL - endif # ZVFS diff --git a/lib/os/zvfs/zvfs_poll.c b/lib/os/zvfs/zvfs_poll.c deleted file mode 100644 index 45aec5cfb8d24..0000000000000 --- a/lib/os/zvfs/zvfs_poll.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2017-2018 Linaro Limited - * Copyright (c) 2021 Nordic Semiconductor - * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) -bool net_socket_is_tls(void *obj); -#else -#define net_socket_is_tls(obj) false -#endif - -int zvfs_poll_internal(struct zvfs_pollfd *fds, int nfds, k_timeout_t timeout) -{ - bool retry; - int ret = 0; - int i; - struct zvfs_pollfd *pfd; - struct k_poll_event poll_events[CONFIG_ZVFS_POLL_MAX]; - struct k_poll_event *pev; - struct k_poll_event *pev_end = poll_events + ARRAY_SIZE(poll_events); - const struct fd_op_vtable *vtable; - struct k_mutex *lock; - k_timepoint_t end; - bool offload = false; - const struct fd_op_vtable *offl_vtable = NULL; - void *offl_ctx = NULL; - - end = sys_timepoint_calc(timeout); - - pev = poll_events; - for (pfd = fds, i = nfds; i--; pfd++) { - void *ctx; - int result; - - /* Per POSIX, negative fd's are just ignored */ - if (pfd->fd < 0) { - continue; - } - - ctx = zvfs_get_fd_obj_and_vtable(pfd->fd, &vtable, &lock); - if (ctx == NULL) { - /* Will set POLLNVAL in return loop */ - continue; - } - - (void)k_mutex_lock(lock, K_FOREVER); - - result = zvfs_fdtable_call_ioctl(vtable, ctx, ZFD_IOCTL_POLL_PREPARE, pfd, &pev, - pev_end); - if (result == -EALREADY) { - /* If POLL_PREPARE returned with EALREADY, it means - * it already detected that some socket is ready. In - * this case, we still perform a k_poll to pick up - * as many events as possible, but without any wait. - */ - timeout = K_NO_WAIT; - end = sys_timepoint_calc(timeout); - result = 0; - } else if (result == -EXDEV) { - /* If POLL_PREPARE returned EXDEV, it means - * it detected an offloaded socket. - * If offloaded socket is used with native TLS, the TLS - * wrapper for the offloaded poll will be used. - * In case the fds array contains a mixup of offloaded - * and non-offloaded sockets, the offloaded poll handler - * shall return an error. - */ - offload = true; - if (offl_vtable == NULL || net_socket_is_tls(ctx)) { - offl_vtable = vtable; - offl_ctx = ctx; - } - - result = 0; - } - - k_mutex_unlock(lock); - - if (result < 0) { - errno = -result; - return -1; - } - } - - if (offload) { - int poll_timeout; - - if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { - poll_timeout = SYS_FOREVER_MS; - } else { - poll_timeout = k_ticks_to_ms_floor32(timeout.ticks); - } - - return zvfs_fdtable_call_ioctl(offl_vtable, offl_ctx, ZFD_IOCTL_POLL_OFFLOAD, fds, - nfds, poll_timeout); - } - - timeout = sys_timepoint_timeout(end); - - do { - ret = k_poll(poll_events, pev - poll_events, timeout); - /* EAGAIN when timeout expired, EINTR when cancelled (i.e. EOF) */ - if (ret != 0 && ret != -EAGAIN && ret != -EINTR) { - errno = -ret; - return -1; - } - - retry = false; - ret = 0; - - pev = poll_events; - for (pfd = fds, i = nfds; i--; pfd++) { - void *ctx; - int result; - - pfd->revents = 0; - - if (pfd->fd < 0) { - continue; - } - - ctx = zvfs_get_fd_obj_and_vtable(pfd->fd, &vtable, &lock); - if (ctx == NULL) { - pfd->revents = ZVFS_POLLNVAL; - ret++; - continue; - } - - (void)k_mutex_lock(lock, K_FOREVER); - - result = zvfs_fdtable_call_ioctl(vtable, ctx, ZFD_IOCTL_POLL_UPDATE, pfd, - &pev); - k_mutex_unlock(lock); - - if (result == -EAGAIN) { - retry = true; - continue; - } else if (result != 0) { - errno = -result; - return -1; - } - - if (pfd->revents != 0) { - ret++; - } - } - - if (retry) { - if (ret > 0) { - break; - } - - timeout = sys_timepoint_timeout(end); - - if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { - break; - } - } - } while (retry); - - return ret; -} - -int z_impl_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout) -{ - k_timeout_t timeout; - - if (poll_timeout < 0) { - timeout = K_FOREVER; - } else { - timeout = K_MSEC(poll_timeout); - } - - return zvfs_poll_internal(fds, nfds, timeout); -} - -#ifdef CONFIG_USERSPACE -static inline int z_vrfy_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int timeout) -{ - struct zvfs_pollfd *fds_copy; - size_t fds_size; - int ret; - - /* Copy fds array from user mode */ - if (size_mul_overflow(nfds, sizeof(struct zvfs_pollfd), &fds_size)) { - errno = EFAULT; - return -1; - } - fds_copy = k_usermode_alloc_from_copy((void *)fds, fds_size); - if (!fds_copy) { - errno = ENOMEM; - return -1; - } - - ret = z_impl_zvfs_poll(fds_copy, nfds, timeout); - - if (ret >= 0) { - k_usermode_to_copy((void *)fds, fds_copy, fds_size); - } - k_free(fds_copy); - - return ret; -} -#include -#endif diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index 9a4bbd60f4591..11a611691c945 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -6,10 +6,9 @@ menu "POSIX device I/O" config POSIX_DEVICE_IO bool "POSIX device I/O [EXPERIMENTAL]" + select FDTABLE select EXPERIMENTAL select REQUIRES_FULL_LIBC - select ZVFS - select ZVFS_POLL help Select 'y' here and Zephyr will provide an implementation of the POSIX_DEVICE_IO Option Group such as FD_CLR(), FD_ISSET(), FD_SET(), FD_ZERO(), close(), fdopen(), fileno(), open(), diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index 7b638c84976e7..e2c7510d7ad87 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -37,7 +37,8 @@ FUNC_ALIAS(open, _open, int); int poll(struct pollfd *fds, int nfds, int timeout) { - return zvfs_poll(fds, nfds, timeout); + /* TODO: create zvfs_poll() and dispatch to subsystems based on file type */ + return zsock_poll(fds, nfds, timeout); } ssize_t pread(int fd, void *buf, size_t count, off_t offset) diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index b767a05cba5ed..2fe534678fa1c 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -5,8 +5,7 @@ menuconfig NET_SOCKETS bool "BSD Sockets compatible API" - select ZVFS - select ZVFS_POLL + select FDTABLE help Provide BSD Sockets like API on top of native Zephyr networking API. @@ -48,7 +47,9 @@ config NET_SOCKETS_POSIX_NAMES config NET_SOCKETS_POLL_MAX int "Max number of supported poll() entries" - default ZVFS_POLL_MAX + default 6 if WIFI_NM_WPA_SUPPLICANT + default 4 if SHELL_BACKEND_TELNET + default 3 help Maximum number of entries supported for poll() call. diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index b78e1479222a2..88d8a3d091706 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -2306,6 +2306,224 @@ static int zsock_poll_update_ctx(struct net_context *ctx, return 0; } +static inline int time_left(uint32_t start, uint32_t timeout) +{ + uint32_t elapsed = k_uptime_get_32() - start; + + return timeout - elapsed; +} + +int zsock_poll_internal(struct zsock_pollfd *fds, int nfds, k_timeout_t timeout) +{ + bool retry; + int ret = 0; + int i; + struct zsock_pollfd *pfd; + struct k_poll_event poll_events[CONFIG_NET_SOCKETS_POLL_MAX]; + struct k_poll_event *pev; + struct k_poll_event *pev_end = poll_events + ARRAY_SIZE(poll_events); + const struct fd_op_vtable *vtable; + struct k_mutex *lock; + k_timepoint_t end; + bool offload = false; + const struct fd_op_vtable *offl_vtable = NULL; + void *offl_ctx = NULL; + + end = sys_timepoint_calc(timeout); + + pev = poll_events; + for (pfd = fds, i = nfds; i--; pfd++) { + void *ctx; + int result; + + /* Per POSIX, negative fd's are just ignored */ + if (pfd->fd < 0) { + continue; + } + + ctx = get_sock_vtable(pfd->fd, + (const struct socket_op_vtable **)&vtable, + &lock); + if (ctx == NULL) { + /* Will set POLLNVAL in return loop */ + continue; + } + + (void)k_mutex_lock(lock, K_FOREVER); + + result = zvfs_fdtable_call_ioctl(vtable, ctx, + ZFD_IOCTL_POLL_PREPARE, + pfd, &pev, pev_end); + if (result == -EALREADY) { + /* If POLL_PREPARE returned with EALREADY, it means + * it already detected that some socket is ready. In + * this case, we still perform a k_poll to pick up + * as many events as possible, but without any wait. + */ + timeout = K_NO_WAIT; + end = sys_timepoint_calc(timeout); + result = 0; + } else if (result == -EXDEV) { + /* If POLL_PREPARE returned EXDEV, it means + * it detected an offloaded socket. + * If offloaded socket is used with native TLS, the TLS + * wrapper for the offloaded poll will be used. + * In case the fds array contains a mixup of offloaded + * and non-offloaded sockets, the offloaded poll handler + * shall return an error. + */ + offload = true; + if (offl_vtable == NULL || net_socket_is_tls(ctx)) { + offl_vtable = vtable; + offl_ctx = ctx; + } + + result = 0; + } + + k_mutex_unlock(lock); + + if (result < 0) { + errno = -result; + return -1; + } + } + + if (offload) { + int poll_timeout; + + if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { + poll_timeout = SYS_FOREVER_MS; + } else { + poll_timeout = k_ticks_to_ms_floor32(timeout.ticks); + } + + return zvfs_fdtable_call_ioctl(offl_vtable, offl_ctx, + ZFD_IOCTL_POLL_OFFLOAD, + fds, nfds, poll_timeout); + } + + timeout = sys_timepoint_timeout(end); + + do { + ret = k_poll(poll_events, pev - poll_events, timeout); + /* EAGAIN when timeout expired, EINTR when cancelled (i.e. EOF) */ + if (ret != 0 && ret != -EAGAIN && ret != -EINTR) { + errno = -ret; + return -1; + } + + retry = false; + ret = 0; + + pev = poll_events; + for (pfd = fds, i = nfds; i--; pfd++) { + void *ctx; + int result; + + pfd->revents = 0; + + if (pfd->fd < 0) { + continue; + } + + ctx = get_sock_vtable( + pfd->fd, + (const struct socket_op_vtable **)&vtable, + &lock); + if (ctx == NULL) { + pfd->revents = ZSOCK_POLLNVAL; + ret++; + continue; + } + + (void)k_mutex_lock(lock, K_FOREVER); + + result = zvfs_fdtable_call_ioctl(vtable, ctx, + ZFD_IOCTL_POLL_UPDATE, + pfd, &pev); + k_mutex_unlock(lock); + + if (result == -EAGAIN) { + retry = true; + continue; + } else if (result != 0) { + errno = -result; + return -1; + } + + if (pfd->revents != 0) { + ret++; + } + } + + if (retry) { + if (ret > 0) { + break; + } + + timeout = sys_timepoint_timeout(end); + + if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { + break; + } + } + } while (retry); + + return ret; +} + +int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int poll_timeout) +{ + k_timeout_t timeout; + int ret; + + SYS_PORT_TRACING_OBJ_FUNC_ENTER(socket, poll, fds, nfds, poll_timeout); + + if (poll_timeout < 0) { + timeout = K_FOREVER; + } else { + timeout = K_MSEC(poll_timeout); + } + + ret = zsock_poll_internal(fds, nfds, timeout); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(socket, poll, fds, nfds, + ret < 0 ? -errno : ret); + return ret; +} + +#ifdef CONFIG_USERSPACE +static inline int z_vrfy_zsock_poll(struct zsock_pollfd *fds, + int nfds, int timeout) +{ + struct zsock_pollfd *fds_copy; + size_t fds_size; + int ret; + + /* Copy fds array from user mode */ + if (size_mul_overflow(nfds, sizeof(struct zsock_pollfd), &fds_size)) { + errno = EFAULT; + return -1; + } + fds_copy = k_usermode_alloc_from_copy((void *)fds, fds_size); + if (!fds_copy) { + errno = ENOMEM; + return -1; + } + + ret = z_impl_zsock_poll(fds_copy, nfds, timeout); + + if (ret >= 0) { + k_usermode_to_copy((void *)fds, fds_copy, fds_size); + } + k_free(fds_copy); + + return ret; +} +#include +#endif + int z_impl_zsock_inet_pton(sa_family_t family, const char *src, void *dst) { if (net_addr_pton(family, src, dst) == 0) { diff --git a/subsys/tracing/ctf/tracing_ctf.h b/subsys/tracing/ctf/tracing_ctf.h index 53eb097d07921..2756e6e8f5d1b 100644 --- a/subsys/tracing/ctf/tracing_ctf.h +++ b/subsys/tracing/ctf/tracing_ctf.h @@ -521,7 +521,7 @@ void sys_trace_k_event_init(struct k_event *event); */ struct sockaddr; struct msghdr; -struct zvfs_pollfd; +struct zsock_pollfd; void sys_trace_socket_init(int sock, int family, int type, int proto); void sys_trace_socket_close_enter(int sock); @@ -552,8 +552,8 @@ void sys_trace_socket_fcntl_enter(int sock, int cmd, int flags); void sys_trace_socket_fcntl_exit(int sock, int ret); void sys_trace_socket_ioctl_enter(int sock, int req); void sys_trace_socket_ioctl_exit(int sock, int ret); -void sys_trace_socket_poll_enter(const struct zvfs_pollfd *fds, int nfds, int timeout); -void sys_trace_socket_poll_exit(const struct zvfs_pollfd *fds, int nfds, int ret); +void sys_trace_socket_poll_enter(const struct zsock_pollfd *fds, int nfds, int timeout); +void sys_trace_socket_poll_exit(const struct zsock_pollfd *fds, int nfds, int ret); void sys_trace_socket_getsockopt_enter(int sock, int level, int optname); void sys_trace_socket_getsockopt_exit(int sock, int level, int optname, void *optval, size_t optlen, int ret); diff --git a/tests/net/lib/coap_client/src/stubs.c b/tests/net/lib/coap_client/src/stubs.c index 8fd41ef7e7258..13effd8f91b91 100644 --- a/tests/net/lib/coap_client/src/stubs.c +++ b/tests/net/lib/coap_client/src/stubs.c @@ -16,7 +16,7 @@ DEFINE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_recvfrom, int, void *, size_t, int, DEFINE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_sendto, int, void*, size_t, int, const struct sockaddr *, socklen_t); -struct zvfs_pollfd { +struct zsock_pollfd { int fd; short events; short revents; @@ -39,7 +39,7 @@ int z_impl_zsock_socket(int family, int type, int proto) return 0; } -int z_impl_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout) +int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int poll_timeout) { LOG_INF("Polling, events %d", my_events); k_sleep(K_MSEC(10)); diff --git a/tests/net/lib/lwm2m/lwm2m_engine/prj.conf b/tests/net/lib/lwm2m/lwm2m_engine/prj.conf index 4dd0a80c1f2d2..5d331d20c3312 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/prj.conf +++ b/tests/net/lib/lwm2m/lwm2m_engine/prj.conf @@ -1,5 +1,3 @@ CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=5120 CONFIG_MP_MAX_NUM_CPUS=1 - -CONFIG_ZVFS=y diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c index 953d4b72f2577..13b0e38e8e6e0 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c @@ -54,7 +54,7 @@ sys_slist_t *lwm2m_obs_obj_path_list(void) static sys_slist_t engine_obj_inst_list = SYS_SLIST_STATIC_INIT(&engine_obj_inst_list); sys_slist_t *lwm2m_engine_obj_inst_list(void) { return &engine_obj_inst_list; } -struct zvfs_pollfd { +struct zsock_pollfd { int fd; short events; short revents; @@ -123,7 +123,7 @@ ssize_t z_impl_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, return -1; } -int z_impl_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout) +int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int poll_timeout) { k_sleep(K_MSEC(1)); fds->revents = my_events; From 0797e987ff54c46ba267d5c0cc448939a5e7f7d0 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:10:40 +0200 Subject: [PATCH 15/18] Revert "posix: device_io: implement pread() and pwrite()" This reverts commit 2d729665162a21cf0bb5e5dc2f6ab36880e09ddd. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 54 +++++++++-------------------------- lib/posix/options/device_io.c | 32 +++------------------ 2 files changed, 17 insertions(+), 69 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index 6edf98066e19c..f65b7dc1ae294 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -308,21 +308,9 @@ int zvfs_alloc_fd(void *obj, const struct fd_op_vtable *vtable) return fd; } -static bool supports_pread_pwrite(uint32_t mode) +static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write) { - switch (mode & ZVFS_MODE_IFMT) { - case ZVFS_MODE_IFSHM: - return true; - default: - return false; - } -} - -static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write, const size_t *from_offset) -{ - bool prw; ssize_t res; - const size_t *off; if (_check_fd(fd) < 0) { return -1; @@ -330,40 +318,24 @@ static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write, const size_t (void)k_mutex_lock(&fdtable[fd].lock, K_FOREVER); - prw = supports_pread_pwrite(fdtable[fd].mode); - if (from_offset != NULL && !prw) { - /* - * Seekable file types should support pread() / pwrite() and per-fd offset passing. - * Otherwise, it's a bug. - */ - errno = ENOTSUP; - res = -1; - goto unlock; - } - - /* If there is no specified from_offset, then use the current offset of the fd */ - off = (from_offset == NULL) ? &fdtable[fd].offset : from_offset; - if (is_write) { - if (fdtable[fd].vtable->write_offs == NULL) { + if (fdtable[fd].vtable->write_offset == NULL) { res = -1; errno = EIO; } else { - res = fdtable[fd].vtable->write_offs(fdtable[fd].obj, buf, sz, *off); + res = fdtable[fd].vtable->write_offset(fdtable[fd].obj, buf, sz, + fdtable[fd].offset); } } else { - if (fdtable[fd].vtable->read_offs == NULL) { + if (fdtable[fd].vtable->read == NULL) { res = -1; errno = EIO; } else { - res = fdtable[fd].vtable->read_offs(fdtable[fd].obj, buf, sz, *off); + res = fdtable[fd].vtable->read_offset(fdtable[fd].obj, buf, sz, + fdtable[fd].offset); } } - if (res > 0 && prw && from_offset == NULL) { - /* - * only update the fd offset when from_offset is not specified - * See pread() / pwrite() - */ + if (res > 0) { fdtable[fd].offset += res; } @@ -373,14 +345,14 @@ static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write, const size_t return res; } -ssize_t zvfs_read(int fd, void *buf, size_t sz, const size_t *from_offset) +ssize_t zvfs_read(int fd, void *buf, size_t sz) { - return zvfs_rw(fd, buf, sz, false, from_offset); + return zvfs_rw(fd, buf, sz, false); } -ssize_t zvfs_write(int fd, const void *buf, size_t sz, const size_t *from_offset) +ssize_t zvfs_write(int fd, const void *buf, size_t sz) { - return zvfs_rw(fd, (void *)buf, sz, true, from_offset); + return zvfs_rw(fd, (void *)buf, sz, true); } int zvfs_close(int fd) @@ -522,7 +494,7 @@ static ssize_t stdinout_read_vmeth(void *obj, void *buffer, size_t count) static ssize_t stdinout_write_vmeth(void *obj, const void *buffer, size_t count) { #if defined(CONFIG_BOARD_NATIVE_POSIX) - return zvfs_write(1, buffer, count, NULL); + return zvfs_write(1, buffer, count); #elif defined(CONFIG_NEWLIB_LIBC) || defined(CONFIG_ARCMWDT_LIBC) return z_impl_zephyr_write_stdout(buffer, count); #else diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c index e2c7510d7ad87..585dc7000c2be 100644 --- a/lib/posix/options/device_io.c +++ b/lib/posix/options/device_io.c @@ -15,8 +15,8 @@ /* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ int zvfs_close(int fd); int zvfs_open(const char *name, int flags); -ssize_t zvfs_read(int fd, void *buf, size_t sz, size_t *from_offset); -ssize_t zvfs_write(int fd, const void *buf, size_t sz, size_t *from_offset); +ssize_t zvfs_read(int fd, void *buf, size_t sz); +ssize_t zvfs_write(int fd, const void *buf, size_t sz); int close(int fd) { @@ -41,33 +41,9 @@ int poll(struct pollfd *fds, int nfds, int timeout) return zsock_poll(fds, nfds, timeout); } -ssize_t pread(int fd, void *buf, size_t count, off_t offset) -{ - size_t off = (size_t)offset; - - if (offset < 0) { - errno = EINVAL; - return -1; - } - - return zvfs_read(fd, buf, count, (size_t *)&off); -} - -ssize_t pwrite(int fd, void *buf, size_t count, off_t offset) -{ - size_t off = (size_t)offset; - - if (offset < 0) { - errno = EINVAL; - return -1; - } - - return zvfs_write(fd, buf, count, (size_t *)&off); -} - ssize_t read(int fd, void *buf, size_t sz) { - return zvfs_read(fd, buf, sz, NULL); + return zvfs_read(fd, buf, sz); } #ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_READ FUNC_ALIAS(read, _read, ssize_t); @@ -81,7 +57,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struc ssize_t write(int fd, const void *buf, size_t sz) { - return zvfs_write(fd, buf, sz, NULL); + return zvfs_write(fd, buf, sz); } #ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_WRITE FUNC_ALIAS(write, _write, ssize_t); From 355c126169e130bb8f9332cbc90c0c2834c212ca Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:10:44 +0200 Subject: [PATCH 16/18] Revert "posix: device_io: provide stdin, stdout, stderr variables" This reverts commit 86b92934cc6c06a4080c6422269b815ac74c0aea. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 7 ------- lib/posix/options/Kconfig.device_io | 8 -------- 2 files changed, 15 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index f65b7dc1ae294..3bd22413c8e4a 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -14,7 +14,6 @@ */ #include -#include #include #include @@ -73,12 +72,6 @@ static struct fd_entry fdtable[CONFIG_ZVFS_OPEN_MAX] = { #endif }; -#ifdef CONFIG_POSIX_DEVICE_IO_STDIN_STDOUT_STDERR -FILE *stdin = &fdtable[0]; -FILE *stdout = &fdtable[1]; -FILE *stderr = &fdtable[2]; -#endif - static K_MUTEX_DEFINE(fdtable_lock); static int z_fd_ref(int fd) diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index 11a611691c945..0999a4462e2d2 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -42,14 +42,6 @@ config POSIX_DEVICE_IO_ALIAS_WRITE help Select 'y' here and Zephyr will provide an alias for write() as _write(). -config POSIX_DEVICE_IO_STDIN_STDOUT_STDERR - bool - help - Select 'y' here and Zephyr will provide the stdin, stdout, and stderr variables. - - Some libc's that implement the POSIX API may already have declared these variables. - However, it should be noted that they are a part of POSIX and not a part of ISO C. - endif # POSIX_DEVICE_IO config POSIX_OPEN_MAX From e912dffb080eddb4a1bd046a25d715d0d769b826 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:10:47 +0200 Subject: [PATCH 17/18] Revert "posix: device_io: require a full libc for c89 functions" This reverts commit 6f62292d42883a221c717cdaf99f59efbe69fa52. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/posix/options/Kconfig.device_io | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index 0999a4462e2d2..9cfbd453102bc 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -8,7 +8,6 @@ config POSIX_DEVICE_IO bool "POSIX device I/O [EXPERIMENTAL]" select FDTABLE select EXPERIMENTAL - select REQUIRES_FULL_LIBC help Select 'y' here and Zephyr will provide an implementation of the POSIX_DEVICE_IO Option Group such as FD_CLR(), FD_ISSET(), FD_SET(), FD_ZERO(), close(), fdopen(), fileno(), open(), From 50c1bf507d2bc35f459c267420149be6d322d503 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 1 Jul 2024 12:10:51 +0200 Subject: [PATCH 18/18] Revert "fdtable: read, write, close: only execute methods if non-NULL" This reverts commit a9a909c558c8c2069742aeee55aba831740826cd. PR #73978 introduced a regression. Unfortunately this PR cannot be reverted without reverting also Let's revert both PRs to stabilize main again towards the 3.7 release. For more details on the issue see https://github.com/zephyrproject-rtos/zephyr/issues/75205 Signed-off-by: Alberto Escolar Piedras --- lib/os/fdtable.c | 72 ++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index 3bd22413c8e4a..9594afdd8cd6c 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -301,7 +301,7 @@ int zvfs_alloc_fd(void *obj, const struct fd_op_vtable *vtable) return fd; } -static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write) +ssize_t zvfs_read(int fd, void *buf, size_t sz) { ssize_t res; @@ -310,57 +310,63 @@ static ssize_t zvfs_rw(int fd, void *buf, size_t sz, bool is_write) } (void)k_mutex_lock(&fdtable[fd].lock, K_FOREVER); - - if (is_write) { - if (fdtable[fd].vtable->write_offset == NULL) { - res = -1; - errno = EIO; - } else { - res = fdtable[fd].vtable->write_offset(fdtable[fd].obj, buf, sz, - fdtable[fd].offset); - } - } else { - if (fdtable[fd].vtable->read == NULL) { - res = -1; - errno = EIO; - } else { - res = fdtable[fd].vtable->read_offset(fdtable[fd].obj, buf, sz, - fdtable[fd].offset); - } - } + res = fdtable[fd].vtable->read_offs(fdtable[fd].obj, buf, sz, fdtable[fd].offset); if (res > 0) { - fdtable[fd].offset += res; + switch (fdtable[fd].mode & ZVFS_MODE_IFMT) { + case ZVFS_MODE_IFDIR: + case ZVFS_MODE_IFBLK: + case ZVFS_MODE_IFSHM: + case ZVFS_MODE_IFREG: + fdtable[fd].offset += res; + break; + default: + break; + } } - -unlock: k_mutex_unlock(&fdtable[fd].lock); return res; } -ssize_t zvfs_read(int fd, void *buf, size_t sz) -{ - return zvfs_rw(fd, buf, sz, false); -} - ssize_t zvfs_write(int fd, const void *buf, size_t sz) { - return zvfs_rw(fd, (void *)buf, sz, true); + ssize_t res; + + if (_check_fd(fd) < 0) { + return -1; + } + + (void)k_mutex_lock(&fdtable[fd].lock, K_FOREVER); + res = fdtable[fd].vtable->write_offs(fdtable[fd].obj, buf, sz, fdtable[fd].offset); + if (res > 0) { + switch (fdtable[fd].mode & ZVFS_MODE_IFMT) { + case ZVFS_MODE_IFDIR: + case ZVFS_MODE_IFBLK: + case ZVFS_MODE_IFSHM: + case ZVFS_MODE_IFREG: + fdtable[fd].offset += res; + break; + default: + break; + } + } + k_mutex_unlock(&fdtable[fd].lock); + + return res; } int zvfs_close(int fd) { - int res = 0; + int res; if (_check_fd(fd) < 0) { return -1; } (void)k_mutex_lock(&fdtable[fd].lock, K_FOREVER); - if (fdtable[fd].vtable->close != NULL) { - /* close() is optional - e.g. stdinout_fd_op_vtable */ - res = fdtable[fd].vtable->close(fdtable[fd].obj); - } + + res = fdtable[fd].vtable->close(fdtable[fd].obj); + k_mutex_unlock(&fdtable[fd].lock); zvfs_free_fd(fd);