1 
2 #ifdef HAVE_CONFIG_H
3 #  include "config.h"
4 #endif
5 
6 #include "sys.h"
7 #include "erl_osenv.h"
8 #include "erl_alloc.h"
9 
10 #include "erl_thr_progress.h"
11 
12 static erts_osenv_t sysenv_global_env;
13 static erts_rwmtx_t sysenv_rwmtx;
14 
15 extern char **environ;
16 
17 static void import_initial_env(void);
18 
erts_sys_env_init()19 void erts_sys_env_init() {
20     erts_rwmtx_init(&sysenv_rwmtx, "environ", NIL,
21         ERTS_LOCK_FLAGS_PROPERTY_STATIC | ERTS_LOCK_FLAGS_CATEGORY_GENERIC);
22 
23     erts_osenv_init(&sysenv_global_env);
24     import_initial_env();
25 }
26 
erts_sys_rlock_global_osenv()27 const erts_osenv_t *erts_sys_rlock_global_osenv() {
28     erts_rwmtx_rlock(&sysenv_rwmtx);
29     return &sysenv_global_env;
30 }
31 
erts_sys_rwlock_global_osenv()32 erts_osenv_t *erts_sys_rwlock_global_osenv() {
33     erts_rwmtx_rwlock(&sysenv_rwmtx);
34     return &sysenv_global_env;
35 }
36 
erts_sys_rwunlock_global_osenv()37 void erts_sys_rwunlock_global_osenv() {
38     erts_rwmtx_rwunlock(&sysenv_rwmtx);
39 }
40 
erts_sys_runlock_global_osenv()41 void erts_sys_runlock_global_osenv() {
42     erts_rwmtx_runlock(&sysenv_rwmtx);
43 }
44 
erts_sys_explicit_8bit_putenv(char * key,char * value)45 int erts_sys_explicit_8bit_putenv(char *key, char *value) {
46     erts_osenv_data_t env_key, env_value;
47     int result;
48 
49     env_key.length = sys_strlen(key);
50     env_key.data = key;
51 
52     env_value.length = sys_strlen(value);
53     env_value.data = value;
54 
55     {
56         erts_osenv_t *env = erts_sys_rwlock_global_osenv();
57         result = erts_osenv_put_native(env, &env_key, &env_value);
58         erts_sys_rwunlock_global_osenv();
59     }
60 
61     return result;
62 }
63 
erts_sys_explicit_8bit_getenv(char * key,char * value,size_t * size)64 int erts_sys_explicit_8bit_getenv(char *key, char *value, size_t *size) {
65     erts_osenv_data_t env_key, env_value;
66     int result;
67 
68     env_key.length = sys_strlen(key);
69     env_key.data = key;
70 
71     /* Reserve space for NUL termination. */
72     env_value.length = *size - 1;
73     env_value.data = value;
74 
75     {
76         const erts_osenv_t *env = erts_sys_rlock_global_osenv();
77         result = erts_osenv_get_native(env, &env_key, &env_value);
78         erts_sys_runlock_global_osenv();
79     }
80 
81     if(result == 1) {
82         value[env_value.length] = '\0';
83     }
84 
85     *size = env_value.length;
86 
87     return result;
88 }
89 
erts_sys_explicit_host_getenv(char * key,char * value,size_t * size)90 int erts_sys_explicit_host_getenv(char *key, char *value, size_t *size) {
91     char *orig_value;
92     size_t length;
93 
94     orig_value = getenv(key);
95 
96     if(orig_value == NULL) {
97         return 0;
98     }
99 
100     length = sys_strlen(orig_value);
101 
102     if (length >= *size) {
103         *size = length + 1;
104         return -1;
105     }
106 
107     sys_memcpy((void*)value, (void*)orig_value, length + 1);
108     *size = length;
109 
110     return 1;
111 }
112 
import_initial_env(void)113 static void import_initial_env(void) {
114     char **environ_iterator, *environ_variable;
115 
116     environ_iterator = environ;
117 
118     while ((environ_variable = *(environ_iterator++)) != NULL) {
119         char *separator_index = strchr(environ_variable, '=');
120 
121         if (separator_index != NULL) {
122             erts_osenv_data_t env_key, env_value;
123 
124             env_key.length = separator_index - environ_variable;
125             env_key.data = environ_variable;
126 
127             env_value.length = sys_strlen(separator_index) - 1;
128             env_value.data = separator_index + 1;
129 
130             erts_osenv_put_native(&sysenv_global_env, &env_key, &env_value);
131         }
132     }
133 }
134