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 "xtc_export.h"
19
20
#include <stddef.h>
21
#include <stdint.h>
22
23
/*
24
* --- Environment (thread-safe against concurrent get/set) ---
25
*
26
* getenv(3) and setenv(3) are not safe against each other: setenv may
27
* reallocate the environ block a concurrent getenv is reading. These
28
* serialize every get/set on one process-wide mutex, and get COPIES
29
* the value into a caller buffer so the returned data cannot be
30
* invalidated by a later setenv from another thread.
31
*
32
* __os_env_get copies the value of `name` into `buf` (always
33
* NUL-terminated when bufsize > 0, truncating if needed). Returns
34
* XTC_OK when the variable exists, XTC_E_NOTFOUND when it does not
35
* (buf is set to the empty string), XTC_E_INVAL on a NULL argument.
36
*
37
* __os_env_set sets/overwrites `name` to `value`; when overwrite == 0
38
* an existing variable is left unchanged. Returns XTC_OK, or
39
* XTC_E_INVAL / XTC_E_NOMEM.
40
*
41
* PUBLIC: int __os_env_get __P((const char *, char *, size_t));
42
* PUBLIC: int __os_env_set __P((const char *, const char *, int));
43
*/
44
XTC_API
int
__os_env_get(
const
char
*name,
char
*buf,
size_t
bufsize);
45
XTC_API
int
__os_env_set(
const
char
*name,
const
char
*value,
int
overwrite);
46
47
/*
48
* --- Per-thread seedable PRNG ---
49
*
50
* rand(3)/random(3) share process-global state and are not thread-safe.
51
* This is a per-thread splitmix64 stream: each thread has its own state
52
* so there is no cross-thread contention or shared-state race, and
53
* __os_rand_seed makes a thread's stream reproducible. The first use
54
* on a thread that has not been seeded auto-seeds from the monotonic
55
* clock XORed with the thread-local state address, so distinct threads
56
* get distinct streams by default.
57
*
58
* NOTE: this is NOT wired into the DST deterministic-simulation clock
59
* (src/evt/sim.c); a future task can add a sim hook here so a
60
* replayed run draws a reproducible sequence. For now it is simply a
61
* clean, thread-safe, explicitly seedable entropy source.
62
*
63
* PUBLIC: void __os_rand_seed __P((uint64_t));
64
* PUBLIC: uint64_t __os_rand_u64 __P((void));
65
*/
66
XTC_API
void
__os_rand_seed(uint64_t seed);
67
XTC_API uint64_t __os_rand_u64(
void
);
68
69
/*
70
* --- Bounded string copy/cat (BSD strlcpy/strlcat semantics) ---
71
*
72
* strncpy(3) does not NUL-terminate when the source is at least as long
73
* as the buffer; strncat(3) uses a confusing count. These follow the
74
* OpenBSD contract: always NUL-terminate when dstsize > 0, and return
75
* the total length the function TRIED to create -- for strlcpy that is
76
* strlen(src); for strlcat that is the initial strlen(dst) plus
77
* strlen(src). A return value >= dstsize means the result was
78
* truncated. Pure; no allocation.
79
*
80
* PUBLIC: size_t __os_strlcpy __P((char *, const char *, size_t));
81
* PUBLIC: size_t __os_strlcat __P((char *, const char *, size_t));
82
*/
83
XTC_API
size_t
__os_strlcpy(
char
*dst,
const
char
*src,
size_t
dstsize);
84
XTC_API
size_t
__os_strlcat(
char
*dst,
const
char
*src,
size_t
dstsize);
85
86
#endif
/* XTC_OS_SHARP_H */
src
inc
os_sharp.h
Generated by
1.9.8