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.
25 #include <sys/types.h>
29 #include <TargetConditionals.h>
30 #include <mach/mach_time.h>
32 #if !(TARGET_OS_IPHONE)
33 #include <crt_externs.h>
38 rust_list_dir_val(struct dirent* entry_ptr) {
39 return entry_ptr->d_name;
42 // Android's struct dirent does have d_type from the very beginning
43 // (android-3). _DIRENT_HAVE_D_TYPE is not defined all the way to android-21
45 #if defined(__ANDROID__)
46 # define _DIRENT_HAVE_D_TYPE
50 rust_dir_get_mode(struct dirent* entry_ptr) {
51 #if defined(_DIRENT_HAVE_D_TYPE) || defined(__APPLE__)
52 switch (entry_ptr->d_type) {
53 case DT_BLK: return S_IFBLK;
54 case DT_CHR: return S_IFCHR;
55 case DT_FIFO: return S_IFIFO;
56 case DT_LNK: return S_IFLNK;
57 case DT_REG: return S_IFREG;
58 case DT_SOCK: return S_IFSOCK;
59 case DT_DIR: return S_IFDIR;
66 rust_dir_get_ino(struct dirent* entry_ptr) {
67 return entry_ptr->d_ino;
71 rust_opendir(char *dirname) {
72 return opendir(dirname);
76 rust_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
77 return readdir_r(dirp, entry, result);
81 rust_dirent_t_size() {
82 return sizeof(struct dirent);
88 /* swiped from http://stackoverflow.com/questions/150355/
89 programmatically-find-the-number-of-cores-on-a-machine */
93 size_t len = sizeof(numCPU);
95 /* set the mib for hw.ncpu */
97 mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU;
99 /* get the number of CPUs from the system */
100 sysctl(mib, 2, &numCPU, &len, NULL, 0);
104 sysctl( mib, 2, &numCPU, &len, NULL, 0 );
112 #elif defined(__GNUC__)
115 return sysconf(_SC_NPROCESSORS_ONLN);
120 rust_get_num_cpus() {
121 return get_num_cpus();
124 #if defined(__DragonFly__)
126 // In DragonFly __error() is an inline function and as such
127 // no symbol exists for it.
128 int *__dfly_error(void) { return __error(); }
131 #if defined(__Bitrig__)
133 #include <sys/param.h>
134 #include <sys/sysctl.h>
137 int rust_get_path(void *p, size_t* sz)
148 if ((p == NULL) && (sz == NULL))
151 /* get the argv array */
153 mib[1] = KERN_PROC_ARGS;
155 mib[3] = KERN_PROC_ENV;
157 /* get the number of bytes needed to get the env */
159 if (sysctl(mib, 4, NULL, &maxlen, NULL, 0) == -1)
162 /* allocate the buffer */
163 if ((menv = calloc(maxlen, sizeof(char))) == NULL)
166 /* get the env array */
167 if (sysctl(mib, 4, menv, &maxlen, NULL, 0) == -1)
173 mib[3] = KERN_PROC_NENV;
175 /* get the length of env array */
176 if (sysctl(mib, 4, &nenv, &len, NULL, 0) == -1)
182 /* find _ key and resolve the value */
183 for (i = 0; i < nenv; i++)
185 if ((eq = strstr(menv[i], "=")) == NULL)
192 if (strncmp(key, "PATH", maxlen) != 0)
197 /* return the length of the value + NUL */
198 *sz = strnlen(val, maxlen) + 1;
204 /* copy *sz bytes to the output buffer */
215 int rust_get_path_array(void * p, size_t * sz)
222 if ((p == NULL) && (sz == NULL))
225 /* get the length of the PATH value */
226 if (rust_get_path(NULL, &len) == -1)
232 /* allocate the buffer */
233 if ((path = calloc(len, sizeof(char))) == NULL)
236 /* get the PATH value */
237 if (rust_get_path(path, &len) == -1)
243 /* count the number of parts in the PATH */
245 for(str = path; *str != '\0'; str++)
251 /* calculate the size of the buffer for the 2D array */
252 len = (num * sizeof(char*) + 1) + strlen(path) + 1;
261 /* make sure we have enough buffer space */
268 /* zero out the buffer */
272 /* copy the data into the right place */
273 str = p + ((num+1) * sizeof(char*));
274 memcpy(str, path, strlen(path));
276 /* parse the path into it's parts */
277 for (i = 0; i < num && (buf[i] = strsep(&str, ":")) != NULL; i++) {;}
284 int rust_get_argv_zero(void* p, size_t* sz)
290 if ((p == NULL) && (sz == NULL))
293 /* get the argv array */
295 mib[1] = KERN_PROC_ARGS;
297 mib[3] = KERN_PROC_ARGV;
299 /* request KERN_PROC_ARGV size */
301 if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
304 /* allocate buffer to receive the values */
305 if ((argv = malloc(len)) == NULL)
308 /* get the argv array */
309 if (sysctl(mib, 4, argv, &len, NULL, 0) == -1)
315 /* get length of argv[0] */
316 len = strnlen(argv[0], len) + 1;
331 memcpy(p, argv[0], len);
336 const char * rust_current_exe()
338 static char *self = NULL;
343 /* If `PATH_MAX` is defined on the platform, `realpath` will truncate the
344 * resolved path up to `PATH_MAX`. While this can make the resolution fail if
345 * the executable is placed in a deep path, the usage of a buffer whose
346 * length depends on `PATH_MAX` is still memory safe. */
347 char buf[2*PATH_MAX], exe[PATH_MAX];
352 if (rust_get_argv_zero(NULL, &sz) == -1)
354 if ((argv0 = calloc(sz, sizeof(char))) == NULL)
356 if (rust_get_argv_zero(argv0, &sz) == -1)
362 /* if argv0 is a relative or absolute path, resolve it with realpath */
363 if ((*argv0 == '.') || (*argv0 == '/') || (strstr(argv0, "/") != NULL))
365 self = realpath(argv0, NULL);
370 /* get the path array */
371 if (rust_get_path_array(NULL, &sz) == -1)
376 if ((paths = calloc(sz, sizeof(char))) == NULL)
381 if (rust_get_path_array(paths, &sz) == -1)
388 for(i = 0; paths[i] != NULL; i++)
390 snprintf(buf, 2*PATH_MAX, "%s/%s", paths[i], argv0);
391 if (realpath(buf, exe) == NULL)
394 if (access(exe, F_OK | X_OK) == -1)
408 #elif defined(__OpenBSD__)
410 #include <sys/param.h>
411 #include <sys/sysctl.h>
414 const char * rust_current_exe() {
415 static char *self = NULL;
424 mib[1] = KERN_PROC_ARGS;
426 mib[3] = KERN_PROC_ARGV;
428 /* request KERN_PROC_ARGV size */
430 if (sysctl(mib, 4, NULL, &argv_len, NULL, 0) == -1)
434 if ((argv = malloc(argv_len)) == NULL)
437 /* request KERN_PROC_ARGV */
438 if (sysctl(mib, 4, argv, &argv_len, NULL, 0) == -1) {
443 /* get realpath if possible */
444 if ((argv[0] != NULL) && ((*argv[0] == '.') || (*argv[0] == '/')
445 || (strstr(argv[0], "/") != NULL)))
447 self = realpath(argv[0], NULL);
460 #endif // !defined(_WIN32)
466 // indent-tabs-mode: nil
468 // buffer-file-coding-system: utf-8-unix