1 /*
2  * %CopyrightBegin%
3  *
4  * Copyright Ericsson AB 1999-2017. All Rights Reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * %CopyrightEnd%
19  */
20 
21 /*
22  * BIFs belonging to the 'os' module.
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #  include "config.h"
27 #endif
28 
29 #include "sys.h"
30 #include "erl_vm.h"
31 #include "global.h"
32 #include "erl_process.h"
33 #include "error.h"
34 #include "erl_driver.h"
35 #include "bif.h"
36 #include "big.h"
37 #include "dist.h"
38 #include "erl_version.h"
39 #include "erl_osenv.h"
40 
41 /*
42  * Return the pid for the Erlang process in the host OS.
43  */
44 
45  /* return a timestamp */
os_timestamp_0(BIF_ALIST_0)46 BIF_RETTYPE os_timestamp_0(BIF_ALIST_0)
47 {
48     Uint megasec, sec, microsec;
49     Eterm* hp;
50 
51     get_sys_now(&megasec, &sec, &microsec);
52     hp = HAlloc(BIF_P, 4);
53     BIF_RET(TUPLE3(hp, make_small(megasec), make_small(sec),
54 		   make_small(microsec)));
55 }
56 
57 
os_getpid_0(BIF_ALIST_0)58 BIF_RETTYPE os_getpid_0(BIF_ALIST_0)
59 {
60      char pid_string[21]; /* enough for a 64 bit number */
61      int n;
62      Eterm* hp;
63      sys_get_pid(pid_string, sizeof(pid_string)); /* In sys.c */
64      n = sys_strlen(pid_string);
65      hp = HAlloc(BIF_P, n*2);
66      BIF_RET(buf_to_intlist(&hp, pid_string, n, NIL));
67 }
68 
os_getenv_foreach(Process * process,Eterm * result,Eterm key,Eterm value)69 static void os_getenv_foreach(Process *process, Eterm *result, Eterm key, Eterm value)
70 {
71     Eterm kvp_term, *hp;
72 
73     hp = HAlloc(process, 5);
74     kvp_term = TUPLE2(hp, key, value);
75     hp += 3;
76 
77     (*result) = CONS(hp, kvp_term, (*result));
78 }
79 
os_list_env_vars_0(BIF_ALIST_0)80 BIF_RETTYPE os_list_env_vars_0(BIF_ALIST_0)
81 {
82     const erts_osenv_t *global_env;
83     Eterm result = NIL;
84 
85     global_env = erts_sys_rlock_global_osenv();
86     erts_osenv_foreach_term(global_env, BIF_P, &result, (void*)&os_getenv_foreach);
87     erts_sys_runlock_global_osenv();
88 
89     return result;
90 }
91 
os_get_env_var_1(BIF_ALIST_1)92 BIF_RETTYPE os_get_env_var_1(BIF_ALIST_1)
93 {
94     const erts_osenv_t *global_env;
95     Eterm out_term;
96     int error;
97 
98     global_env = erts_sys_rlock_global_osenv();
99     error = erts_osenv_get_term(global_env, BIF_P, BIF_ARG_1, &out_term);
100     erts_sys_runlock_global_osenv();
101 
102     if (error == 0) {
103         return am_false;
104     } else if (error < 0) {
105         BIF_ERROR(BIF_P, BADARG);
106     }
107 
108     return out_term;
109 }
110 
os_set_env_var_2(BIF_ALIST_2)111 BIF_RETTYPE os_set_env_var_2(BIF_ALIST_2)
112 {
113     erts_osenv_t *global_env;
114     int error;
115 
116     global_env = erts_sys_rwlock_global_osenv();
117     error = erts_osenv_put_term(global_env, BIF_ARG_1, BIF_ARG_2);
118     erts_sys_rwunlock_global_osenv();
119 
120     if (error < 0) {
121         BIF_ERROR(BIF_P, BADARG);
122     }
123 
124     BIF_RET(am_true);
125 }
126 
os_unset_env_var_1(BIF_ALIST_1)127 BIF_RETTYPE os_unset_env_var_1(BIF_ALIST_1)
128 {
129     erts_osenv_t *global_env;
130     int error;
131 
132     global_env = erts_sys_rwlock_global_osenv();
133     error = erts_osenv_unset_term(global_env, BIF_ARG_1);
134     erts_sys_rwunlock_global_osenv();
135 
136     if (error < 0) {
137         BIF_ERROR(BIF_P, BADARG);
138     }
139 
140     BIF_RET(am_true);
141 }
142 
os_set_signal_2(BIF_ALIST_2)143 BIF_RETTYPE os_set_signal_2(BIF_ALIST_2) {
144     if (is_atom(BIF_ARG_1) && ((BIF_ARG_2 == am_ignore) ||
145                                (BIF_ARG_2 == am_default) ||
146                                (BIF_ARG_2 == am_handle))) {
147         if (!erts_set_signal(BIF_ARG_1, BIF_ARG_2))
148             goto error;
149 
150         BIF_RET(am_ok);
151     }
152 
153 error:
154     BIF_ERROR(BIF_P, BADARG);
155 }
156