auto merge of #4900 : luqmana/rust/core_os_errors, r=graydon
Rewrote the last pull request (#4859) to not require on llvm for core. Also fixes #2269.
This commit is contained in:
commit
6016214101
@ -62,11 +62,10 @@ extern mod rustrt {
|
|||||||
unsafe fn rust_path_exists(path: *libc::c_char) -> c_int;
|
unsafe fn rust_path_exists(path: *libc::c_char) -> c_int;
|
||||||
unsafe fn rust_list_files2(&&path: ~str) -> ~[~str];
|
unsafe fn rust_list_files2(&&path: ~str) -> ~[~str];
|
||||||
unsafe fn rust_process_wait(handle: c_int) -> c_int;
|
unsafe fn rust_process_wait(handle: c_int) -> c_int;
|
||||||
unsafe fn last_os_error() -> ~str;
|
|
||||||
unsafe fn rust_set_exit_status(code: libc::intptr_t);
|
unsafe fn rust_set_exit_status(code: libc::intptr_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const tmpbuf_sz : uint = 1000u;
|
pub const TMPBUF_SZ : uint = 1000u;
|
||||||
|
|
||||||
pub fn getcwd() -> Path {
|
pub fn getcwd() -> Path {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -80,7 +79,7 @@ pub fn as_c_charp<T>(s: &str, f: fn(*c_char) -> T) -> T {
|
|||||||
|
|
||||||
pub fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool)
|
pub fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool)
|
||||||
-> Option<~str> {
|
-> Option<~str> {
|
||||||
let buf = vec::cast_to_mut(vec::from_elem(tmpbuf_sz, 0u8 as c_char));
|
let buf = vec::cast_to_mut(vec::from_elem(TMPBUF_SZ, 0u8 as c_char));
|
||||||
do vec::as_mut_buf(buf) |b, sz| {
|
do vec::as_mut_buf(buf) |b, sz| {
|
||||||
if f(b, sz as size_t) {
|
if f(b, sz as size_t) {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -99,19 +98,19 @@ pub mod win32 {
|
|||||||
use str;
|
use str;
|
||||||
use option::{None, Option};
|
use option::{None, Option};
|
||||||
use option;
|
use option;
|
||||||
use os::tmpbuf_sz;
|
use os::TMPBUF_SZ;
|
||||||
use libc::types::os::arch::extra::DWORD;
|
use libc::types::os::arch::extra::DWORD;
|
||||||
|
|
||||||
pub fn fill_utf16_buf_and_decode(f: fn(*mut u16, DWORD) -> DWORD)
|
pub fn fill_utf16_buf_and_decode(f: fn(*mut u16, DWORD) -> DWORD)
|
||||||
-> Option<~str> {
|
-> Option<~str> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut n = tmpbuf_sz as DWORD;
|
let mut n = TMPBUF_SZ as DWORD;
|
||||||
let mut res = None;
|
let mut res = None;
|
||||||
let mut done = false;
|
let mut done = false;
|
||||||
while !done {
|
while !done {
|
||||||
let buf = vec::cast_to_mut(vec::from_elem(n as uint, 0u16));
|
let buf = vec::cast_to_mut(vec::from_elem(n as uint, 0u16));
|
||||||
do vec::as_mut_buf(buf) |b, _sz| {
|
do vec::as_mut_buf(buf) |b, _sz| {
|
||||||
let k : DWORD = f(b, tmpbuf_sz as DWORD);
|
let k : DWORD = f(b, TMPBUF_SZ as DWORD);
|
||||||
if k == (0 as DWORD) {
|
if k == (0 as DWORD) {
|
||||||
done = true;
|
done = true;
|
||||||
} else if (k == n &&
|
} else if (k == n &&
|
||||||
@ -387,11 +386,11 @@ pub fn self_exe_path() -> Option<Path> {
|
|||||||
unsafe {
|
unsafe {
|
||||||
use libc::funcs::posix01::unistd::readlink;
|
use libc::funcs::posix01::unistd::readlink;
|
||||||
|
|
||||||
let mut path_str = str::with_capacity(tmpbuf_sz);
|
let mut path_str = str::with_capacity(TMPBUF_SZ);
|
||||||
let len = do str::as_c_str(path_str) |buf| {
|
let len = do str::as_c_str(path_str) |buf| {
|
||||||
let buf = buf as *mut c_char;
|
let buf = buf as *mut c_char;
|
||||||
do as_c_charp("/proc/self/exe") |proc_self_buf| {
|
do as_c_charp("/proc/self/exe") |proc_self_buf| {
|
||||||
readlink(proc_self_buf, buf, tmpbuf_sz as size_t)
|
readlink(proc_self_buf, buf, TMPBUF_SZ as size_t)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if len == -1 {
|
if len == -1 {
|
||||||
@ -766,11 +765,136 @@ pub fn remove_file(p: &Path) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub fn errno() -> int {
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
#[cfg(target_os = "freebsd")]
|
||||||
|
fn errno_location() -> *c_int {
|
||||||
|
#[nolink]
|
||||||
|
extern {
|
||||||
|
unsafe fn __error() -> *c_int;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
__error()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
fn errno_location() -> *c_int {
|
||||||
|
#[nolink]
|
||||||
|
extern {
|
||||||
|
unsafe fn __errno_location() -> *c_int;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
__errno_location()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(*errno_location()) as int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub fn errno() -> uint {
|
||||||
|
use libc::types::os::arch::extra::DWORD;
|
||||||
|
|
||||||
|
#[link_name = "kernel32"]
|
||||||
|
#[abi = "stdcall"]
|
||||||
|
extern {
|
||||||
|
unsafe fn GetLastError() -> DWORD;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
GetLastError() as uint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a string representing the platform-dependent last error
|
/// Get a string representing the platform-dependent last error
|
||||||
pub fn last_os_error() -> ~str {
|
pub fn last_os_error() -> ~str {
|
||||||
unsafe {
|
#[cfg(unix)]
|
||||||
rustrt::last_os_error()
|
fn strerror() -> ~str {
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
#[cfg(target_os = "freebsd")]
|
||||||
|
fn strerror_r(errnum: c_int, buf: *c_char, buflen: size_t) -> c_int {
|
||||||
|
#[nolink]
|
||||||
|
extern {
|
||||||
|
unsafe fn strerror_r(errnum: c_int, buf: *c_char,
|
||||||
|
buflen: size_t) -> c_int;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
strerror_r(errnum, buf, buflen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GNU libc provides a non-compliant version of strerror_r by default
|
||||||
|
// and requires macros to instead use the POSIX compliant variant.
|
||||||
|
// So we just use __xpg_strerror_r which is always POSIX compliant
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn strerror_r(errnum: c_int, buf: *c_char, buflen: size_t) -> c_int {
|
||||||
|
#[nolink]
|
||||||
|
extern {
|
||||||
|
unsafe fn __xpg_strerror_r(errnum: c_int, buf: *c_char,
|
||||||
|
buflen: size_t) -> c_int;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
__xpg_strerror_r(errnum, buf, buflen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut buf = [0 as c_char, ..TMPBUF_SZ];
|
||||||
|
unsafe {
|
||||||
|
let err = strerror_r(errno() as c_int, &buf[0],
|
||||||
|
TMPBUF_SZ as size_t);
|
||||||
|
if err < 0 {
|
||||||
|
die!(~"strerror_r failure");
|
||||||
|
}
|
||||||
|
|
||||||
|
str::raw::from_c_str(&buf[0])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn strerror() -> ~str {
|
||||||
|
use libc::types::os::arch::extra::DWORD;
|
||||||
|
use libc::types::os::arch::extra::LPSTR;
|
||||||
|
use libc::types::os::arch::extra::LPVOID;
|
||||||
|
|
||||||
|
#[link_name = "kernel32"]
|
||||||
|
#[abi = "stdcall"]
|
||||||
|
extern {
|
||||||
|
unsafe fn FormatMessageA(flags: DWORD, lpSrc: LPVOID,
|
||||||
|
msgId: DWORD, langId: DWORD,
|
||||||
|
buf: LPSTR, nsize: DWORD,
|
||||||
|
args: *c_void) -> DWORD;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
|
||||||
|
const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
|
||||||
|
|
||||||
|
let mut buf = [0 as c_char, ..TMPBUF_SZ];
|
||||||
|
|
||||||
|
// This value is calculated from the macro
|
||||||
|
// MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
|
||||||
|
let langId = 0x0800 as DWORD;
|
||||||
|
let err = errno() as DWORD;
|
||||||
|
unsafe {
|
||||||
|
let res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
ptr::mut_null(), err, langId,
|
||||||
|
&mut buf[0], TMPBUF_SZ as DWORD,
|
||||||
|
ptr::null());
|
||||||
|
if res == 0 {
|
||||||
|
die!(fmt!("[%?] FormatMessage failure", errno()));
|
||||||
|
}
|
||||||
|
|
||||||
|
str::raw::from_c_str(&buf[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strerror()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,50 +52,6 @@ timegm(struct tm *tm)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern "C" CDECL rust_str*
|
|
||||||
last_os_error() {
|
|
||||||
rust_task *task = rust_get_current_task();
|
|
||||||
|
|
||||||
LOG(task, task, "last_os_error()");
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
LPTSTR buf;
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
DWORD res = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL, err,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
(LPTSTR) &buf, 0, NULL);
|
|
||||||
if (!res) {
|
|
||||||
task->fail();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#elif defined(_GNU_SOURCE) && !defined(__ANDROID__)
|
|
||||||
char cbuf[BUF_BYTES];
|
|
||||||
char *buf = strerror_r(errno, cbuf, sizeof(cbuf));
|
|
||||||
if (!buf) {
|
|
||||||
task->fail();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
char buf[BUF_BYTES];
|
|
||||||
int err = strerror_r(errno, buf, sizeof(buf));
|
|
||||||
if (err) {
|
|
||||||
task->fail();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rust_str * st = make_str(task->kernel, buf, strlen(buf),
|
|
||||||
"last_os_error");
|
|
||||||
#ifdef __WIN32__
|
|
||||||
LocalFree((HLOCAL)buf);
|
|
||||||
#endif
|
|
||||||
return st;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" CDECL rust_str *
|
extern "C" CDECL rust_str *
|
||||||
rust_getcwd() {
|
rust_getcwd() {
|
||||||
rust_task *task = rust_get_current_task();
|
rust_task *task = rust_get_current_task();
|
||||||
|
@ -14,7 +14,6 @@ rust_gmtime
|
|||||||
rust_localtime
|
rust_localtime
|
||||||
rust_timegm
|
rust_timegm
|
||||||
rust_mktime
|
rust_mktime
|
||||||
last_os_error
|
|
||||||
new_task
|
new_task
|
||||||
precise_time_ns
|
precise_time_ns
|
||||||
rand_free
|
rand_free
|
||||||
|
@ -15,5 +15,5 @@
|
|||||||
|
|
||||||
#[crate_type = "lib"];
|
#[crate_type = "lib"];
|
||||||
extern {
|
extern {
|
||||||
fn last_os_error() -> ~str;
|
fn rust_get_argc() -> libc::c_int;
|
||||||
}
|
}
|
||||||
|
@ -11,5 +11,5 @@
|
|||||||
#[link(name="foreign_lib", vers="0.0")];
|
#[link(name="foreign_lib", vers="0.0")];
|
||||||
|
|
||||||
pub extern mod rustrt {
|
pub extern mod rustrt {
|
||||||
pub fn last_os_error() -> ~str;
|
pub fn rust_get_argc() -> libc::c_int;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
extern mod std;
|
extern mod std;
|
||||||
|
|
||||||
extern mod rustrt {
|
extern mod rustrt {
|
||||||
pub fn last_os_error() -> ~str;
|
pub fn rust_get_argc() -> libc::c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getbig_call_c_and_fail(i: int) {
|
fn getbig_call_c_and_fail(i: int) {
|
||||||
@ -26,7 +26,7 @@ fn getbig_call_c_and_fail(i: int) {
|
|||||||
getbig_call_c_and_fail(i - 1);
|
getbig_call_c_and_fail(i - 1);
|
||||||
} else {
|
} else {
|
||||||
unsafe {
|
unsafe {
|
||||||
rustrt::last_os_error();
|
rustrt::rust_get_argc();
|
||||||
die!();
|
die!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,5 +15,5 @@ extern mod anonexternmod;
|
|||||||
use anonexternmod::*;
|
use anonexternmod::*;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
last_os_error();
|
rust_get_argc();
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
#[abi = "cdecl"]
|
#[abi = "cdecl"]
|
||||||
#[link_name = "rustrt"]
|
#[link_name = "rustrt"]
|
||||||
extern {
|
extern {
|
||||||
fn last_os_error() -> ~str;
|
fn rust_get_argc() -> libc::c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _ = last_os_error();
|
let _ = rust_get_argc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,18 +14,18 @@
|
|||||||
#[abi = "cdecl"]
|
#[abi = "cdecl"]
|
||||||
#[link_name = "rustrt"]
|
#[link_name = "rustrt"]
|
||||||
extern mod rustrt1 {
|
extern mod rustrt1 {
|
||||||
pub fn last_os_error() -> ~str;
|
pub fn rust_get_argc() -> libc::c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[abi = "cdecl"]
|
#[abi = "cdecl"]
|
||||||
#[link_name = "rustrt"]
|
#[link_name = "rustrt"]
|
||||||
extern mod rustrt2 {
|
extern mod rustrt2 {
|
||||||
pub fn last_os_error() -> ~str;
|
pub fn rust_get_argc() -> libc::c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
rustrt1::last_os_error();
|
rustrt1::rust_get_argc();
|
||||||
rustrt2::last_os_error();
|
rustrt2::rust_get_argc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,5 +18,5 @@
|
|||||||
extern mod foreign_lib;
|
extern mod foreign_lib;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let foo = foreign_lib::rustrt::last_os_error();
|
let foo = foreign_lib::rustrt::rust_get_argc();
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ extern mod rustrt {
|
|||||||
pub fn debug_get_stk_seg() -> *u8;
|
pub fn debug_get_stk_seg() -> *u8;
|
||||||
|
|
||||||
pub fn rust_get_sched_id() -> libc::intptr_t;
|
pub fn rust_get_sched_id() -> libc::intptr_t;
|
||||||
pub fn last_os_error() -> ~str;
|
pub fn rust_get_argc() -> libc::c_int;
|
||||||
pub fn rust_getcwd() -> ~str;
|
pub fn rust_getcwd() -> ~str;
|
||||||
pub fn get_task_id() -> libc::intptr_t;
|
pub fn get_task_id() -> libc::intptr_t;
|
||||||
pub fn rust_sched_threads();
|
pub fn rust_sched_threads();
|
||||||
@ -23,7 +23,7 @@ extern mod rustrt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn calllink01() { unsafe { rustrt::rust_get_sched_id(); } }
|
fn calllink01() { unsafe { rustrt::rust_get_sched_id(); } }
|
||||||
fn calllink02() { unsafe { rustrt::last_os_error(); } }
|
fn calllink02() { unsafe { rustrt::rust_get_argc(); } }
|
||||||
fn calllink03() { unsafe { rustrt::rust_getcwd(); } }
|
fn calllink03() { unsafe { rustrt::rust_getcwd(); } }
|
||||||
fn calllink08() { unsafe { rustrt::get_task_id(); } }
|
fn calllink08() { unsafe { rustrt::get_task_id(); } }
|
||||||
fn calllink09() { unsafe { rustrt::rust_sched_threads(); } }
|
fn calllink09() { unsafe { rustrt::rust_sched_threads(); } }
|
||||||
|
Loading…
Reference in New Issue
Block a user