]> git.proxmox.com Git - wasi-libc.git/blame - libc-bottom-half/sources/__environ.c
Fix -std=gnu17 when generating predefined_macros.txt (#187)
[wasi-libc.git] / libc-bottom-half / sources / __environ.c
CommitLineData
bdfbb545
DG
1#include <unistd.h>
2#include <stdlib.h>
410c6607 3#include <sysexits.h>
446cb3f1 4#include <wasi/api.h>
bdfbb545 5#include <wasi/libc.h>
bdfbb545 6
a8a5dbcf
DG
7static char *empty_environ[1] = { NULL };
8char **__environ = empty_environ;
bdfbb545
DG
9extern __typeof(__environ) _environ __attribute__((weak, alias("__environ")));
10extern __typeof(__environ) environ __attribute__((weak, alias("__environ")));
11
410c6607
DG
12// We define this function here in the same source file as __environ, so that
13// this function is called in iff environment variable support is used.
14// Concerning the 50 -- levels up to 100 are reserved for the implementation,
15// so we an arbitrary number in the middle of the range to allow other
16// reserved things to go before or after.
17__attribute__((constructor(50)))
18static void __wasilibc_populate_environ(void) {
bdfbb545
DG
19 __wasi_errno_t err;
20
21 // Get the sizes of the arrays we'll have to create to copy in the environment.
22 size_t environ_count;
23 size_t environ_buf_size;
24 err = __wasi_environ_sizes_get(&environ_count, &environ_buf_size);
446cb3f1 25 if (err != __WASI_ERRNO_SUCCESS) {
410c6607 26 goto oserr;
bdfbb545
DG
27 }
28 if (environ_count == 0) {
410c6607 29 return;
bdfbb545
DG
30 }
31
32 // Add 1 for the NULL pointer to mark the end, and check for overflow.
33 size_t num_ptrs = environ_count + 1;
34 if (num_ptrs == 0) {
410c6607 35 goto software;
bdfbb545
DG
36 }
37
38 // Allocate memory for storing the environment chars.
39 char *environ_buf = malloc(environ_buf_size);
40 if (environ_buf == NULL) {
410c6607 41 goto software;
bdfbb545
DG
42 }
43
44 // Allocate memory for the array of pointers. This uses `calloc` both to
45 // handle overflow and to initialize the NULL pointer at the end.
46 char **environ_ptrs = calloc(num_ptrs, sizeof(char *));
47 if (environ_ptrs == NULL) {
48 free(environ_buf);
410c6607 49 goto software;
bdfbb545
DG
50 }
51
52 // Fill the environment chars, and the __environ array with pointers into those chars.
446cb3f1
DG
53 // TODO: Remove the casts on `environ_ptrs` and `environ_buf` once the witx is updated with char8 support.
54 err = __wasi_environ_get((uint8_t **)environ_ptrs, (uint8_t *)environ_buf);
410c6607 55 if (err != __WASI_ERRNO_SUCCESS) {
bdfbb545
DG
56 free(environ_buf);
57 free(environ_ptrs);
410c6607 58 goto oserr;
bdfbb545 59 }
410c6607
DG
60
61 __environ = environ_ptrs;
1fad3389 62 return;
410c6607
DG
63oserr:
64 _Exit(EX_OSERR);
65software:
66 _Exit(EX_SOFTWARE);
bdfbb545 67}