feat(stdlib): environment and multibyte helpers
This commit is contained in:
@@ -367,6 +367,170 @@ lcong48(unsigned short param[7]);
|
||||
|
||||
#endif /* VLIBC_LEVEL_GE(2) */
|
||||
|
||||
/* environment, multibyte characters, and temporary files (todo 13) */
|
||||
|
||||
/*
|
||||
* getenv/setenv/unsetenv (POSIX base), the C-locale multibyte conversions
|
||||
* (C23 7.24.7), and mkstemp/mkdtemp are level 1. The XSI/BSD extras —
|
||||
* putenv, clearenv, mktemp, the PTY helpers, and getsubopt — are level 2.
|
||||
*
|
||||
* None of these functions carries an intent attribute. getenv and the
|
||||
* environment mutators all read or write the shared global environ, so
|
||||
* pure/const would let the compiler hoist a stale getenv result across a
|
||||
* setenv call. The multibyte conversions are locale-stateful in general,
|
||||
* the temporary-file functions create filesystem entries, and ptsname
|
||||
* writes a shared static buffer — none of them is side-effect-free.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The process environment: a NULL-terminated array of "name=value"
|
||||
* strings. The array is installed by the startup code before main; the
|
||||
* functions below mutate it (setenv/unsetenv copy strings into malloc'd
|
||||
* storage). Reassigning environ directly is permitted by POSIX, but
|
||||
* calling setenv/unsetenv/putenv/clearenv afterwards is undefined, as it
|
||||
* is everywhere (the array is then no longer guaranteed to be owned by
|
||||
* the library).
|
||||
*/
|
||||
extern char **environ;
|
||||
|
||||
/*
|
||||
* Return a pointer to the value part (the bytes after '=') of the
|
||||
* environment entry whose name matches name, or NULL when the variable
|
||||
* is not set. The pointer is valid until the next setenv, unsetenv,
|
||||
* putenv, or clearenv call. No intent attribute: the result depends on
|
||||
* the mutable global environ.
|
||||
*/
|
||||
char *
|
||||
getenv(const char *name);
|
||||
|
||||
/*
|
||||
* Set name to value. A copy of "name=value" is made, so the caller may
|
||||
* reuse or free its buffers once the call returns. With overwrite
|
||||
* nonzero an existing entry is replaced; with overwrite zero an existing
|
||||
* entry is left unchanged and 0 is returned. Returns -1 with errno
|
||||
* EINVAL when name is NULL, empty, or contains '=', and -1 with errno
|
||||
* ENOMEM on allocation failure. A NULL value is treated as the empty
|
||||
* string.
|
||||
*/
|
||||
int
|
||||
setenv(const char *name, const char *value, int overwrite);
|
||||
|
||||
/*
|
||||
* Remove every entry whose name is name, compacting the array. Returns
|
||||
* -1 with errno EINVAL when name is NULL, empty, or contains '='.
|
||||
*/
|
||||
int
|
||||
unsetenv(const char *name);
|
||||
|
||||
/*
|
||||
* C-locale multibyte conversions (C23 7.24.7). Only the "C" locale
|
||||
* exists today (locale support is a later todo), where every multibyte
|
||||
* character is a single byte: byte c corresponds to the wide character
|
||||
* (unsigned char)c. The encoding is therefore stateless — the s == NULL
|
||||
* and NULL-destination forms all report "state-independent" — and no
|
||||
* mbstate_t variant is needed. mbtowc never fails in this locale (every
|
||||
* byte, including 0x80..0xFF, is a valid character); wctomb fails with
|
||||
* -1 + errno EILSEQ for any wchar_t outside 0..255.
|
||||
*/
|
||||
int
|
||||
mblen(const char *s, size_t n);
|
||||
|
||||
int
|
||||
mbtowc(wchar_t *restrict pwc, const char *restrict s, size_t n);
|
||||
|
||||
int
|
||||
wctomb(char *s, wchar_t wc);
|
||||
|
||||
size_t
|
||||
mbstowcs(wchar_t *restrict pwcs, const char *restrict s, size_t n);
|
||||
|
||||
size_t
|
||||
wcstombs(char *restrict s, const wchar_t *restrict pwcs, size_t n);
|
||||
|
||||
/*
|
||||
* Temporary files and directories. mkstemp replaces the trailing
|
||||
* "XXXXXX" of the template with random characters, creates the file
|
||||
* with mode 0600, and returns an open file descriptor (-1 with errno
|
||||
* EINVAL when the template has no "XXXXXX" suffix). mkdtemp does the
|
||||
* same replacement, creates a directory with mode 0700, and returns the
|
||||
* template (NULL on failure). The parameter is unnamed in these
|
||||
* declarations because POSIX's `template` is a C++ keyword and this
|
||||
* header is compiled by C++ consumers too.
|
||||
*/
|
||||
int
|
||||
mkstemp(char *);
|
||||
|
||||
char *
|
||||
mkdtemp(char *);
|
||||
|
||||
#if VLIBC_LEVEL_GE(2)
|
||||
/* Level 2 (muslmimic): XSI and BSD environment extras. */
|
||||
|
||||
/*
|
||||
* Add string — a "name=value" pair in CALLER-OWNED storage — to the
|
||||
* environment: the caller's buffer becomes part of the environment and
|
||||
* must remain valid for the life of the process. An existing variable of
|
||||
* the same name is replaced (the old pointer is dropped); a string
|
||||
* without '=' removes the variable instead (glibc/musl behavior).
|
||||
* Returns 0, or -1 with errno ENOMEM.
|
||||
*/
|
||||
int
|
||||
putenv(char *string);
|
||||
|
||||
/*
|
||||
* Empty the environment, leaving environ as a fresh valid empty array
|
||||
* (never NULL) so later setenv calls keep working. The previous array
|
||||
* and its entries are deliberately not freed — entries may be putenv'd
|
||||
* caller storage or initial-stack strings. Returns 0, or -1 with errno
|
||||
* ENOMEM.
|
||||
*/
|
||||
int
|
||||
clearenv(void);
|
||||
|
||||
/*
|
||||
* Obsolescent mkstemp without the file: fills in the trailing "XXXXXX"
|
||||
* and returns the template, creating nothing. The name is not guaranteed
|
||||
* unique — nothing exists to race on. NULL with errno EINVAL when the
|
||||
* template has no "XXXXXX" suffix.
|
||||
*/
|
||||
char *
|
||||
mktemp(char *);
|
||||
|
||||
/*
|
||||
* XSI PTY helpers. posix_openpt opens the master side of a
|
||||
* pseudo-terminal via /dev/ptmx (flags, plus O_NOCTTY, are passed to
|
||||
* open) and returns the fd. grantpt returns 0 without doing anything:
|
||||
* modern kernels grant the slave when the master is opened. unlockpt
|
||||
* releases the slave-side lock. ptsname formats the slave path
|
||||
* "/dev/pts/N" into a shared static buffer — the result is valid until
|
||||
* the next ptsname call and is not thread-safe.
|
||||
*/
|
||||
int
|
||||
posix_openpt(int flags);
|
||||
|
||||
char *
|
||||
ptsname(int fd);
|
||||
|
||||
int
|
||||
grantpt(int fd);
|
||||
|
||||
int
|
||||
unlockpt(int fd);
|
||||
|
||||
/*
|
||||
* Parse one comma-separated suboption out of *optionp (POSIX XSI). On
|
||||
* success the index of the matching token is returned and *valuep points
|
||||
* to the "=value" part (or is NULL when the suboption has no '='); for
|
||||
* an unrecognized suboption -1 is returned and *valuep points to the
|
||||
* whole suboption string; at the end of the list -1 is returned and
|
||||
* *valuep is NULL. *optionp always advances past the comma, which is
|
||||
* overwritten with NUL (the string is modified in place).
|
||||
*/
|
||||
int
|
||||
getsubopt(char **optionp, char *const *tokens, char **valuep);
|
||||
|
||||
#endif /* VLIBC_LEVEL_GE(2) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user