This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit eb8dca9782b4cfd82be966ca43aa31f7ec9bb35c Author: Marco Casaroli <[email protected]> AuthorDate: Tue Oct 20 20:50:45 2026 +0200 libs/libc/unistd: Answer every POSIX name in sysconf(). sysconf() knew 21 names. For all other names of <unistd.h>, also for the limits that <limits.h> defines (LINE_MAX, HOST_NAME_MAX, TIMER_MAX, PTHREAD_KEYS_MAX, ...), it returned -1 with errno ENOSYS. POSIX requires EINVAL for a name that is not valid, and -1 without a change of errno for a valid name that has no limit or an option that is not supported. Programs read -1 as "no limit" and check errno. Return the value of the <limits.h> or <unistd.h> constant for each limit and option. For an option that <unistd.h> leaves undefined, return _POSIX_VERSION if the configuration has it (fsync(), IPv6, regcomp(), the priority inheritance and protection of mutexes), else -1. The names of the C compilation environments give 1 for the environment of the build. _SC_THREAD_THREADS_MAX is -1: the number of threads has no limit (the uint8_t member count of the task group is gone). _SC_PHYS_PAGES and _SC_AVPHYS_PAGES come from sysinfo(). _SC_GETGR_R_SIZE_MAX is the buffer that getgrgid_r() needs. Return -1 with errno unchanged for the other names, and -1 with EINVAL for a name that is not valid. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- include/unistd.h | 4 +- libs/libc/unistd/lib_sysconf.c | 374 +++++++++++++++++++++++++++++++++++------ 2 files changed, 327 insertions(+), 51 deletions(-) diff --git a/include/unistd.h b/include/unistd.h index 91b68141756..07682ef08e7 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -201,8 +201,8 @@ #define _PC_SYNC_IO 0x0012 #define _PC_VDISABLE 0x0013 -/* Constants used with POSIX sysconf(). sysconf() will return -1 and set - * errno to ENOSYS for most of these. +/* Constants used with POSIX sysconf(). sysconf() returns -1 for the + * options and limits that NuttX does not have. */ #define _SC_2_C_BIND 0x0001 diff --git a/libs/libc/unistd/lib_sysconf.c b/libs/libc/unistd/lib_sysconf.c index b577d053768..79fb6acdff6 100644 --- a/libs/libc/unistd/lib_sysconf.c +++ b/libs/libc/unistd/lib_sysconf.c @@ -29,6 +29,7 @@ #include <nuttx/atexit.h> #include <sys/resource.h> +#include <sys/sysinfo.h> #include <unistd.h> #include <limits.h> #include <sched.h> @@ -209,41 +210,87 @@ long sysconf(int name) { - int errcode; - - /* NOTE: The initialize implementation of this interface is very sparse. - * It was originally created to support only the functionality of - * getdtablesize() but can be extended to support as much of the standard - * POSIX sysconf() as is necessary. - */ - switch (name) { -#ifdef CONFIG_FS_AIO - case _SC_ASYNCHRONOUS_IO: - return _POSIX_ASYNCHRONOUS_IO; -#endif - case _SC_PRIORITIZED_IO: - return _POSIX_PRIORITIZED_IO; + /* Limits of <limits.h> */ + + case _SC_AIO_LISTIO_MAX: + return AIO_LISTIO_MAX; + case _SC_AIO_MAX: return AIO_MAX; + + case _SC_AIO_PRIO_DELTA_MAX: + return 0; + + case _SC_ARG_MAX: + return ARG_MAX; + + case _SC_ATEXIT_MAX: + return ATEXIT_MAX; + + case _SC_BC_BASE_MAX: + return _POSIX2_BC_BASE_MAX; + + case _SC_BC_DIM_MAX: + return _POSIX2_BC_DIM_MAX; + + case _SC_BC_SCALE_MAX: + return _POSIX2_BC_SCALE_MAX; + + case _SC_BC_STRING_MAX: + return _POSIX2_BC_STRING_MAX; + + case _SC_CHILD_MAX: + return CHILD_MAX; + + case _SC_CLK_TCK: + return CLK_TCK; + + case _SC_COLL_WEIGHTS_MAX: + return _POSIX2_COLL_WEIGHTS_MAX; + + case _SC_DELAYTIMER_MAX: + return DELAYTIMER_MAX; + + case _SC_EXPR_NEST_MAX: + return _POSIX2_EXPR_NEST_MAX; + + case _SC_GETGR_R_SIZE_MAX: +#ifdef CONFIG_LIBC_GROUP_FILE + return CONFIG_LIBC_GROUP_LINESIZE + + (CONFIG_LIBC_GROUP_NUSERS + 1) * sizeof(FAR char *); +#else + return -1; +#endif + case _SC_GETPW_R_SIZE_MAX: #ifdef CONFIG_LIBC_PASSWD_LINESIZE return CONFIG_LIBC_PASSWD_LINESIZE; #else return _POSIX_GETPW_R_SIZE_MAX; #endif - case _SC_CPUTIME: - return _POSIX_CPUTIME; - case _SC_THREAD_CPUTIME: - return _POSIX_THREAD_CPUTIME; - case _SC_REALTIME_SIGNALS: - return _POSIX_REALTIME_SIGNALS; - case _SC_CLK_TCK: - return CLK_TCK; - case _SC_ARG_MAX: - return ARG_MAX; + case _SC_HOST_NAME_MAX: + return HOST_NAME_MAX; + + case _SC_IOV_MAX: + return IOV_MAX; + + case _SC_LINE_MAX: + return LINE_MAX; + + case _SC_LOGIN_NAME_MAX: + return LOGIN_NAME_MAX; + + case _SC_MQ_OPEN_MAX: + return MQ_OPEN_MAX; + + case _SC_MQ_PRIO_MAX: + return MQ_PRIO_MAX; + + case _SC_NGROUPS_MAX: + return NGROUPS_MAX; case _SC_OPEN_MAX: { @@ -259,48 +306,277 @@ long sysconf(int name) return OPEN_MAX; } - case _SC_NGROUPS_MAX: - return NGROUPS_MAX; + case _SC_PAGESIZE: + return DEFAULT_MM_PGSIZE; - case _SC_ATEXIT_MAX: - return ATEXIT_MAX; + case _SC_RE_DUP_MAX: + return _POSIX2_RE_DUP_MAX; + + case _SC_RTSIG_MAX: + return RTSIG_MAX; + + case _SC_SEM_NSEMS_MAX: + return SEM_NSEMS_MAX; + + case _SC_SEM_VALUE_MAX: + return SEM_VALUE_MAX; + + case _SC_SIGQUEUE_MAX: + return SIGQUEUE_MAX; + + case _SC_STREAM_MAX: + return STREAM_MAX; + + case _SC_SYMLOOP_MAX: + return SYMLOOP_MAX; + + case _SC_THREAD_DESTRUCTOR_ITERATIONS: + return PTHREAD_DESTRUCTOR_ITERATIONS; + + /* A configuration without pthreads has no CONFIG_TLS_NELEM */ + + case _SC_THREAD_KEYS_MAX: +#ifdef CONFIG_TLS_NELEM + return PTHREAD_KEYS_MAX; +#else + return 0; +#endif + + case _SC_THREAD_STACK_MIN: + return CONFIG_PTHREAD_STACK_MIN; + + case _SC_TIMER_MAX: + return TIMER_MAX; + + case _SC_TTY_NAME_MAX: + return TTY_NAME_MAX; + + case _SC_TZNAME_MAX: + return TZNAME_MAX; + + /* Memory and processors */ + + case _SC_PHYS_PAGES: + case _SC_AVPHYS_PAGES: + { + struct sysinfo info; + + if (sysinfo(&info) < 0) + { + return -1; + } + + return (name == _SC_PHYS_PAGES ? info.totalram : info.freeram) * + info.mem_unit / DEFAULT_MM_PGSIZE; + } case _SC_NPROCESSORS_CONF: case _SC_NPROCESSORS_ONLN: return CONFIG_SMP_NCPUS; - case _SC_MONOTONIC_CLOCK: - return _POSIX_MONOTONIC_CLOCK; + /* Options of <unistd.h>: the value of the macro, -1 if not supported */ + + case _SC_ASYNCHRONOUS_IO: +#ifdef _POSIX_ASYNCHRONOUS_IO + return _POSIX_ASYNCHRONOUS_IO; +#else + return -1; +#endif + + case _SC_BARRIERS: + return _POSIX_BARRIERS; case _SC_CLOCK_SELECTION: return _POSIX_CLOCK_SELECTION; - case _SC_PAGESIZE: - return DEFAULT_MM_PGSIZE; + case _SC_CPUTIME: + return _POSIX_CPUTIME; - case _SC_THREAD_STACK_MIN: - return CONFIG_PTHREAD_STACK_MIN; + case _SC_MAPPED_FILES: + return _POSIX_MAPPED_FILES; - /* threads limit to tcb_s->group->tg_nmembers(unint_8) */ + case _SC_MESSAGE_PASSING: + return _POSIX_MESSAGE_PASSING; - case _SC_THREAD_THREADS_MAX: - return UINT8_MAX; + case _SC_MONOTONIC_CLOCK: + return _POSIX_MONOTONIC_CLOCK; - case _SC_AIO_LISTIO_MAX: - return AIO_LISTIO_MAX; + case _SC_PRIORITIZED_IO: + return _POSIX_PRIORITIZED_IO; - case _SC_IOV_MAX: - return IOV_MAX; + case _SC_PRIORITY_SCHEDULING: + return _POSIX_PRIORITY_SCHEDULING; - default: -#if 0 /* Assume valid but not implemented for the time being */ - errcode = EINVAL; + case _SC_READER_WRITER_LOCKS: + return _POSIX_READER_WRITER_LOCKS; + + case _SC_REALTIME_SIGNALS: + return _POSIX_REALTIME_SIGNALS; + + case _SC_SEMAPHORES: + return _POSIX_SEMAPHORES; + + case _SC_SHARED_MEMORY_OBJECTS: + return _POSIX_SHARED_MEMORY_OBJECTS; + + case _SC_SPIN_LOCKS: + return _POSIX_SPIN_LOCKS; + + case _SC_SPORADIC_SERVER: + return _POSIX_SPORADIC_SERVER; + + case _SC_SYNCHRONIZED_IO: + return _POSIX_SYNCHRONIZED_IO; + + case _SC_THREAD_ATTR_STACKADDR: + return _POSIX_THREAD_ATTR_STACKADDR; + + case _SC_THREAD_ATTR_STACKSIZE: + return _POSIX_THREAD_ATTR_STACKSIZE; + + case _SC_THREAD_CPUTIME: + return _POSIX_THREAD_CPUTIME; + + case _SC_THREAD_PRIORITY_SCHEDULING: + return _POSIX_THREAD_PRIORITY_SCHEDULING; + + case _SC_THREAD_PROCESS_SHARED: + return _POSIX_THREAD_PROCESS_SHARED; + + case _SC_THREAD_SPORADIC_SERVER: + return _POSIX_THREAD_SPORADIC_SERVER; + + case _SC_THREADS: + return _POSIX_THREADS; + + case _SC_TIMEOUTS: +#ifdef _POSIX_TIMEOUTS + return _POSIX_TIMEOUTS; #else - errcode = ENOSYS; + return -1; #endif - break; - } - set_errno(errcode); - return ERROR; + case _SC_TIMERS: +#ifdef _POSIX_TIMERS + return _POSIX_TIMERS; +#else + return -1; +#endif + + case _SC_VERSION: + return _POSIX_VERSION; + + case _SC_XOPEN_UNIX: + return _XOPEN_UNIX; + + case _SC_XOPEN_VERSION: + return _XOPEN_VERSION; + + /* Options that <unistd.h> leaves undefined: sysconf() tells if this + * configuration has them. + */ + + case _SC_FSYNC: + return _POSIX_VERSION; + + case _SC_IPV6: +#ifdef CONFIG_NET_IPv6 + return _POSIX_VERSION; +#else + return -1; +#endif + + case _SC_REGEXP: +#ifdef CONFIG_LIBC_REGEX + return _POSIX_VERSION; +#else + return -1; +#endif + + case _SC_THREAD_PRIO_INHERIT: +#if defined(CONFIG_PRIORITY_INHERITANCE) && !defined(CONFIG_DISABLE_PTHREAD) + return _POSIX_VERSION; +#else + return -1; +#endif + + case _SC_THREAD_PRIO_PROTECT: +#if defined(CONFIG_PRIORITY_PROTECT) && !defined(CONFIG_DISABLE_PTHREAD) + return _POSIX_VERSION; +#else + return -1; +#endif + + /* The C-language compilation environment of this build */ + + case _SC_V6_ILP32_OFF32: + case _SC_XBS5_ILP32_OFF32: + return sizeof(int) == 4 && sizeof(long) == 4 && + sizeof(FAR void *) == 4 && sizeof(off_t) == 4 ? 1 : -1; + + case _SC_V6_ILP32_OFFBIG: + case _SC_XBS5_ILP32_OFFBIG: + return sizeof(int) == 4 && sizeof(long) == 4 && + sizeof(FAR void *) == 4 && sizeof(off_t) == 8 ? 1 : -1; + + case _SC_V6_LP64_OFF64: + case _SC_XBS5_LP64_OFF64: + return sizeof(int) == 4 && sizeof(long) == 8 && + sizeof(FAR void *) == 8 && sizeof(off_t) == 8 ? 1 : -1; + + /* Names that POSIX defines, for options and limits that NuttX does not + * have: -1 without a change of errno. + */ + + case _SC_2_C_BIND: + case _SC_2_C_DEV: + case _SC_2_CHAR_TERM: + case _SC_2_FORT_DEV: + case _SC_2_FORT_RUN: + case _SC_2_LOCALEDEF: + case _SC_2_PBS: + case _SC_2_PBS_ACCOUNTING: + case _SC_2_PBS_CHECKPOINT: + case _SC_2_PBS_LOCATE: + case _SC_2_PBS_MESSAGE: + case _SC_2_PBS_TRACK: + case _SC_2_SW_DEV: + case _SC_2_UPE: + case _SC_2_VERSION: + case _SC_ADVISORY_INFO: + case _SC_JOB_CONTROL: + case _SC_MEMLOCK: + case _SC_MEMLOCK_RANGE: + case _SC_MEMORY_PROTECTION: + case _SC_RAW_SOCKETS: + case _SC_SAVED_IDS: + case _SC_SHELL: + case _SC_SPAWN: + case _SC_SS_REPL_MAX: + case _SC_THREAD_SAFE_FUNCTIONS: + case _SC_THREAD_THREADS_MAX: + case _SC_TRACE: + case _SC_TRACE_EVENT_FILTER: + case _SC_TRACE_EVENT_NAME_MAX: + case _SC_TRACE_INHERIT: + case _SC_TRACE_LOG: + case _SC_TRACE_NAME_MAX: + case _SC_TRACE_SYS_MAX: + case _SC_TRACE_USER_EVENT_MAX: + case _SC_TYPED_MEMORY_OBJECTS: + case _SC_V6_LPBIG_OFFBIG: + case _SC_XBS5_LPBIG_OFFBIG: + case _SC_XOPEN_CRYPT: + case _SC_XOPEN_ENH_I18N: + case _SC_XOPEN_LEGACY: + case _SC_XOPEN_REALTIME: + case _SC_XOPEN_REALTIME_THREADS: + case _SC_XOPEN_SHM: + case _SC_XOPEN_STREAMS: + return -1; + + default: + set_errno(EINVAL); + return -1; + } }
