diff --git a/mk/crates.mk b/mk/crates.mk index 2b66baed45b..2597c724da9 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -71,7 +71,7 @@ DEPS_rustc_bitflags := core DEPS_rustc_unicode := core DEPS_std := core libc rand alloc collections rustc_unicode \ - native:rust_builtin native:backtrace \ + native:backtrace \ alloc_system DEPS_arena := std DEPS_glob := std diff --git a/mk/rt.mk b/mk/rt.mk index 9d12bf39825..9dbbcbebb97 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -35,7 +35,7 @@ # that's per-target so you're allowed to conditionally add files based on the # target. ################################################################################ -NATIVE_LIBS := rust_builtin hoedown miniz rust_test_helpers +NATIVE_LIBS := hoedown miniz rust_test_helpers # $(1) is the target triple define NATIVE_LIBRARIES @@ -50,8 +50,6 @@ NATIVE_DEPS_hoedown_$(1) := hoedown/src/autolink.c \ hoedown/src/stack.c \ hoedown/src/version.c NATIVE_DEPS_miniz_$(1) = miniz.c -NATIVE_DEPS_rust_builtin_$(1) := rust_builtin.c \ - rust_android_dummy.c NATIVE_DEPS_rust_test_helpers_$(1) := rust_test_helpers.c ################################################################################ diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index 413eac3cf79..eaaa9391d31 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -108,3 +108,14 @@ pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize { let flags = align_to_flags(align); unsafe { je_nallocx(size as size_t, flags) as usize } } + +// These symbols are used by jemalloc on android but the really old android +// we're building on doesn't have them defined, so just make sure the symbols +// are available. +#[no_mangle] +#[cfg(target_os = "android")] +pub extern fn pthread_atfork(_prefork: *mut u8, + _postfork_parent: *mut u8, + _postfork_child: *mut u8) -> i32 { + 0 +} diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs index 8383b3ec189..9b1046f39a7 100644 --- a/src/libstd/rtdeps.rs +++ b/src/libstd/rtdeps.rs @@ -12,11 +12,6 @@ //! the standard library This varies per-platform, but these libraries are //! necessary for running libstd. -// A few small shims in C that haven't been translated to Rust yet -#[cfg(all(not(test), not(windows)))] -#[link(name = "rust_builtin", kind = "static")] -extern {} - // LLVM implements the `frem` instruction as a call to `fmod`, which lives in // libm. Hence, we must explicitly link to it. // diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index e634c10d8b7..e8575a6c21c 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -14,7 +14,8 @@ use os::unix::prelude::*; use ffi::{CString, CStr, OsString, OsStr}; use fmt; use io::{self, Error, ErrorKind, SeekFrom}; -use libc::{self, c_int, off_t, c_char, mode_t}; +use libc::{dirent, readdir_r}; +use libc::{self, c_int, off_t, mode_t}; use mem; use path::{Path, PathBuf}; use ptr; @@ -43,7 +44,7 @@ unsafe impl Send for Dir {} unsafe impl Sync for Dir {} pub struct DirEntry { - buf: Vec, // actually *mut libc::dirent + entry: dirent, root: Arc, } @@ -126,32 +127,22 @@ impl Iterator for ReadDir { type Item = io::Result; fn next(&mut self) -> Option> { - extern { - fn rust_dirent_t_size() -> libc::size_t; - } - - let mut buf: Vec = Vec::with_capacity(unsafe { - rust_dirent_t_size() - }); - let ptr = buf.as_mut_ptr() as *mut libc::dirent; - - let mut entry_ptr = ptr::null_mut(); - loop { - if unsafe { libc::readdir_r(self.dirp.0, ptr, &mut entry_ptr) != 0 } { - return Some(Err(Error::last_os_error())) - } - if entry_ptr.is_null() { - return None - } - - let entry = DirEntry { - buf: buf, + unsafe { + let mut ret = DirEntry { + entry: mem::zeroed(), root: self.root.clone() }; - if entry.name_bytes() == b"." || entry.name_bytes() == b".." { - buf = entry.buf; - } else { - return Some(Ok(entry)) + let mut entry_ptr = ptr::null_mut(); + loop { + if readdir_r(self.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 { + return Some(Err(Error::last_os_error())) + } + if entry_ptr.is_null() { + return None + } + if ret.name_bytes() != b"." && ret.name_bytes() != b".." { + return Some(Ok(ret)) + } } } } @@ -166,7 +157,7 @@ impl Drop for Dir { impl DirEntry { pub fn path(&self) -> PathBuf { - self.root.join(::from_bytes(self.name_bytes())) + self.root.join(OsStr::from_bytes(self.name_bytes())) } pub fn file_name(&self) -> OsString { @@ -178,35 +169,64 @@ impl DirEntry { } pub fn file_type(&self) -> io::Result { - extern { - fn rust_dir_get_mode(ptr: *mut libc::dirent) -> c_int; - } - unsafe { - match rust_dir_get_mode(self.dirent()) { - -1 => lstat(&self.path()).map(|m| m.file_type()), - n => Ok(FileType { mode: n as mode_t }), - } + match self.entry.d_type { + libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }), + libc::DT_FIFO => Ok(FileType { mode: libc::S_IFIFO }), + libc::DT_LNK => Ok(FileType { mode: libc::S_IFLNK }), + libc::DT_REG => Ok(FileType { mode: libc::S_IFREG }), + libc::DT_SOCK => Ok(FileType { mode: libc::S_IFSOCK }), + libc::DT_DIR => Ok(FileType { mode: libc::S_IFDIR }), + libc::DT_BLK => Ok(FileType { mode: libc::S_IFBLK }), + _ => lstat(&self.path()).map(|m| m.file_type()), } } + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "linux"))] pub fn ino(&self) -> raw::ino_t { - extern { - fn rust_dir_get_ino(ptr: *mut libc::dirent) -> raw::ino_t; - } - unsafe { rust_dir_get_ino(self.dirent()) } + self.entry.d_ino } + #[cfg(target_os = "android")] + pub fn ino(&self) -> raw::ino_t { + self.entry.d_ino as raw::ino_t + } + + #[cfg(any(target_os = "freebsd", + target_os = "openbsd", + target_os = "bitrig", + target_os = "netbsd", + target_os = "dragonfly"))] + pub fn ino(&self) -> raw::ino_t { + self.entry.d_fileno + } + + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "netbsd"))] fn name_bytes(&self) -> &[u8] { - extern { - fn rust_list_dir_val(ptr: *mut libc::dirent) -> *const c_char; - } unsafe { - CStr::from_ptr(rust_list_dir_val(self.dirent())).to_bytes() + ::slice::from_raw_parts(self.entry.d_name.as_ptr() as *const u8, + self.entry.d_namlen as usize) } } - - fn dirent(&self) -> *mut libc::dirent { - self.buf.as_ptr() as *mut _ + #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", + target_os = "bitrig", + target_os = "openbsd"))] + fn name_bytes(&self) -> &[u8] { + unsafe { + ::slice::from_raw_parts(self.entry.d_name.as_ptr() as *const u8, + self.entry.d_namelen as usize) + } + } + #[cfg(any(target_os = "android", + target_os = "linux"))] + fn name_bytes(&self) -> &[u8] { + unsafe { + CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() + } } } diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 12b9d6191a0..c62960d74cb 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -38,12 +38,17 @@ static ENV_LOCK: StaticMutex = StaticMutex::new(); /// Returns the platform-specific value of errno pub fn errno() -> i32 { extern { - #[cfg_attr(any(target_os = "linux", target_os = "android"), link_name = "__errno_location")] - #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd", + #[cfg_attr(any(target_os = "linux"), link_name = "__errno_location")] + #[cfg_attr(any(target_os = "bitrig", + target_os = "netbsd", + target_os = "openbsd", + target_os = "android", target_env = "newlib"), link_name = "__errno")] #[cfg_attr(target_os = "dragonfly", link_name = "__dfly_error")] - #[cfg_attr(any(target_os = "macos", target_os = "ios", target_os = "freebsd"), + #[cfg_attr(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd"), link_name = "__error")] fn errno_location() -> *const c_int; } @@ -173,17 +178,19 @@ pub fn current_exe() -> io::Result { libc::KERN_PROC_PATHNAME as c_int, -1 as c_int]; let mut sz: libc::size_t = 0; - let err = libc::sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint, - ptr::null_mut(), &mut sz, ptr::null_mut(), - 0 as libc::size_t); - if err != 0 { return Err(io::Error::last_os_error()); } - if sz == 0 { return Err(io::Error::last_os_error()); } + try!(cvt(libc::sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint, + ptr::null_mut(), &mut sz, ptr::null_mut(), + 0 as libc::size_t))); + if sz == 0 { + return Err(io::Error::last_os_error()) + } let mut v: Vec = Vec::with_capacity(sz as usize); - let err = libc::sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint, - v.as_mut_ptr() as *mut libc::c_void, &mut sz, - ptr::null_mut(), 0 as libc::size_t); - if err != 0 { return Err(io::Error::last_os_error()); } - if sz == 0 { return Err(io::Error::last_os_error()); } + try!(cvt(libc::sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint, + v.as_mut_ptr() as *mut libc::c_void, &mut sz, + ptr::null_mut(), 0 as libc::size_t))); + if sz == 0 { + return Err(io::Error::last_os_error()); + } v.set_len(sz as usize - 1); // chop off trailing NUL Ok(PathBuf::from(OsString::from_vec(v))) } @@ -201,22 +208,28 @@ pub fn current_exe() -> io::Result { #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] pub fn current_exe() -> io::Result { - use sync::StaticMutex; - static LOCK: StaticMutex = StaticMutex::new(); - - extern { - fn rust_current_exe() -> *const c_char; - } - - let _guard = LOCK.lock(); - unsafe { - let v = rust_current_exe(); - if v.is_null() { - Err(io::Error::last_os_error()) + let mut mib = [libc::CTL_KERN, + libc::KERN_PROC_ARGS, + libc::getpid(), + libc::KERN_PROC_ARGV]; + let mib = mib.as_mut_ptr(); + let mut argv_len = 0; + try!(cvt(libc::sysctl(mib, 4, 0 as *mut _, &mut argv_len, + 0 as *mut _, 0))); + let mut argv = Vec::<*const libc::c_char>::with_capacity(argv_len as usize); + try!(cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, + &mut argv_len, 0 as *mut _, 0))); + argv.set_len(argv_len as usize); + if argv[0].is_null() { + return Err(io::Error::new(io::ErrorKind::Other, + "no current exe available")) + } + let argv0 = CStr::from_ptr(argv[0]).to_bytes(); + if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') { + ::fs::canonicalize(OsStr::from_bytes(argv0)) } else { - let vec = CStr::from_ptr(v).to_bytes().to_vec(); - Ok(PathBuf::from(OsString::from_vec(vec))) + Ok(PathBuf::from(OsStr::from_bytes(argv0))) } } } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 20d7c66cf12..a844bdf1351 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -906,10 +906,45 @@ fn get_concurrency() -> usize { } } - #[cfg(unix)] + #[cfg(any(target_os = "linux", + target_os = "macos", + target_os = "ios", + target_os = "android"))] fn num_cpus() -> usize { - extern { fn rust_get_num_cpus() -> libc::uintptr_t; } - unsafe { rust_get_num_cpus() as usize } + unsafe { + libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize + } + } + + #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", + target_os = "bitrig", + target_os = "openbsd", + target_os = "netbsd"))] + fn num_cpus() -> usize { + let mut cpus: libc::c_uint = 0; + let mut CPUS_SIZE = std::mem::size_of_val(&cpus); + let mut mib = [libc::CTL_HW, libc::HW_AVAILCPU, 0, 0]; + + unsafe { + libc::sysctl(mib.as_mut_ptr(), 2, + &mut cpus as *mut _ as *mut _, + &mut CPUS_SIZE as *mut _ as *mut _, + 0 as *mut _, 0); + } + if cpus < 1 { + mib[1] = HW_NCPU; + unsafe { + libc::sysctl(mib.as_mut_ptr(), 2, + &mut cpus as *mut _ as *mut _, + &mut CPUS_SIZE as *mut _ as *mut _, + 0 as *mut _, 0); + } + if cpus < 1 { + cpus = 1; + } + } + cpus as usize } } diff --git a/src/rt/rust_android_dummy.c b/src/rt/rust_android_dummy.c deleted file mode 100644 index c322dc6706f..00000000000 --- a/src/rt/rust_android_dummy.c +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifdef __ANDROID__ - -#include "rust_android_dummy.h" -#include -#include - -int backtrace(void **array, int size) { return 0; } - -char **backtrace_symbols(void *const *array, int size) { return 0; } - -void backtrace_symbols_fd (void *const *array, int size, int fd) {} - -volatile int* __errno_location() { - return &errno; -} - -float log2f(float f) -{ - return logf( f ) / logf( 2 ); -} - -double log2( double n ) -{ - return log( n ) / log( 2 ); -} - -double exp10( double x ) -{ - return pow( 10, x ); -} - -void telldir() -{ -} - -void seekdir() -{ -} - -void mkfifo() -{ -} - -void abs() -{ -} - -void labs() -{ -} - -void rand() -{ -} - -void srand() -{ -} - -void atof() -{ -} - -int glob(const char *pattern, - int flags, - int (*errfunc) (const char *epath, int eerrno), - glob_t *pglob) -{ - return 0; -} - -void globfree(glob_t *pglob) -{ -} - -int pthread_atfork(void (*prefork)(void), - void (*postfork_parent)(void), - void (*postfork_child)(void)) -{ - return 0; -} - -int mlockall(int flags) -{ - return 0; -} - -int munlockall(void) -{ - return 0; -} - -int shm_open(const char *name, int oflag, mode_t mode) -{ - return 0; -} - -int shm_unlink(const char *name) -{ - return 0; -} - -int posix_madvise(void *addr, size_t len, int advice) -{ - return 0; -} - -#endif diff --git a/src/rt/rust_builtin.c b/src/rt/rust_builtin.c deleted file mode 100644 index c2168d785b9..00000000000 --- a/src/rt/rust_builtin.c +++ /dev/null @@ -1,470 +0,0 @@ -// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#if !defined(_WIN32) - -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __APPLE__ -#include -#include - -#if !(TARGET_OS_IPHONE) -#include -#endif -#endif - -char* -rust_list_dir_val(struct dirent* entry_ptr) { - return entry_ptr->d_name; -} - -// Android's struct dirent does have d_type from the very beginning -// (android-3). _DIRENT_HAVE_D_TYPE is not defined all the way to android-21 -// though... -#if defined(__ANDROID__) -# define _DIRENT_HAVE_D_TYPE -#endif - -int -rust_dir_get_mode(struct dirent* entry_ptr) { -#if defined(_DIRENT_HAVE_D_TYPE) || defined(__APPLE__) - switch (entry_ptr->d_type) { - case DT_BLK: return S_IFBLK; - case DT_CHR: return S_IFCHR; - case DT_FIFO: return S_IFIFO; - case DT_LNK: return S_IFLNK; - case DT_REG: return S_IFREG; - case DT_SOCK: return S_IFSOCK; - case DT_DIR: return S_IFDIR; - } -#endif - return -1; -} - -ino_t -rust_dir_get_ino(struct dirent* entry_ptr) { - return entry_ptr->d_ino; -} - -DIR* -rust_opendir(char *dirname) { - return opendir(dirname); -} - -int -rust_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { - return readdir_r(dirp, entry, result); -} - -size_t -rust_dirent_t_size() { - return sizeof(struct dirent); -} - -#if defined(__BSD__) -static int -get_num_cpus() { - /* swiped from http://stackoverflow.com/questions/150355/ - programmatically-find-the-number-of-cores-on-a-machine */ - - unsigned int numCPU; - int mib[4]; - size_t len = sizeof(numCPU); - - /* set the mib for hw.ncpu */ - mib[0] = CTL_HW; - mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU; - - /* get the number of CPUs from the system */ - sysctl(mib, 2, &numCPU, &len, NULL, 0); - - if( numCPU < 1 ) { - mib[1] = HW_NCPU; - sysctl( mib, 2, &numCPU, &len, NULL, 0 ); - - if( numCPU < 1 ) { - numCPU = 1; - } - } - return numCPU; -} -#elif defined(__GNUC__) -static int -get_num_cpus() { - return sysconf(_SC_NPROCESSORS_ONLN); -} -#endif - -uintptr_t -rust_get_num_cpus() { - return get_num_cpus(); -} - -#if defined(__DragonFly__) -#include -// In DragonFly __error() is an inline function and as such -// no symbol exists for it. -int *__dfly_error(void) { return __error(); } -#endif - -#if defined(__Bitrig__) -#include -#include -#include -#include - -int rust_get_path(void *p, size_t* sz) -{ - int mib[4]; - char *eq = NULL; - char *key = NULL; - char *val = NULL; - char **menv = NULL; - size_t maxlen, len; - int nenv = 0; - int i; - - if ((p == NULL) && (sz == NULL)) - return -1; - - /* get the argv array */ - mib[0] = CTL_KERN; - mib[1] = KERN_PROC_ARGS; - mib[2] = getpid(); - mib[3] = KERN_PROC_ENV; - - /* get the number of bytes needed to get the env */ - maxlen = 0; - if (sysctl(mib, 4, NULL, &maxlen, NULL, 0) == -1) - return -1; - - /* allocate the buffer */ - if ((menv = calloc(maxlen, sizeof(char))) == NULL) - return -1; - - /* get the env array */ - if (sysctl(mib, 4, menv, &maxlen, NULL, 0) == -1) - { - free(menv); - return -1; - } - - mib[3] = KERN_PROC_NENV; - len = sizeof(int); - /* get the length of env array */ - if (sysctl(mib, 4, &nenv, &len, NULL, 0) == -1) - { - free(menv); - return -1; - } - - /* find _ key and resolve the value */ - for (i = 0; i < nenv; i++) - { - if ((eq = strstr(menv[i], "=")) == NULL) - continue; - - key = menv[i]; - val = eq + 1; - *eq = '\0'; - - if (strncmp(key, "PATH", maxlen) != 0) - continue; - - if (p == NULL) - { - /* return the length of the value + NUL */ - *sz = strnlen(val, maxlen) + 1; - free(menv); - return 0; - } - else - { - /* copy *sz bytes to the output buffer */ - memcpy(p, val, *sz); - free(menv); - return 0; - } - } - - free(menv); - return -1; -} - -int rust_get_path_array(void * p, size_t * sz) -{ - char *path, *str; - char **buf; - int i, num; - size_t len; - - if ((p == NULL) && (sz == NULL)) - return -1; - - /* get the length of the PATH value */ - if (rust_get_path(NULL, &len) == -1) - return -1; - - if (len == 0) - return -1; - - /* allocate the buffer */ - if ((path = calloc(len, sizeof(char))) == NULL) - return -1; - - /* get the PATH value */ - if (rust_get_path(path, &len) == -1) - { - free(path); - return -1; - } - - /* count the number of parts in the PATH */ - num = 1; - for(str = path; *str != '\0'; str++) - { - if (*str == ':') - num++; - } - - /* calculate the size of the buffer for the 2D array */ - len = (num * sizeof(char*) + 1) + strlen(path) + 1; - - if (p == NULL) - { - free(path); - *sz = len; - return 0; - } - - /* make sure we have enough buffer space */ - if (*sz < len) - { - free(path); - return -1; - } - - /* zero out the buffer */ - buf = (char**)p; - memset(buf, 0, *sz); - - /* copy the data into the right place */ - str = p + ((num+1) * sizeof(char*)); - memcpy(str, path, strlen(path)); - - /* parse the path into it's parts */ - for (i = 0; i < num && (buf[i] = strsep(&str, ":")) != NULL; i++) {;} - buf[num] = NULL; - - free(path); - return 0; -} - -int rust_get_argv_zero(void* p, size_t* sz) -{ - int mib[4]; - char **argv = NULL; - size_t len; - - if ((p == NULL) && (sz == NULL)) - return -1; - - /* get the argv array */ - mib[0] = CTL_KERN; - mib[1] = KERN_PROC_ARGS; - mib[2] = getpid(); - mib[3] = KERN_PROC_ARGV; - - /* request KERN_PROC_ARGV size */ - len = 0; - if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1) - return -1; - - /* allocate buffer to receive the values */ - if ((argv = malloc(len)) == NULL) - return -1; - - /* get the argv array */ - if (sysctl(mib, 4, argv, &len, NULL, 0) == -1) - { - free(argv); - return -1; - } - - /* get length of argv[0] */ - len = strnlen(argv[0], len) + 1; - - if (p == NULL) - { - *sz = len; - free(argv); - return 0; - } - - if (*sz < len) - { - free(argv); - return -1; - } - - memcpy(p, argv[0], len); - free(argv); - return 0; -} - -const char * rust_current_exe() -{ - static char *self = NULL; - char *argv0; - char **paths; - size_t sz; - int i; - /* If `PATH_MAX` is defined on the platform, `realpath` will truncate the - * resolved path up to `PATH_MAX`. While this can make the resolution fail if - * the executable is placed in a deep path, the usage of a buffer whose - * length depends on `PATH_MAX` is still memory safe. */ - char buf[2*PATH_MAX], exe[PATH_MAX]; - - if (self != NULL) - return self; - - if (rust_get_argv_zero(NULL, &sz) == -1) - return NULL; - if ((argv0 = calloc(sz, sizeof(char))) == NULL) - return NULL; - if (rust_get_argv_zero(argv0, &sz) == -1) - { - free(argv0); - return NULL; - } - - /* if argv0 is a relative or absolute path, resolve it with realpath */ - if ((*argv0 == '.') || (*argv0 == '/') || (strstr(argv0, "/") != NULL)) - { - self = realpath(argv0, NULL); - free(argv0); - return self; - } - - /* get the path array */ - if (rust_get_path_array(NULL, &sz) == -1) - { - free(argv0); - return NULL; - } - if ((paths = calloc(sz, sizeof(char))) == NULL) - { - free(argv0); - return NULL; - } - if (rust_get_path_array(paths, &sz) == -1) - { - free(argv0); - free(paths); - return NULL; - } - - for(i = 0; paths[i] != NULL; i++) - { - snprintf(buf, 2*PATH_MAX, "%s/%s", paths[i], argv0); - if (realpath(buf, exe) == NULL) - continue; - - if (access(exe, F_OK | X_OK) == -1) - continue; - - self = strdup(exe); - free(argv0); - free(paths); - return self; - } - - free(argv0); - free(paths); - return NULL; -} - -#elif defined(__OpenBSD__) - -#include -#include -#include - -const char * rust_current_exe() { - static char *self = NULL; - - if (self == NULL) { - int mib[4]; - char **argv = NULL; - size_t argv_len; - - /* initialize mib */ - mib[0] = CTL_KERN; - mib[1] = KERN_PROC_ARGS; - mib[2] = getpid(); - mib[3] = KERN_PROC_ARGV; - - /* request KERN_PROC_ARGV size */ - argv_len = 0; - if (sysctl(mib, 4, NULL, &argv_len, NULL, 0) == -1) - return (NULL); - - /* allocate size */ - if ((argv = malloc(argv_len)) == NULL) - return (NULL); - - /* request KERN_PROC_ARGV */ - if (sysctl(mib, 4, argv, &argv_len, NULL, 0) == -1) { - free(argv); - return (NULL); - } - - /* get realpath if possible */ - if ((argv[0] != NULL) && ((*argv[0] == '.') || (*argv[0] == '/') - || (strstr(argv[0], "/") != NULL))) - - self = realpath(argv[0], NULL); - else - self = NULL; - - /* cleanup */ - free(argv); - } - - return (self); -} - -#endif - -#endif // !defined(_WIN32) - -// -// Local Variables: -// mode: C++ -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: -//