libxtc
0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
os_sharp.h
1
/*-
2
* Copyright (c) 2026, The XTC Project
3
* Use of this source code is governed by the ISC License.
4
*
5
* src/inc/os_sharp.h
6
* POSIX/libc "sharp edges" abstraction: thread-safe environment
7
* access, a per-thread seedable PRNG, and BSD-semantics bounded
8
* string copy/cat. These smooth three well-known threaded-C
9
* footguns (getenv/setenv races, the process-global non-reentrant
10
* rand(), and strncpy's missing NUL terminator). The public
11
* complement is xtc_env_get / xtc_env_set / xtc_rand_u64 /
12
* xtc_rand_seed / xtc_strlcpy / xtc_strlcat.
13
*/
14
15
#ifndef XTC_OS_SHARP_H
16
#define XTC_OS_SHARP_H
17
18
#include <stddef.h>
19
#include <stdint.h>
20
21
/*
22
* --- Environment (thread-safe against concurrent get/set) ---
23
*
24
* getenv(3) and setenv(3) are not safe against each other: setenv may
25
* reallocate the environ block a concurrent getenv is reading. These
26
* serialize every get/set on one process-wide mutex, and get COPIES
27
* the value into a caller buffer so the returned data cannot be
28
* invalidated by a later setenv from another thread.
29
*
30
* __os_env_get copies the value of `name` into `buf` (always
31
* NUL-terminated when bufsize > 0, truncating if needed). Returns
32
* XTC_OK when the variable exists, XTC_E_NOTFOUND when it does not
33
* (buf is set to the empty string), XTC_E_INVAL on a NULL argument.
34
*
35
* __os_env_set sets/overwrites `name` to `value`; when overwrite == 0
36
* an existing variable is left unchanged. Returns XTC_OK, or
37
* XTC_E_INVAL / XTC_E_NOMEM.
38
*
39
* PUBLIC: int __os_env_get __P((const char *, char *, size_t));
40
* PUBLIC: int __os_env_set __P((const char *, const char *, int));
41
*/
42
int
__os_env_get(
const
char
*name,
char
*buf,
size_t
bufsize);
43
int
__os_env_set(
const
char
*name,
const
char
*value,
int
overwrite);
44
45
/*
46
* --- Per-thread seedable PRNG ---
47
*
48
* rand(3)/random(3) share process-global state and are not thread-safe.
49
* This is a per-thread splitmix64 stream: each thread has its own state
50
* so there is no cross-thread contention or shared-state race, and
51
* __os_rand_seed makes a thread's stream reproducible. The first use
52
* on a thread that has not been seeded auto-seeds from the monotonic
53
* clock XORed with the thread-local state address, so distinct threads
54
* get distinct streams by default.
55
*
56
* NOTE: this is NOT wired into the DST deterministic-simulation clock
57
* (src/evt/sim.c); a future task can add a sim hook here so a
58
* replayed run draws a reproducible sequence. For now it is simply a
59
* clean, thread-safe, explicitly seedable entropy source.
60
*
61
* PUBLIC: void __os_rand_seed __P((uint64_t));
62
* PUBLIC: uint64_t __os_rand_u64 __P((void));
63
*/
64
void
__os_rand_seed(uint64_t seed);
65
uint64_t __os_rand_u64(
void
);
66
67
/*
68
* --- Bounded string copy/cat (BSD strlcpy/strlcat semantics) ---
69
*
70
* strncpy(3) does not NUL-terminate when the source is at least as long
71
* as the buffer; strncat(3) uses a confusing count. These follow the
72
* OpenBSD contract: always NUL-terminate when dstsize > 0, and return
73
* the total length the function TRIED to create -- for strlcpy that is
74
* strlen(src); for strlcat that is the initial strlen(dst) plus
75
* strlen(src). A return value >= dstsize means the result was
76
* truncated. Pure; no allocation.
77
*
78
* PUBLIC: size_t __os_strlcpy __P((char *, const char *, size_t));
79
* PUBLIC: size_t __os_strlcat __P((char *, const char *, size_t));
80
*/
81
size_t
__os_strlcpy(
char
*dst,
const
char
*src,
size_t
dstsize);
82
size_t
__os_strlcat(
char
*dst,
const
char
*src,
size_t
dstsize);
83
84
#endif
/* XTC_OS_SHARP_H */
src
inc
os_sharp.h
Generated by
1.9.8