Browse Source

posix: implement the XSI_SINGLE_PROCESS Option Group

gettimeofday() was already implemented, but incorrectly lumped into
POSIX_TIMERS.

putenv() is really just a wrapper around setenv().

The only one left to implement was gethostid() which was relatively
trivial.

Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
pull/89922/head
Chris Friedt 3 months ago committed by Anas Nashif
parent
commit
cfae041834
  1. 4
      include/zephyr/posix/unistd.h
  2. 9
      lib/posix/options/CMakeLists.txt
  3. 6
      lib/posix/options/Kconfig.proc1
  4. 1
      lib/posix/options/Kconfig.profile
  5. 7
      lib/posix/options/Kconfig.xsi_single_process
  6. 21
      lib/posix/options/clock.c
  7. 92
      lib/posix/options/xsi_single_process.c
  8. 1
      tests/lib/time/prj.conf
  9. 2
      tests/posix/headers/src/sys_time_h.c

4
include/zephyr/posix/unistd.h

@ -77,6 +77,10 @@ size_t confstr(int name, char *buf, size_t len);
long sysconf(int opt); long sysconf(int opt);
#endif /* CONFIG_POSIX_SYSCONF_IMPL_FULL */ #endif /* CONFIG_POSIX_SYSCONF_IMPL_FULL */
#if _XOPEN_SOURCE >= 500
long gethostid(void);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

9
lib/posix/options/CMakeLists.txt

@ -3,6 +3,7 @@
set(GEN_DIR ${ZEPHYR_BINARY_DIR}/include/generated) set(GEN_DIR ${ZEPHYR_BINARY_DIR}/include/generated)
zephyr_syscall_header_ifdef(CONFIG_POSIX_TIMERS posix_clock.h) zephyr_syscall_header_ifdef(CONFIG_POSIX_TIMERS posix_clock.h)
zephyr_syscall_header_ifdef(CONFIG_XSI_SINGLE_PROCESS posix_clock.h)
if(CONFIG_POSIX_API) if(CONFIG_POSIX_API)
zephyr_include_directories(${ZEPHYR_BASE}/include/zephyr/posix) zephyr_include_directories(${ZEPHYR_BASE}/include/zephyr/posix)
@ -155,6 +156,14 @@ endif()
zephyr_library_sources_ifdef(CONFIG_XOPEN_STREAMS stropts.c) zephyr_library_sources_ifdef(CONFIG_XOPEN_STREAMS stropts.c)
if (NOT CONFIG_TC_PROVIDES_XSI_SINGLE_PROCESS)
zephyr_library_sources_ifdef(CONFIG_XSI_SINGLE_PROCESS
clock_common.c
env_common.c
xsi_single_process.c
)
endif()
if (NOT CONFIG_TC_PROVIDES_XSI_SYSTEM_LOGGING) if (NOT CONFIG_TC_PROVIDES_XSI_SYSTEM_LOGGING)
zephyr_library_sources_ifdef(CONFIG_XSI_SYSTEM_LOGGING syslog.c) zephyr_library_sources_ifdef(CONFIG_XSI_SYSTEM_LOGGING syslog.c)
endif() endif()

6
lib/posix/options/Kconfig.proc1

@ -49,8 +49,12 @@ config POSIX_UNAME_NODENAME_LEN
help help
Defines the maximum string length of nodename version. Defines the maximum string length of nodename version.
endif # POSIX_SINGLE_PROCESS
if POSIX_SINGLE_PROCESS || XSI_SINGLE_PROCESS
module = POSIX_ENV module = POSIX_ENV
module-str = POSIX env logging module-str = POSIX env logging
source "subsys/logging/Kconfig.template.log_config" source "subsys/logging/Kconfig.template.log_config"
endif # POSIX_SINGLE_PROCESS endif # POSIX_SINGLE_PROCESS || XSI_SINGLE_PROCESS

1
lib/posix/options/Kconfig.profile

@ -12,6 +12,7 @@ config POSIX_API
imply EVENTFD # eventfd(), eventfd_read(), eventfd_write() imply EVENTFD # eventfd(), eventfd_read(), eventfd_write()
imply POSIX_FD_MGMT # open(), close(), read(), write() imply POSIX_FD_MGMT # open(), close(), read(), write()
imply POSIX_MULTI_PROCESS # sleep(), getpid(), etc imply POSIX_MULTI_PROCESS # sleep(), getpid(), etc
imply XSI_SINGLE_PROCESS # gettimeofday()
help help
This option enables the required POSIX System Interfaces (base definitions), all of PSE51, This option enables the required POSIX System Interfaces (base definitions), all of PSE51,
and some features found in PSE52. and some features found in PSE52.

7
lib/posix/options/Kconfig.xsi_single_process

@ -4,11 +4,14 @@
config XSI_SINGLE_PROCESS config XSI_SINGLE_PROCESS
bool "X/Open single process" bool "X/Open single process"
depends on POSIX_SINGLE_PROCESS select HWINFO
depends on POSIX_TIMERS
help help
Select 'y' here and Zephyr will provide implementations of Select 'y' here and Zephyr will provide implementations of
gethostid(), gettimeofday(), and putenv(). gethostid(), gettimeofday(), and putenv().
For more information, please see For more information, please see
https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html
module = XSI_SINGLE_PROCESS
module-str = XSI Single Process
source "subsys/logging/Kconfig.template.log_config"

21
lib/posix/options/clock.c

@ -91,27 +91,6 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
return z_clock_nanosleep(CLOCK_MONOTONIC, 0, rqtp, rmtp); return z_clock_nanosleep(CLOCK_MONOTONIC, 0, rqtp, rmtp);
} }
/**
* @brief Get current real time.
*
* See IEEE 1003.1
*/
int gettimeofday(struct timeval *tv, void *tz)
{
struct timespec ts;
int res;
/* As per POSIX, "if tzp is not a null pointer, the behavior
* is unspecified." "tzp" is the "tz" parameter above. */
ARG_UNUSED(tz);
res = clock_gettime(CLOCK_REALTIME, &ts);
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
return res;
}
int clock_getcpuclockid(pid_t pid, clockid_t *clock_id) int clock_getcpuclockid(pid_t pid, clockid_t *clock_id)
{ {
/* We don't allow any process ID but our own. */ /* We don't allow any process ID but our own. */

92
lib/posix/options/xsi_single_process.c

@ -0,0 +1,92 @@
/*
* Copyright (c) 2018 Intel Corporation
* Copyright (c) 2023 Meta
* Copyright (c) 2025 Tenstorrent AI ULC
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <zephyr/drivers/hwinfo.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys_clock.h>
#include <zephyr/toolchain.h>
LOG_MODULE_REGISTER(xsi_single_process, CONFIG_XSI_SINGLE_PROCESS_LOG_LEVEL);
extern int z_setenv(const char *name, const char *val, int overwrite);
extern int z_clock_gettime(clockid_t clockid, struct timespec *tp);
long gethostid(void)
{
int rc;
uint32_t buf = 0;
rc = hwinfo_get_device_id((uint8_t *)&buf, sizeof(buf));
if ((rc < 0) || (rc != sizeof(buf)) || (buf == 0)) {
LOG_DBG("%s() failed: %d", "hwinfo_get_device_id", rc);
return (long)rc;
}
return (long)buf;
}
int gettimeofday(struct timeval *tv, void *tz)
{
struct timespec ts;
int res;
/*
* As per POSIX, "if tzp is not a null pointer, the behavior is unspecified." "tzp" is the
* "tz" parameter above.
*/
ARG_UNUSED(tz);
res = z_clock_gettime(CLOCK_REALTIME, &ts);
if (res < 0) {
LOG_DBG("%s() failed: %d", "clock_gettime", res);
return res;
}
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
return 0;
}
int putenv(char *string)
{
if (string == NULL) {
errno = EINVAL;
return -1;
}
char *const name = string;
for (char *val = name; *val != '\0'; ++val) {
if (*val == '=') {
int rc;
*val = '\0';
++val;
rc = z_setenv(name, val, 1);
--val;
*val = '=';
if (rc < 0) {
LOG_DBG("%s() failed: %d", "setenv", rc);
return rc;
}
return 0;
}
}
/* was unable to find '=' in string */
errno = EINVAL;
return -1;
}

1
tests/lib/time/prj.conf

@ -1,3 +1,4 @@
CONFIG_ZTEST=y CONFIG_ZTEST=y
CONFIG_POSIX_TIMERS=y CONFIG_POSIX_TIMERS=y
CONFIG_XSI_SINGLE_PROCESS=y
CONFIG_PICOLIBC=y CONFIG_PICOLIBC=y

2
tests/posix/headers/src/sys_time_h.c

@ -29,7 +29,7 @@ ZTEST(posix_headers, test_sys_time_h)
/* zassert_not_equal(-1, ITIMER_VIRTUAL); */ /* not implemented */ /* zassert_not_equal(-1, ITIMER_VIRTUAL); */ /* not implemented */
/* zassert_not_equal(-1, ITIMER_PROF); */ /* not implemented */ /* zassert_not_equal(-1, ITIMER_PROF); */ /* not implemented */
if (IS_ENABLED(CONFIG_POSIX_API)) { if (IS_ENABLED(CONFIG_XSI_SINGLE_PROCESS)) {
/* zassert_not_null(getitimer); */ /* not implemented */ /* zassert_not_null(getitimer); */ /* not implemented */
zassert_not_null(gettimeofday); zassert_not_null(gettimeofday);
/* zassert_not_null(setitimer); */ /* not implemented */ /* zassert_not_null(setitimer); */ /* not implemented */

Loading…
Cancel
Save