1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
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.
24 #include <sys/types.h>
34 #include <TargetConditionals.h>
35 #include <mach/mach_time.h>
37 #if !(TARGET_OS_IPHONE)
38 #include <crt_externs.h>
42 /* Foreign builtins. */
43 //include valgrind.h after stdint.h so that uintptr_t is defined for msys2 w64
45 #include "valgrind/valgrind.h"
50 rust_list_dir_val(struct dirent* entry_ptr) {
51 return entry_ptr->d_name;
55 rust_dir_get_mode(struct dirent* entry_ptr) {
56 #if defined(_DIRENT_HAVE_D_TYPE)
57 switch (entry_ptr->d_type) {
58 case DT_BLK: return S_IFBLK;
59 case DT_CHR: return S_IFCHR;
60 case DT_FIFO: return S_IFIFO;
61 case DT_LNK: return S_IFLNK;
62 case DT_REG: return S_IFREG;
63 case DT_SOCK: return S_IFSOCK;
70 rust_dir_get_ino(struct dirent* entry_ptr) {
71 return entry_ptr->d_ino;
75 rust_opendir(char *dirname) {
76 return opendir(dirname);
80 rust_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
81 return readdir_r(dirp, entry, result);
85 rust_dirent_t_size() {
86 return sizeof(struct dirent);
94 GetSystemInfo(&sysinfo);
96 return (int) sysinfo.dwNumberOfProcessors;
98 #elif defined(__BSD__)
101 /* swiped from http://stackoverflow.com/questions/150355/
102 programmatically-find-the-number-of-cores-on-a-machine */
106 size_t len = sizeof(numCPU);
108 /* set the mib for hw.ncpu */
110 mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU;
112 /* get the number of CPUs from the system */
113 sysctl(mib, 2, &numCPU, &len, NULL, 0);
117 sysctl( mib, 2, &numCPU, &len, NULL, 0 );
125 #elif defined(__GNUC__)
128 return sysconf(_SC_NPROCESSORS_ONLN);
133 rust_get_num_cpus() {
134 return get_num_cpus();
138 rust_running_on_valgrind() {
142 return RUNNING_ON_VALGRIND;
146 #if defined(__DragonFly__)
148 // In DragonFly __error() is an inline function and as such
149 // no symbol exists for it.
150 int *__dfly_error(void) { return __error(); }
153 #if defined(__Bitrig__)
155 #include <sys/param.h>
156 #include <sys/sysctl.h>
159 int rust_get_path(void *p, size_t* sz)
170 if ((p == NULL) && (sz == NULL))
173 /* get the argv array */
175 mib[1] = KERN_PROC_ARGS;
177 mib[3] = KERN_PROC_ENV;
179 /* get the number of bytes needed to get the env */
181 if (sysctl(mib, 4, NULL, &maxlen, NULL, 0) == -1)
184 /* allocate the buffer */
185 if ((menv = calloc(maxlen, sizeof(char))) == NULL)
188 /* get the env array */
189 if (sysctl(mib, 4, menv, &maxlen, NULL, 0) == -1)
195 mib[3] = KERN_PROC_NENV;
197 /* get the length of env array */
198 if (sysctl(mib, 4, &nenv, &len, NULL, 0) == -1)
204 /* find _ key and resolve the value */
205 for (i = 0; i < nenv; i++)
207 if ((eq = strstr(menv[i], "=")) == NULL)
214 if (strncmp(key, "PATH", maxlen) != 0)
219 /* return the length of the value + NUL */
220 *sz = strnlen(val, maxlen) + 1;
226 /* copy *sz bytes to the output buffer */
237 int rust_get_path_array(void * p, size_t * sz)
244 if ((p == NULL) && (sz == NULL))
247 /* get the length of the PATH value */
248 if (rust_get_path(NULL, &len) == -1)
254 /* allocate the buffer */
255 if ((path = calloc(len, sizeof(char))) == NULL)
258 /* get the PATH value */
259 if (rust_get_path(path, &len) == -1)
265 /* count the number of parts in the PATH */
267 for(str = path; *str != '\0'; str++)
273 /* calculate the size of the buffer for the 2D array */
274 len = (num * sizeof(char*) + 1) + strlen(path) + 1;
283 /* make sure we have enough buffer space */
290 /* zero out the buffer */
294 /* copy the data into the right place */
295 str = p + ((num+1) * sizeof(char*));
296 memcpy(str, path, strlen(path));
298 /* parse the path into it's parts */
299 for (i = 0; i < num && (buf[i] = strsep(&str, ":")) != NULL; i++) {;}
306 int rust_get_argv_zero(void* p, size_t* sz)
312 if ((p == NULL) && (sz == NULL))
315 /* get the argv array */
317 mib[1] = KERN_PROC_ARGS;
319 mib[3] = KERN_PROC_ARGV;
321 /* request KERN_PROC_ARGV size */
323 if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
326 /* allocate buffer to receive the values */
327 if ((argv = malloc(len)) == NULL)
330 /* get the argv array */
331 if (sysctl(mib, 4, argv, &len, NULL, 0) == -1)
337 /* get length of argv[0] */
338 len = strnlen(argv[0], len) + 1;
354 memcpy(p, argv[0], len);
359 const char * rust_current_exe()
361 static char *self = NULL;
366 char buf[2*PATH_MAX], exe[2*PATH_MAX];
371 if (rust_get_argv_zero(NULL, &sz) == -1)
373 if ((argv0 = calloc(sz, sizeof(char))) == NULL)
375 if (rust_get_argv_zero(argv0, &sz) == -1)
381 /* if argv0 is a relative or absolute path, resolve it with realpath */
382 if ((*argv0 == '.') || (*argv0 == '/') || (strstr(argv0, "/") != NULL))
384 self = realpath(argv0, NULL);
389 /* get the path array */
390 if (rust_get_path_array(NULL, &sz) == -1)
395 if ((paths = calloc(sz, sizeof(char))) == NULL)
400 if (rust_get_path_array(paths, &sz) == -1)
407 for(i = 0; paths[i] != NULL; i++)
409 snprintf(buf, 2*PATH_MAX, "%s/%s", paths[i], argv0);
410 if (realpath(buf, exe) == NULL)
413 if (access(exe, F_OK | X_OK) == -1)
427 #elif defined(__OpenBSD__)
429 #include <sys/param.h>
430 #include <sys/sysctl.h>
433 const char * rust_current_exe() {
434 static char *self = NULL;
443 mib[1] = KERN_PROC_ARGS;
445 mib[3] = KERN_PROC_ARGV;
447 /* request KERN_PROC_ARGV size */
449 if (sysctl(mib, 4, NULL, &argv_len, NULL, 0) == -1)
453 if ((argv = malloc(argv_len)) == NULL)
456 /* request KERN_PROC_ARGV */
457 if (sysctl(mib, 4, argv, &argv_len, NULL, 0) == -1) {
462 /* get realpath if possible */
463 if ((argv[0] != NULL) && ((*argv[0] == '.') || (*argv[0] == '/')
464 || (strstr(argv[0], "/") != NULL)))
466 self = realpath(argv[0], NULL);
483 // indent-tabs-mode: nil
485 // buffer-file-coding-system: utf-8-unix