/// to symbols. This is a bit of a hokey implementation as-is, but it works for
/// all unix platforms we support right now, so it at least gets the job done.
-use io;
-use fs;
-
pub use self::tracing::write;
// tracing impls:
// symbol resolvers:
mod printing;
-pub fn get_executable_filename() -> io::Result<(Vec<i8>, fs::File)> {
- Err(io::Error::new(io::ErrorKind::Other, "Not implemented"))
+#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "emscripten")))]
+pub mod gnu {
+ use io;
+ use fs;
+
+ pub fn get_executable_filename() -> io::Result<(Vec<i8>, fs::File)> {
+ Err(io::Error::new(io::ErrorKind::Other, "Not implemented"))
+ }
}
use libc::c_void;
use mem;
use ptr;
-use path::PathBuf;
-use fs::{OpenOptions, File};
-use sys::ext::fs::OpenOptionsExt;
use sys::c;
use sys::dynamic_lib::DynamicLibrary;
use sys::mutex::Mutex;
-use sys::handle::Handle;
macro_rules! sym {
($lib:expr, $e:expr, $t:ident) => (
#[path = "printing/gnu.rs"]
mod printing;
+#[cfg(target_env = "gnu")]
+#[path = "backtrace_gnu.rs"]
+pub mod gnu;
+
type SymInitializeFn =
unsafe extern "system" fn(c::HANDLE, *mut c_void,
c::BOOL) -> c::BOOL;
Ok(())
}
-
-fn query_full_process_image_name() -> io::Result<PathBuf> {
- unsafe {
- let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION,
- c::FALSE,
- c::GetCurrentProcessId()));
- super::fill_utf16_buf(|buf, mut sz| {
- if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 {
- 0
- } else {
- sz
- }
- }, super::os2path)
- }
-}
-
-fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> {
- // We query the current image name, open the file without FILE_SHARE_DELETE so it
- // can't be moved and then get the current image name again. If the names are the
- // same than we have successfully locked the file
- let image_name1 = query_full_process_image_name()?;
- let file = OpenOptions::new()
- .read(true)
- .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE)
- .open(&image_name1)?;
- let image_name2 = query_full_process_image_name()?;
-
- if image_name1 != image_name2 {
- return Err(io::Error::new(io::ErrorKind::Other,
- "executable moved while trying to lock it"));
- }
-
- Ok((image_name1, file))
-}
-
-// Get the executable filename for libbacktrace
-// This returns the path in the ANSI code page and a File which should remain open
-// for as long as the path should remain valid
-pub fn get_executable_filename() -> io::Result<(Vec<i8>, File)> {
- let (executable, file) = lock_and_get_executable_filename()?;
- let u16_executable = super::to_u16s(executable.into_os_string())?;
- Ok((super::wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS,
- &u16_executable, true)?, file))
-}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use io;
+use sys::c;
+use path::PathBuf;
+use fs::{OpenOptions, File};
+use sys::ext::fs::OpenOptionsExt;
+use sys::handle::Handle;
+use super::super::{fill_utf16_buf, os2path, to_u16s, wide_char_to_multi_byte};
+
+fn query_full_process_image_name() -> io::Result<PathBuf> {
+ unsafe {
+ let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION,
+ c::FALSE,
+ c::GetCurrentProcessId()));
+ fill_utf16_buf(|buf, mut sz| {
+ if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 {
+ 0
+ } else {
+ sz
+ }
+ }, os2path)
+ }
+}
+
+fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> {
+ // We query the current image name, open the file without FILE_SHARE_DELETE so it
+ // can't be moved and then get the current image name again. If the names are the
+ // same than we have successfully locked the file
+ let image_name1 = query_full_process_image_name()?;
+ let file = OpenOptions::new()
+ .read(true)
+ .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE)
+ .open(&image_name1)?;
+ let image_name2 = query_full_process_image_name()?;
+
+ if image_name1 != image_name2 {
+ return Err(io::Error::new(io::ErrorKind::Other,
+ "executable moved while trying to lock it"));
+ }
+
+ Ok((image_name1, file))
+}
+
+// Get the executable filename for libbacktrace
+// This returns the path in the ANSI code page and a File which should remain open
+// for as long as the path should remain valid
+pub fn get_executable_filename() -> io::Result<(Vec<i8>, File)> {
+ let (executable, file) = lock_and_get_executable_filename()?;
+ let u16_executable = to_u16s(executable.into_os_string())?;
+ Ok((wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS,
+ &u16_executable, true)?, file))
+}
pub const MAX_PROTOCOL_CHAIN: DWORD = 7;
-pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400;
pub const TOKEN_READ: DWORD = 0x20008;
pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
pub const CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400;
pub const STARTF_USESTDHANDLES: DWORD = 0x00000100;
-pub const CP_ACP: UINT = 0;
-
-pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400;
-
pub const AF_INET: c_int = 2;
pub const AF_INET6: c_int = 23;
pub const SD_BOTH: c_int = 2;
pNumArgs: *mut c_int) -> *mut *mut u16;
pub fn GetTempPathW(nBufferLength: DWORD,
lpBuffer: LPCWSTR) -> DWORD;
- pub fn OpenProcess(dwDesiredAccess: DWORD,
- bInheritHandle: BOOL,
- dwProcessId: DWORD) -> HANDLE;
pub fn OpenProcessToken(ProcessHandle: HANDLE,
DesiredAccess: DWORD,
TokenHandle: *mut HANDLE) -> BOOL;
_dwFlags: DWORD) -> DWORD {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
}
- pub fn QueryFullProcessImageNameW(_hProcess: HANDLE,
- _dwFlags: DWORD,
- _lpExeName: LPWSTR,
- _lpdwSize: LPDWORD) -> BOOL {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
- }
pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
}
panic!("rwlocks not available")
}
}
+
+#[cfg(target_env = "gnu")]
+mod gnu {
+ use super::*;
+
+ pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400;
+
+ pub const CP_ACP: UINT = 0;
+
+ pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400;
+
+ extern "system" {
+ pub fn OpenProcess(dwDesiredAccess: DWORD,
+ bInheritHandle: BOOL,
+ dwProcessId: DWORD) -> HANDLE;
+ }
+
+ compat_fn! {
+ kernel32:
+
+ pub fn QueryFullProcessImageNameW(_hProcess: HANDLE,
+ _dwFlags: DWORD,
+ _lpExeName: LPWSTR,
+ _lpdwSize: LPDWORD) -> BOOL {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
+ }
+ }
+}
+
+#[cfg(target_env = "gnu")]
+pub use self::gnu::*;
PathBuf::from(OsString::from_wide(s))
}
+#[allow(dead_code)] // Only used in backtrace::gnu::get_executable_filename()
fn wide_char_to_multi_byte(code_page: u32,
flags: u32,
s: &[u16],
static mut STATE: *mut backtrace_state = ptr::null_mut();
if !STATE.is_null() { return STATE }
- let filename = match ::sys::backtrace::get_executable_filename() {
+ let filename = match ::sys::backtrace::gnu::get_executable_filename() {
Ok((filename, file)) => {
// filename is purposely leaked here since libbacktrace requires
// it to stay allocated permanently, file is also leaked so that