Skip to content

Commit 6016214

Browse files
committed
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.
2 parents 27b3e01 + 2180fe2 commit 6016214

11 files changed

+148
-69
lines changed

src/libcore/os.rs

Lines changed: 134 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,10 @@ extern mod rustrt {
6262
unsafe fn rust_path_exists(path: *libc::c_char) -> c_int;
6363
unsafe fn rust_list_files2(&&path: ~str) -> ~[~str];
6464
unsafe fn rust_process_wait(handle: c_int) -> c_int;
65-
unsafe fn last_os_error() -> ~str;
6665
unsafe fn rust_set_exit_status(code: libc::intptr_t);
6766
}
6867

69-
pub const tmpbuf_sz : uint = 1000u;
68+
pub const TMPBUF_SZ : uint = 1000u;
7069

7170
pub fn getcwd() -> Path {
7271
unsafe {
@@ -80,7 +79,7 @@ pub fn as_c_charp<T>(s: &str, f: fn(*c_char) -> T) -> T {
8079

8180
pub fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool)
8281
-> Option<~str> {
83-
let buf = vec::cast_to_mut(vec::from_elem(tmpbuf_sz, 0u8 as c_char));
82+
let buf = vec::cast_to_mut(vec::from_elem(TMPBUF_SZ, 0u8 as c_char));
8483
do vec::as_mut_buf(buf) |b, sz| {
8584
if f(b, sz as size_t) {
8685
unsafe {
@@ -99,19 +98,19 @@ pub mod win32 {
9998
use str;
10099
use option::{None, Option};
101100
use option;
102-
use os::tmpbuf_sz;
101+
use os::TMPBUF_SZ;
103102
use libc::types::os::arch::extra::DWORD;
104103

105104
pub fn fill_utf16_buf_and_decode(f: fn(*mut u16, DWORD) -> DWORD)
106105
-> Option<~str> {
107106
unsafe {
108-
let mut n = tmpbuf_sz as DWORD;
107+
let mut n = TMPBUF_SZ as DWORD;
109108
let mut res = None;
110109
let mut done = false;
111110
while !done {
112111
let buf = vec::cast_to_mut(vec::from_elem(n as uint, 0u16));
113112
do vec::as_mut_buf(buf) |b, _sz| {
114-
let k : DWORD = f(b, tmpbuf_sz as DWORD);
113+
let k : DWORD = f(b, TMPBUF_SZ as DWORD);
115114
if k == (0 as DWORD) {
116115
done = true;
117116
} else if (k == n &&
@@ -387,11 +386,11 @@ pub fn self_exe_path() -> Option<Path> {
387386
unsafe {
388387
use libc::funcs::posix01::unistd::readlink;
389388

390-
let mut path_str = str::with_capacity(tmpbuf_sz);
389+
let mut path_str = str::with_capacity(TMPBUF_SZ);
391390
let len = do str::as_c_str(path_str) |buf| {
392391
let buf = buf as *mut c_char;
393392
do as_c_charp("/proc/self/exe") |proc_self_buf| {
394-
readlink(proc_self_buf, buf, tmpbuf_sz as size_t)
393+
readlink(proc_self_buf, buf, TMPBUF_SZ as size_t)
395394
}
396395
};
397396
if len == -1 {
@@ -766,11 +765,136 @@ pub fn remove_file(p: &Path) -> bool {
766765
}
767766
}
768767

768+
#[cfg(unix)]
769+
pub fn errno() -> int {
770+
#[cfg(target_os = "macos")]
771+
#[cfg(target_os = "freebsd")]
772+
fn errno_location() -> *c_int {
773+
#[nolink]
774+
extern {
775+
unsafe fn __error() -> *c_int;
776+
}
777+
unsafe {
778+
__error()
779+
}
780+
}
781+
782+
#[cfg(target_os = "linux")]
783+
#[cfg(target_os = "android")]
784+
fn errno_location() -> *c_int {
785+
#[nolink]
786+
extern {
787+
unsafe fn __errno_location() -> *c_int;
788+
}
789+
unsafe {
790+
__errno_location()
791+
}
792+
}
793+
794+
unsafe {
795+
(*errno_location()) as int
796+
}
797+
}
798+
799+
#[cfg(windows)]
800+
pub fn errno() -> uint {
801+
use libc::types::os::arch::extra::DWORD;
802+
803+
#[link_name = "kernel32"]
804+
#[abi = "stdcall"]
805+
extern {
806+
unsafe fn GetLastError() -> DWORD;
807+
}
808+
809+
unsafe {
810+
GetLastError() as uint
811+
}
812+
}
813+
769814
/// Get a string representing the platform-dependent last error
770815
pub fn last_os_error() -> ~str {
771-
unsafe {
772-
rustrt::last_os_error()
816+
#[cfg(unix)]
817+
fn strerror() -> ~str {
818+
#[cfg(target_os = "macos")]
819+
#[cfg(target_os = "android")]
820+
#[cfg(target_os = "freebsd")]
821+
fn strerror_r(errnum: c_int, buf: *c_char, buflen: size_t) -> c_int {
822+
#[nolink]
823+
extern {
824+
unsafe fn strerror_r(errnum: c_int, buf: *c_char,
825+
buflen: size_t) -> c_int;
826+
}
827+
unsafe {
828+
strerror_r(errnum, buf, buflen)
829+
}
830+
}
831+
832+
// GNU libc provides a non-compliant version of strerror_r by default
833+
// and requires macros to instead use the POSIX compliant variant.
834+
// So we just use __xpg_strerror_r which is always POSIX compliant
835+
#[cfg(target_os = "linux")]
836+
fn strerror_r(errnum: c_int, buf: *c_char, buflen: size_t) -> c_int {
837+
#[nolink]
838+
extern {
839+
unsafe fn __xpg_strerror_r(errnum: c_int, buf: *c_char,
840+
buflen: size_t) -> c_int;
841+
}
842+
unsafe {
843+
__xpg_strerror_r(errnum, buf, buflen)
844+
}
845+
}
846+
847+
let mut buf = [0 as c_char, ..TMPBUF_SZ];
848+
unsafe {
849+
let err = strerror_r(errno() as c_int, &buf[0],
850+
TMPBUF_SZ as size_t);
851+
if err < 0 {
852+
die!(~"strerror_r failure");
853+
}
854+
855+
str::raw::from_c_str(&buf[0])
856+
}
857+
}
858+
859+
#[cfg(windows)]
860+
fn strerror() -> ~str {
861+
use libc::types::os::arch::extra::DWORD;
862+
use libc::types::os::arch::extra::LPSTR;
863+
use libc::types::os::arch::extra::LPVOID;
864+
865+
#[link_name = "kernel32"]
866+
#[abi = "stdcall"]
867+
extern {
868+
unsafe fn FormatMessageA(flags: DWORD, lpSrc: LPVOID,
869+
msgId: DWORD, langId: DWORD,
870+
buf: LPSTR, nsize: DWORD,
871+
args: *c_void) -> DWORD;
872+
}
873+
874+
const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
875+
const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
876+
877+
let mut buf = [0 as c_char, ..TMPBUF_SZ];
878+
879+
// This value is calculated from the macro
880+
// MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
881+
let langId = 0x0800 as DWORD;
882+
let err = errno() as DWORD;
883+
unsafe {
884+
let res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
885+
FORMAT_MESSAGE_IGNORE_INSERTS,
886+
ptr::mut_null(), err, langId,
887+
&mut buf[0], TMPBUF_SZ as DWORD,
888+
ptr::null());
889+
if res == 0 {
890+
die!(fmt!("[%?] FormatMessage failure", errno()));
891+
}
892+
893+
str::raw::from_c_str(&buf[0])
894+
}
773895
}
896+
897+
strerror()
774898
}
775899
776900
/**

src/rt/rust_builtin.cpp

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -52,50 +52,6 @@ timegm(struct tm *tm)
5252
}
5353
#endif
5454

55-
56-
extern "C" CDECL rust_str*
57-
last_os_error() {
58-
rust_task *task = rust_get_current_task();
59-
60-
LOG(task, task, "last_os_error()");
61-
62-
#if defined(__WIN32__)
63-
LPTSTR buf;
64-
DWORD err = GetLastError();
65-
DWORD res = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
66-
FORMAT_MESSAGE_FROM_SYSTEM |
67-
FORMAT_MESSAGE_IGNORE_INSERTS,
68-
NULL, err,
69-
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
70-
(LPTSTR) &buf, 0, NULL);
71-
if (!res) {
72-
task->fail();
73-
return NULL;
74-
}
75-
#elif defined(_GNU_SOURCE) && !defined(__ANDROID__)
76-
char cbuf[BUF_BYTES];
77-
char *buf = strerror_r(errno, cbuf, sizeof(cbuf));
78-
if (!buf) {
79-
task->fail();
80-
return NULL;
81-
}
82-
#else
83-
char buf[BUF_BYTES];
84-
int err = strerror_r(errno, buf, sizeof(buf));
85-
if (err) {
86-
task->fail();
87-
return NULL;
88-
}
89-
#endif
90-
91-
rust_str * st = make_str(task->kernel, buf, strlen(buf),
92-
"last_os_error");
93-
#ifdef __WIN32__
94-
LocalFree((HLOCAL)buf);
95-
#endif
96-
return st;
97-
}
98-
9955
extern "C" CDECL rust_str *
10056
rust_getcwd() {
10157
rust_task *task = rust_get_current_task();

src/rt/rustrt.def.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ rust_gmtime
1414
rust_localtime
1515
rust_timegm
1616
rust_mktime
17-
last_os_error
1817
new_task
1918
precise_time_ns
2019
rand_free

src/test/auxiliary/anon-extern-mod-cross-crate-1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515

1616
#[crate_type = "lib"];
1717
extern {
18-
fn last_os_error() -> ~str;
18+
fn rust_get_argc() -> libc::c_int;
1919
}

src/test/auxiliary/foreign_lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
#[link(name="foreign_lib", vers="0.0")];
1212

1313
pub extern mod rustrt {
14-
pub fn last_os_error() -> ~str;
14+
pub fn rust_get_argc() -> libc::c_int;
1515
}

src/test/run-fail/morestack2.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@
1818
extern mod std;
1919

2020
extern mod rustrt {
21-
pub fn last_os_error() -> ~str;
21+
pub fn rust_get_argc() -> libc::c_int;
2222
}
2323

2424
fn getbig_call_c_and_fail(i: int) {
2525
if i != 0 {
2626
getbig_call_c_and_fail(i - 1);
2727
} else {
2828
unsafe {
29-
rustrt::last_os_error();
29+
rustrt::rust_get_argc();
3030
die!();
3131
}
3232
}

src/test/run-pass/anon-extern-mod-cross-crate-2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ extern mod anonexternmod;
1515
use anonexternmod::*;
1616

1717
pub fn main() {
18-
last_os_error();
18+
rust_get_argc();
1919
}

src/test/run-pass/anon-extern-mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
#[abi = "cdecl"]
1212
#[link_name = "rustrt"]
1313
extern {
14-
fn last_os_error() -> ~str;
14+
fn rust_get_argc() -> libc::c_int;
1515
}
1616

1717
pub fn main() {
1818
unsafe {
19-
let _ = last_os_error();
19+
let _ = rust_get_argc();
2020
}
2121
}

src/test/run-pass/foreign-dupe.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@
1414
#[abi = "cdecl"]
1515
#[link_name = "rustrt"]
1616
extern mod rustrt1 {
17-
pub fn last_os_error() -> ~str;
17+
pub fn rust_get_argc() -> libc::c_int;
1818
}
1919

2020
#[abi = "cdecl"]
2121
#[link_name = "rustrt"]
2222
extern mod rustrt2 {
23-
pub fn last_os_error() -> ~str;
23+
pub fn rust_get_argc() -> libc::c_int;
2424
}
2525

2626
pub fn main() {
2727
unsafe {
28-
rustrt1::last_os_error();
29-
rustrt2::last_os_error();
28+
rustrt1::rust_get_argc();
29+
rustrt2::rust_get_argc();
3030
}
3131
}

src/test/run-pass/invoke-external-foreign.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@
1818
extern mod foreign_lib;
1919

2020
pub fn main() {
21-
let foo = foreign_lib::rustrt::last_os_error();
21+
let foo = foreign_lib::rustrt::rust_get_argc();
2222
}

src/test/run-pass/morestack6.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ extern mod rustrt {
1515
pub fn debug_get_stk_seg() -> *u8;
1616

1717
pub fn rust_get_sched_id() -> libc::intptr_t;
18-
pub fn last_os_error() -> ~str;
18+
pub fn rust_get_argc() -> libc::c_int;
1919
pub fn rust_getcwd() -> ~str;
2020
pub fn get_task_id() -> libc::intptr_t;
2121
pub fn rust_sched_threads();
2222
pub fn rust_get_task();
2323
}
2424

2525
fn calllink01() { unsafe { rustrt::rust_get_sched_id(); } }
26-
fn calllink02() { unsafe { rustrt::last_os_error(); } }
26+
fn calllink02() { unsafe { rustrt::rust_get_argc(); } }
2727
fn calllink03() { unsafe { rustrt::rust_getcwd(); } }
2828
fn calllink08() { unsafe { rustrt::get_task_id(); } }
2929
fn calllink09() { unsafe { rustrt::rust_sched_threads(); } }

0 commit comments

Comments
 (0)