]> git.proxmox.com Git - rustc.git/blame - src/rt/rust_builtin.c
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / rt / rust_builtin.c
CommitLineData
85aaf69f 1// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
1a4d82fc
JJ
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
c1a9b12d
SL
11#if !defined(_WIN32)
12
1a4d82fc
JJ
13#include <stdint.h>
14#include <time.h>
15#include <string.h>
16#include <assert.h>
17#include <stdlib.h>
18
62682a34 19
1a4d82fc 20#include <dirent.h>
d9579d0f 21#include <pthread.h>
1a4d82fc 22#include <signal.h>
d9579d0f
AL
23#include <sys/stat.h>
24#include <sys/time.h>
25#include <sys/types.h>
1a4d82fc 26#include <unistd.h>
1a4d82fc
JJ
27
28#ifdef __APPLE__
29#include <TargetConditionals.h>
30#include <mach/mach_time.h>
31
32#if !(TARGET_OS_IPHONE)
33#include <crt_externs.h>
34#endif
35#endif
36
1a4d82fc 37char*
1a4d82fc
JJ
38rust_list_dir_val(struct dirent* entry_ptr) {
39 return entry_ptr->d_name;
40}
d9579d0f
AL
41
42int
43rust_dir_get_mode(struct dirent* entry_ptr) {
62682a34 44#if defined(_DIRENT_HAVE_D_TYPE) || defined(__APPLE__)
d9579d0f
AL
45 switch (entry_ptr->d_type) {
46 case DT_BLK: return S_IFBLK;
47 case DT_CHR: return S_IFCHR;
48 case DT_FIFO: return S_IFIFO;
49 case DT_LNK: return S_IFLNK;
50 case DT_REG: return S_IFREG;
51 case DT_SOCK: return S_IFSOCK;
62682a34 52 case DT_DIR: return S_IFDIR;
d9579d0f 53 }
1a4d82fc 54#endif
d9579d0f
AL
55 return -1;
56}
1a4d82fc 57
d9579d0f
AL
58ino_t
59rust_dir_get_ino(struct dirent* entry_ptr) {
60 return entry_ptr->d_ino;
61}
1a4d82fc
JJ
62
63DIR*
64rust_opendir(char *dirname) {
65 return opendir(dirname);
66}
67
68int
69rust_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
70 return readdir_r(dirp, entry, result);
71}
72
73int
74rust_dirent_t_size() {
75 return sizeof(struct dirent);
76}
1a4d82fc 77
c1a9b12d 78#if defined(__BSD__)
1a4d82fc
JJ
79int
80get_num_cpus() {
81 /* swiped from http://stackoverflow.com/questions/150355/
82 programmatically-find-the-number-of-cores-on-a-machine */
83
84 unsigned int numCPU;
85 int mib[4];
86 size_t len = sizeof(numCPU);
87
88 /* set the mib for hw.ncpu */
89 mib[0] = CTL_HW;
90 mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU;
91
92 /* get the number of CPUs from the system */
93 sysctl(mib, 2, &numCPU, &len, NULL, 0);
94
95 if( numCPU < 1 ) {
96 mib[1] = HW_NCPU;
97 sysctl( mib, 2, &numCPU, &len, NULL, 0 );
98
99 if( numCPU < 1 ) {
100 numCPU = 1;
101 }
102 }
103 return numCPU;
104}
105#elif defined(__GNUC__)
106int
107get_num_cpus() {
108 return sysconf(_SC_NPROCESSORS_ONLN);
109}
110#endif
111
112uintptr_t
113rust_get_num_cpus() {
114 return get_num_cpus();
115}
116
1a4d82fc
JJ
117#if defined(__DragonFly__)
118#include <errno.h>
119// In DragonFly __error() is an inline function and as such
120// no symbol exists for it.
121int *__dfly_error(void) { return __error(); }
122#endif
123
c34b1796
AL
124#if defined(__Bitrig__)
125#include <stdio.h>
126#include <sys/param.h>
127#include <sys/sysctl.h>
128#include <limits.h>
129
130int rust_get_path(void *p, size_t* sz)
131{
132 int mib[4];
133 char *eq = NULL;
134 char *key = NULL;
135 char *val = NULL;
136 char **menv = NULL;
137 size_t maxlen, len;
138 int nenv = 0;
139 int i;
140
141 if ((p == NULL) && (sz == NULL))
142 return -1;
143
144 /* get the argv array */
145 mib[0] = CTL_KERN;
146 mib[1] = KERN_PROC_ARGS;
147 mib[2] = getpid();
148 mib[3] = KERN_PROC_ENV;
149
150 /* get the number of bytes needed to get the env */
151 maxlen = 0;
152 if (sysctl(mib, 4, NULL, &maxlen, NULL, 0) == -1)
153 return -1;
154
155 /* allocate the buffer */
156 if ((menv = calloc(maxlen, sizeof(char))) == NULL)
157 return -1;
158
159 /* get the env array */
160 if (sysctl(mib, 4, menv, &maxlen, NULL, 0) == -1)
161 {
162 free(menv);
163 return -1;
164 }
165
166 mib[3] = KERN_PROC_NENV;
167 len = sizeof(int);
168 /* get the length of env array */
169 if (sysctl(mib, 4, &nenv, &len, NULL, 0) == -1)
170 {
171 free(menv);
172 return -1;
173 }
174
175 /* find _ key and resolve the value */
176 for (i = 0; i < nenv; i++)
177 {
178 if ((eq = strstr(menv[i], "=")) == NULL)
179 continue;
180
181 key = menv[i];
182 val = eq + 1;
183 *eq = '\0';
184
185 if (strncmp(key, "PATH", maxlen) != 0)
186 continue;
187
188 if (p == NULL)
189 {
190 /* return the length of the value + NUL */
191 *sz = strnlen(val, maxlen) + 1;
192 free(menv);
193 return 0;
194 }
195 else
196 {
197 /* copy *sz bytes to the output buffer */
198 memcpy(p, val, *sz);
199 free(menv);
200 return 0;
201 }
202 }
203
204 free(menv);
205 return -1;
206}
207
208int rust_get_path_array(void * p, size_t * sz)
209{
210 char *path, *str;
211 char **buf;
212 int i, num;
213 size_t len;
214
215 if ((p == NULL) && (sz == NULL))
216 return -1;
217
218 /* get the length of the PATH value */
219 if (rust_get_path(NULL, &len) == -1)
220 return -1;
221
222 if (len == 0)
223 return -1;
224
225 /* allocate the buffer */
226 if ((path = calloc(len, sizeof(char))) == NULL)
227 return -1;
228
229 /* get the PATH value */
230 if (rust_get_path(path, &len) == -1)
231 {
232 free(path);
233 return -1;
234 }
235
236 /* count the number of parts in the PATH */
237 num = 1;
238 for(str = path; *str != '\0'; str++)
239 {
240 if (*str == ':')
241 num++;
242 }
243
244 /* calculate the size of the buffer for the 2D array */
245 len = (num * sizeof(char*) + 1) + strlen(path) + 1;
246
247 if (p == NULL)
248 {
249 free(path);
250 *sz = len;
251 return 0;
252 }
253
254 /* make sure we have enough buffer space */
255 if (*sz < len)
256 {
257 free(path);
258 return -1;
259 }
260
261 /* zero out the buffer */
262 buf = (char**)p;
263 memset(buf, 0, *sz);
264
265 /* copy the data into the right place */
266 str = p + ((num+1) * sizeof(char*));
267 memcpy(str, path, strlen(path));
268
269 /* parse the path into it's parts */
270 for (i = 0; i < num && (buf[i] = strsep(&str, ":")) != NULL; i++) {;}
271 buf[num] = NULL;
272
273 free(path);
274 return 0;
275}
276
277int rust_get_argv_zero(void* p, size_t* sz)
278{
279 int mib[4];
280 char **argv = NULL;
281 size_t len;
282
283 if ((p == NULL) && (sz == NULL))
284 return -1;
285
286 /* get the argv array */
287 mib[0] = CTL_KERN;
288 mib[1] = KERN_PROC_ARGS;
289 mib[2] = getpid();
290 mib[3] = KERN_PROC_ARGV;
291
292 /* request KERN_PROC_ARGV size */
293 len = 0;
294 if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
295 return -1;
296
297 /* allocate buffer to receive the values */
298 if ((argv = malloc(len)) == NULL)
299 return -1;
300
301 /* get the argv array */
302 if (sysctl(mib, 4, argv, &len, NULL, 0) == -1)
303 {
304 free(argv);
305 return -1;
306 }
307
308 /* get length of argv[0] */
309 len = strnlen(argv[0], len) + 1;
310
311 if (p == NULL)
312 {
313 *sz = len;
314 free(argv);
315 return 0;
316 }
317
318 if (*sz < len)
319 {
320 free(argv);
321 return -1;
322 }
323
324 memset(p, 0, len);
325 memcpy(p, argv[0], len);
326 free(argv);
327 return 0;
328}
329
330const char * rust_current_exe()
331{
332 static char *self = NULL;
333 char *argv0;
334 char **paths;
335 size_t sz;
336 int i;
337 char buf[2*PATH_MAX], exe[2*PATH_MAX];
338
339 if (self != NULL)
340 return self;
341
342 if (rust_get_argv_zero(NULL, &sz) == -1)
343 return NULL;
344 if ((argv0 = calloc(sz, sizeof(char))) == NULL)
345 return NULL;
346 if (rust_get_argv_zero(argv0, &sz) == -1)
347 {
348 free(argv0);
349 return NULL;
350 }
351
352 /* if argv0 is a relative or absolute path, resolve it with realpath */
353 if ((*argv0 == '.') || (*argv0 == '/') || (strstr(argv0, "/") != NULL))
354 {
355 self = realpath(argv0, NULL);
356 free(argv0);
357 return self;
358 }
359
360 /* get the path array */
361 if (rust_get_path_array(NULL, &sz) == -1)
362 {
363 free(argv0);
364 return NULL;
365 }
366 if ((paths = calloc(sz, sizeof(char))) == NULL)
367 {
368 free(argv0);
369 return NULL;
370 }
371 if (rust_get_path_array(paths, &sz) == -1)
372 {
373 free(argv0);
374 free(paths);
375 return NULL;
376 }
377
378 for(i = 0; paths[i] != NULL; i++)
379 {
380 snprintf(buf, 2*PATH_MAX, "%s/%s", paths[i], argv0);
381 if (realpath(buf, exe) == NULL)
382 continue;
383
384 if (access(exe, F_OK | X_OK) == -1)
385 continue;
386
387 self = strdup(exe);
388 free(argv0);
389 free(paths);
390 return self;
391 }
392
393 free(argv0);
394 free(paths);
395 return NULL;
396}
397
398#elif defined(__OpenBSD__)
399
85aaf69f
SL
400#include <sys/param.h>
401#include <sys/sysctl.h>
402#include <limits.h>
403
404const char * rust_current_exe() {
405 static char *self = NULL;
406
407 if (self == NULL) {
408 int mib[4];
409 char **argv = NULL;
410 size_t argv_len;
411
412 /* initialize mib */
413 mib[0] = CTL_KERN;
414 mib[1] = KERN_PROC_ARGS;
415 mib[2] = getpid();
416 mib[3] = KERN_PROC_ARGV;
417
418 /* request KERN_PROC_ARGV size */
419 argv_len = 0;
420 if (sysctl(mib, 4, NULL, &argv_len, NULL, 0) == -1)
421 return (NULL);
422
423 /* allocate size */
424 if ((argv = malloc(argv_len)) == NULL)
425 return (NULL);
426
427 /* request KERN_PROC_ARGV */
428 if (sysctl(mib, 4, argv, &argv_len, NULL, 0) == -1) {
429 free(argv);
430 return (NULL);
431 }
432
433 /* get realpath if possible */
434 if ((argv[0] != NULL) && ((*argv[0] == '.') || (*argv[0] == '/')
435 || (strstr(argv[0], "/") != NULL)))
436
437 self = realpath(argv[0], NULL);
438 else
439 self = NULL;
440
441 /* cleanup */
442 free(argv);
443 }
444
445 return (self);
446}
c34b1796 447
85aaf69f
SL
448#endif
449
c1a9b12d
SL
450#endif // !defined(_WIN32)
451
1a4d82fc
JJ
452//
453// Local Variables:
454// mode: C++
455// fill-column: 78;
456// indent-tabs-mode: nil
457// c-basic-offset: 4
458// buffer-file-coding-system: utf-8-unix
459// End:
460//