Skip to content

Commit cfae041

Browse files
cfriedtnashif
authored andcommitted
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>
1 parent 0b869ef commit cfae041

File tree

9 files changed

+118
-25
lines changed

9 files changed

+118
-25
lines changed

include/zephyr/posix/unistd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ size_t confstr(int name, char *buf, size_t len);
7777
long sysconf(int opt);
7878
#endif /* CONFIG_POSIX_SYSCONF_IMPL_FULL */
7979

80+
#if _XOPEN_SOURCE >= 500
81+
long gethostid(void);
82+
#endif
83+
8084
#ifdef __cplusplus
8185
}
8286
#endif

lib/posix/options/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
set(GEN_DIR ${ZEPHYR_BINARY_DIR}/include/generated)
44

55
zephyr_syscall_header_ifdef(CONFIG_POSIX_TIMERS posix_clock.h)
6+
zephyr_syscall_header_ifdef(CONFIG_XSI_SINGLE_PROCESS posix_clock.h)
67

78
if(CONFIG_POSIX_API)
89
zephyr_include_directories(${ZEPHYR_BASE}/include/zephyr/posix)
@@ -155,6 +156,14 @@ endif()
155156

156157
zephyr_library_sources_ifdef(CONFIG_XOPEN_STREAMS stropts.c)
157158

159+
if (NOT CONFIG_TC_PROVIDES_XSI_SINGLE_PROCESS)
160+
zephyr_library_sources_ifdef(CONFIG_XSI_SINGLE_PROCESS
161+
clock_common.c
162+
env_common.c
163+
xsi_single_process.c
164+
)
165+
endif()
166+
158167
if (NOT CONFIG_TC_PROVIDES_XSI_SYSTEM_LOGGING)
159168
zephyr_library_sources_ifdef(CONFIG_XSI_SYSTEM_LOGGING syslog.c)
160169
endif()

lib/posix/options/Kconfig.proc1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,12 @@ config POSIX_UNAME_NODENAME_LEN
4949
help
5050
Defines the maximum string length of nodename version.
5151

52+
endif # POSIX_SINGLE_PROCESS
53+
54+
if POSIX_SINGLE_PROCESS || XSI_SINGLE_PROCESS
55+
5256
module = POSIX_ENV
5357
module-str = POSIX env logging
5458
source "subsys/logging/Kconfig.template.log_config"
5559

56-
endif # POSIX_SINGLE_PROCESS
60+
endif # POSIX_SINGLE_PROCESS || XSI_SINGLE_PROCESS

lib/posix/options/Kconfig.profile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ config POSIX_API
1212
imply EVENTFD # eventfd(), eventfd_read(), eventfd_write()
1313
imply POSIX_FD_MGMT # open(), close(), read(), write()
1414
imply POSIX_MULTI_PROCESS # sleep(), getpid(), etc
15+
imply XSI_SINGLE_PROCESS # gettimeofday()
1516
help
1617
This option enables the required POSIX System Interfaces (base definitions), all of PSE51,
1718
and some features found in PSE52.

lib/posix/options/Kconfig.xsi_single_process

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44

55
config XSI_SINGLE_PROCESS
66
bool "X/Open single process"
7-
depends on POSIX_SINGLE_PROCESS
8-
depends on POSIX_TIMERS
7+
select HWINFO
98
help
109
Select 'y' here and Zephyr will provide implementations of
1110
gethostid(), gettimeofday(), and putenv().
1211

1312
For more information, please see
1413
https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html
14+
15+
module = XSI_SINGLE_PROCESS
16+
module-str = XSI Single Process
17+
source "subsys/logging/Kconfig.template.log_config"

lib/posix/options/clock.c

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -91,27 +91,6 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
9191
return z_clock_nanosleep(CLOCK_MONOTONIC, 0, rqtp, rmtp);
9292
}
9393

94-
/**
95-
* @brief Get current real time.
96-
*
97-
* See IEEE 1003.1
98-
*/
99-
int gettimeofday(struct timeval *tv, void *tz)
100-
{
101-
struct timespec ts;
102-
int res;
103-
104-
/* As per POSIX, "if tzp is not a null pointer, the behavior
105-
* is unspecified." "tzp" is the "tz" parameter above. */
106-
ARG_UNUSED(tz);
107-
108-
res = clock_gettime(CLOCK_REALTIME, &ts);
109-
tv->tv_sec = ts.tv_sec;
110-
tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
111-
112-
return res;
113-
}
114-
11594
int clock_getcpuclockid(pid_t pid, clockid_t *clock_id)
11695
{
11796
/* We don't allow any process ID but our own. */
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright (c) 2018 Intel Corporation
3+
* Copyright (c) 2023 Meta
4+
* Copyright (c) 2025 Tenstorrent AI ULC
5+
*
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#include <errno.h>
10+
#include <string.h>
11+
#include <sys/time.h>
12+
#include <time.h>
13+
14+
#include <zephyr/drivers/hwinfo.h>
15+
#include <zephyr/logging/log.h>
16+
#include <zephyr/sys_clock.h>
17+
#include <zephyr/toolchain.h>
18+
19+
LOG_MODULE_REGISTER(xsi_single_process, CONFIG_XSI_SINGLE_PROCESS_LOG_LEVEL);
20+
21+
extern int z_setenv(const char *name, const char *val, int overwrite);
22+
extern int z_clock_gettime(clockid_t clockid, struct timespec *tp);
23+
24+
long gethostid(void)
25+
{
26+
int rc;
27+
uint32_t buf = 0;
28+
29+
rc = hwinfo_get_device_id((uint8_t *)&buf, sizeof(buf));
30+
if ((rc < 0) || (rc != sizeof(buf)) || (buf == 0)) {
31+
LOG_DBG("%s() failed: %d", "hwinfo_get_device_id", rc);
32+
return (long)rc;
33+
}
34+
35+
return (long)buf;
36+
}
37+
38+
int gettimeofday(struct timeval *tv, void *tz)
39+
{
40+
struct timespec ts;
41+
int res;
42+
43+
/*
44+
* As per POSIX, "if tzp is not a null pointer, the behavior is unspecified." "tzp" is the
45+
* "tz" parameter above.
46+
*/
47+
ARG_UNUSED(tz);
48+
49+
res = z_clock_gettime(CLOCK_REALTIME, &ts);
50+
if (res < 0) {
51+
LOG_DBG("%s() failed: %d", "clock_gettime", res);
52+
return res;
53+
}
54+
55+
tv->tv_sec = ts.tv_sec;
56+
tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
57+
58+
return 0;
59+
}
60+
61+
int putenv(char *string)
62+
{
63+
if (string == NULL) {
64+
errno = EINVAL;
65+
return -1;
66+
}
67+
68+
char *const name = string;
69+
70+
for (char *val = name; *val != '\0'; ++val) {
71+
if (*val == '=') {
72+
int rc;
73+
74+
*val = '\0';
75+
++val;
76+
rc = z_setenv(name, val, 1);
77+
--val;
78+
*val = '=';
79+
80+
if (rc < 0) {
81+
LOG_DBG("%s() failed: %d", "setenv", rc);
82+
return rc;
83+
}
84+
85+
return 0;
86+
}
87+
}
88+
89+
/* was unable to find '=' in string */
90+
errno = EINVAL;
91+
return -1;
92+
}

tests/lib/time/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
CONFIG_ZTEST=y
22
CONFIG_POSIX_TIMERS=y
3+
CONFIG_XSI_SINGLE_PROCESS=y
34
CONFIG_PICOLIBC=y

tests/posix/headers/src/sys_time_h.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ ZTEST(posix_headers, test_sys_time_h)
2929
/* zassert_not_equal(-1, ITIMER_VIRTUAL); */ /* not implemented */
3030
/* zassert_not_equal(-1, ITIMER_PROF); */ /* not implemented */
3131

32-
if (IS_ENABLED(CONFIG_POSIX_API)) {
32+
if (IS_ENABLED(CONFIG_XSI_SINGLE_PROCESS)) {
3333
/* zassert_not_null(getitimer); */ /* not implemented */
3434
zassert_not_null(gettimeofday);
3535
/* zassert_not_null(setitimer); */ /* not implemented */

0 commit comments

Comments
 (0)