1 | /*
|
---|
2 | ** env.c - ENV is a Hash-like accessor for environment variables.
|
---|
3 | **
|
---|
4 | */
|
---|
5 |
|
---|
6 | #include "mruby.h"
|
---|
7 | #include "mruby/hash.h"
|
---|
8 | #include "mruby/khash.h"
|
---|
9 | #include "mruby/class.h"
|
---|
10 | #include "mruby/array.h"
|
---|
11 | #include "mruby/string.h"
|
---|
12 | #include "mruby/variable.h"
|
---|
13 | #include <string.h>
|
---|
14 | #include <stdio.h>
|
---|
15 | #include <stdlib.h>
|
---|
16 |
|
---|
17 | #ifdef _WIN32
|
---|
18 | int
|
---|
19 | unsetenv(const char* name)
|
---|
20 | {
|
---|
21 | int r;
|
---|
22 | char* p = malloc(strlen(name) + 2);
|
---|
23 | if (!p) return -1;
|
---|
24 | strcpy(p, name);
|
---|
25 | strcat(p, "=");
|
---|
26 | r = _putenv(p);
|
---|
27 | free(p);
|
---|
28 | return r;
|
---|
29 | }
|
---|
30 |
|
---|
31 | int
|
---|
32 | setenv(const char* name, const char* value, int overwrite)
|
---|
33 | {
|
---|
34 | int r;
|
---|
35 | char* p = malloc(strlen(name) + strlen(value) + 2);
|
---|
36 | if (!p) return -1;
|
---|
37 | strcpy(p, name);
|
---|
38 | strcat(p, "=");
|
---|
39 | strcat(p, value);
|
---|
40 | r = _putenv(p);
|
---|
41 | free(p);
|
---|
42 | return r;
|
---|
43 | }
|
---|
44 | #define environ _environ
|
---|
45 | #else
|
---|
46 | extern char **environ;
|
---|
47 | #endif
|
---|
48 |
|
---|
49 |
|
---|
50 | mrb_value
|
---|
51 | mrb_env_aget(mrb_state *mrb, mrb_value self)
|
---|
52 | {
|
---|
53 | mrb_value key;
|
---|
54 | const char *cname, *cvalue;
|
---|
55 |
|
---|
56 | mrb_get_args(mrb, "S", &key);
|
---|
57 | cname = mrb_string_value_cstr(mrb, &key);
|
---|
58 | cvalue = getenv(cname);
|
---|
59 | if (cvalue != NULL) {
|
---|
60 | return mrb_str_new_cstr(mrb, cvalue);
|
---|
61 | } else {
|
---|
62 | return mrb_nil_value();
|
---|
63 | }
|
---|
64 | }
|
---|
65 |
|
---|
66 | mrb_value
|
---|
67 | mrb_env_has_key(mrb_state *mrb, mrb_value self)
|
---|
68 | {
|
---|
69 | mrb_value name;
|
---|
70 | const char *key;
|
---|
71 | mrb_get_args(mrb, "S", &name);
|
---|
72 | key = mrb_str_to_cstr(mrb, name);
|
---|
73 | if (getenv(key) != NULL) {
|
---|
74 | return mrb_true_value();
|
---|
75 | } else {
|
---|
76 | return mrb_false_value();
|
---|
77 | }
|
---|
78 | }
|
---|
79 |
|
---|
80 | mrb_value
|
---|
81 | mrb_env_keys(mrb_state *mrb, mrb_value self)
|
---|
82 | {
|
---|
83 | int i;
|
---|
84 | mrb_value ary;
|
---|
85 |
|
---|
86 | ary = mrb_ary_new(mrb);
|
---|
87 | for (i = 0; environ[i] != NULL; i++) {
|
---|
88 | char *str = strchr(environ[i], '=');
|
---|
89 | if (str != NULL) {
|
---|
90 | int len = str - environ[i];
|
---|
91 | mrb_ary_push(mrb, ary, mrb_str_new(mrb, environ[i], len));
|
---|
92 | }
|
---|
93 | }
|
---|
94 |
|
---|
95 | return ary;
|
---|
96 | }
|
---|
97 |
|
---|
98 | mrb_value
|
---|
99 | mrb_env_values(mrb_state *mrb, mrb_value self)
|
---|
100 | {
|
---|
101 | int i;
|
---|
102 | mrb_value ary;
|
---|
103 |
|
---|
104 | ary = mrb_ary_new(mrb);
|
---|
105 | for (i = 0; environ[i] != NULL; i++) {
|
---|
106 | char *str = strchr(environ[i], '=');
|
---|
107 | if (str) {
|
---|
108 | int len;
|
---|
109 | str++;
|
---|
110 | len = strlen(str);
|
---|
111 | mrb_ary_push(mrb, ary, mrb_str_new(mrb, str, len));
|
---|
112 | }
|
---|
113 | }
|
---|
114 |
|
---|
115 | return ary;
|
---|
116 | }
|
---|
117 |
|
---|
118 | static mrb_value
|
---|
119 | mrb_env_size(mrb_state *mrb, mrb_value self)
|
---|
120 | {
|
---|
121 | int i;
|
---|
122 |
|
---|
123 | for (i = 0; environ[i] != NULL; i++)
|
---|
124 | ;
|
---|
125 |
|
---|
126 | return mrb_fixnum_value(i);
|
---|
127 | }
|
---|
128 |
|
---|
129 | static mrb_value
|
---|
130 | mrb_env_to_hash(mrb_state *mrb, mrb_value self)
|
---|
131 | {
|
---|
132 | int i;
|
---|
133 | mrb_value hash;
|
---|
134 |
|
---|
135 | hash = mrb_hash_new(mrb);
|
---|
136 | for (i = 0; environ[i] != NULL; i++) {
|
---|
137 | char *str = strchr(environ[i], '=');
|
---|
138 | if (str != NULL) {
|
---|
139 | mrb_value val;
|
---|
140 | int ai = mrb_gc_arena_save(mrb);
|
---|
141 | int len = str - environ[i];
|
---|
142 | mrb_value key = mrb_str_new(mrb, environ[i], len);
|
---|
143 | str++;
|
---|
144 | val = mrb_str_new(mrb, str, strlen(str));
|
---|
145 | mrb_hash_set(mrb, hash, key, val);
|
---|
146 | mrb_gc_arena_restore(mrb, ai);
|
---|
147 | }
|
---|
148 | }
|
---|
149 |
|
---|
150 | return hash;
|
---|
151 | }
|
---|
152 |
|
---|
153 | static mrb_value
|
---|
154 | mrb_env_to_a(mrb_state *mrb, mrb_value self)
|
---|
155 | {
|
---|
156 | int i;
|
---|
157 | mrb_value ary;
|
---|
158 |
|
---|
159 | ary = mrb_ary_new(mrb);
|
---|
160 | for (i = 0; environ[i] != NULL; i++) {
|
---|
161 | char *str = strchr(environ[i], '=');
|
---|
162 | if (str != NULL) {
|
---|
163 | int ai = mrb_gc_arena_save(mrb);
|
---|
164 | mrb_value elem = mrb_ary_new(mrb);
|
---|
165 | int len = str - environ[i];
|
---|
166 | mrb_ary_push(mrb, elem, mrb_str_new(mrb, environ[i], len));
|
---|
167 | str++;
|
---|
168 | mrb_ary_push(mrb, elem, mrb_str_new(mrb, str, strlen(str)));
|
---|
169 | mrb_ary_push(mrb, ary, elem);
|
---|
170 | mrb_gc_arena_restore(mrb, ai);
|
---|
171 | }
|
---|
172 | }
|
---|
173 |
|
---|
174 | return ary;
|
---|
175 | }
|
---|
176 |
|
---|
177 | static mrb_value
|
---|
178 | mrb_env_inspect(mrb_state *mrb, mrb_value self)
|
---|
179 | {
|
---|
180 | mrb_value hash = mrb_env_to_hash(mrb, self);
|
---|
181 | return mrb_funcall(mrb, hash, "inspect", 0);
|
---|
182 | }
|
---|
183 |
|
---|
184 | static mrb_value
|
---|
185 | mrb_env_to_s(mrb_state *mrb, mrb_value self)
|
---|
186 | {
|
---|
187 | return mrb_str_new_cstr(mrb, "ENV");
|
---|
188 | }
|
---|
189 |
|
---|
190 | static mrb_value
|
---|
191 | mrb_env_aset(mrb_state *mrb, mrb_value self)
|
---|
192 | {
|
---|
193 | mrb_value name, value;
|
---|
194 | const char *cname, *cvalue;
|
---|
195 |
|
---|
196 | mrb_get_args(mrb, "So", &name, &value);
|
---|
197 | cname = mrb_string_value_cstr(mrb, &name);
|
---|
198 |
|
---|
199 | if (mrb_nil_p(value)) {
|
---|
200 | if (unsetenv(cname) != 0) {
|
---|
201 | mrb_raise(mrb, E_RUNTIME_ERROR, "can't delete environment variable");
|
---|
202 | }
|
---|
203 | } else {
|
---|
204 | mrb_convert_type(mrb, value, MRB_TT_STRING, "String", "to_str");
|
---|
205 | cvalue = mrb_string_value_cstr(mrb, &value);
|
---|
206 | if (setenv(cname, cvalue, 1) != 0) {
|
---|
207 | mrb_raise(mrb, E_RUNTIME_ERROR, "can't change environment variable");
|
---|
208 | }
|
---|
209 | }
|
---|
210 | return value;
|
---|
211 | }
|
---|
212 |
|
---|
213 | void
|
---|
214 | mrb_mruby_env_gem_init(mrb_state *mrb)
|
---|
215 | {
|
---|
216 | struct RObject *e;
|
---|
217 |
|
---|
218 | e = (struct RObject*) mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
|
---|
219 | #if defined(MRUBY_RELEASE_NO) && MRUBY_RELEASE_NO >= 10000
|
---|
220 | mrb_include_module(mrb, (struct RClass*)e, mrb_module_get(mrb, "Enumerable"));
|
---|
221 | #else
|
---|
222 | mrb_include_module(mrb, (struct RClass*)e, mrb_class_get(mrb, "Enumerable"));
|
---|
223 | #endif
|
---|
224 |
|
---|
225 | mrb_define_singleton_method(mrb, e,"[]", mrb_env_aget, MRB_ARGS_REQ(1));
|
---|
226 | mrb_define_singleton_method(mrb, e,"[]=", mrb_env_aset, MRB_ARGS_REQ(2));
|
---|
227 | mrb_define_singleton_method(mrb, e,"has_key?", mrb_env_has_key, MRB_ARGS_REQ(1));
|
---|
228 | mrb_define_singleton_method(mrb, e,"inspect", mrb_env_inspect, MRB_ARGS_NONE());
|
---|
229 | mrb_define_singleton_method(mrb, e,"keys", mrb_env_keys, MRB_ARGS_NONE());
|
---|
230 | mrb_define_singleton_method(mrb, e,"size", mrb_env_size, MRB_ARGS_NONE());
|
---|
231 | mrb_define_singleton_method(mrb, e,"store", mrb_env_aset, MRB_ARGS_REQ(2));
|
---|
232 | mrb_define_singleton_method(mrb, e,"to_a", mrb_env_to_a, MRB_ARGS_NONE());
|
---|
233 | mrb_define_singleton_method(mrb, e,"to_hash", mrb_env_to_hash, MRB_ARGS_NONE());
|
---|
234 | mrb_define_singleton_method(mrb, e,"to_s", mrb_env_to_s, MRB_ARGS_NONE());
|
---|
235 | mrb_define_singleton_method(mrb, e,"values", mrb_env_values, MRB_ARGS_NONE());
|
---|
236 |
|
---|
237 | mrb_define_global_const(mrb, "ENV", mrb_obj_value(e));
|
---|
238 | }
|
---|
239 |
|
---|
240 | void
|
---|
241 | mrb_mruby_env_gem_final(mrb_state *mrb)
|
---|
242 | {
|
---|
243 | }
|
---|