about summary refs log tree commit diff
path: root/src/libstd/sys/unix/backtrace/mod.rs
diff options
context:
space:
mode:
authorJohn Colanduoni <john@colanduoni.com>2017-07-22 23:05:47 -0700
committerkennytm <kennytm@gmail.com>2017-09-02 03:24:15 +0800
commite8121b3d163f90a8f1cefca07352d3780eed933d (patch)
tree5d3cef5f0030de9f4f04619d081facbbad6c3290 /src/libstd/sys/unix/backtrace/mod.rs
parentf861b6ee46465097eec266c160ac53e230df7cf0 (diff)
downloadrust-e8121b3d163f90a8f1cefca07352d3780eed933d.tar.gz
rust-e8121b3d163f90a8f1cefca07352d3780eed933d.zip
Add libbacktrace support for Apple platforms
Diffstat (limited to 'src/libstd/sys/unix/backtrace/mod.rs')
-rw-r--r--src/libstd/sys/unix/backtrace/mod.rs29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs
index bf52da2ed4a..5bb34fe60cc 100644
--- a/src/libstd/sys/unix/backtrace/mod.rs
+++ b/src/libstd/sys/unix/backtrace/mod.rs
@@ -91,15 +91,42 @@ mod tracing;
 // symbol resolvers:
 mod printing;
 
-#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "emscripten")))]
+#[cfg(not(target_os = "emscripten"))]
 pub mod gnu {
     use io;
     use fs;
     use libc::c_char;
 
+    #[cfg(not(any(target_os = "macos", target_os = "ios")))]
     pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
         Err(io::Error::new(io::ErrorKind::Other, "Not implemented"))
     }
+
+    #[cfg(any(target_os = "macos", target_os = "ios"))]
+    pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
+        use ptr;
+        use slice;
+        use ffi::OsStr;
+        use os::unix::ffi::OsStrExt;
+        use libc::c_int;
+
+        extern {
+            fn _NSGetExecutablePath(buf: *mut c_char,
+                                    bufsize: *mut u32) -> c_int;
+        }
+        unsafe {
+            let mut bufsize: u32 = 0;
+            _NSGetExecutablePath(ptr::null_mut(), &mut bufsize);
+            if bufsize == 0 { return Err(io::Error::last_os_error()); }
+            let mut buffer: Vec<c_char> = Vec::with_capacity(bufsize as usize);
+            let ret = _NSGetExecutablePath(buffer.as_mut_ptr(), &mut bufsize);
+            if ret != 0 { return Err(io::Error::last_os_error()); }
+            buffer.set_len(bufsize as usize);
+            let file = fs::File::open(OsStr::from_bytes(
+                    slice::from_raw_parts(buffer.as_ptr() as *const u8, buffer.len()-1)))?;
+            Ok((buffer, file))
+        }
+    }
 }
 
 pub struct BacktraceContext;