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