Skip to content

Commit a85da94

Browse files
committed
Update handling of errno
This commit copies the latest errno-handling code from libstd's `src/libstd/sys/unix/os.rs`, which brings support for more platforms. The code has to be copied because libstd doesn't export `errno` (`std::sys` is private).
1 parent dfc4efd commit a85da94

File tree

1 file changed

+40
-43
lines changed

1 file changed

+40
-43
lines changed

serial-unix/src/error.rs

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@
2020
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
use core;
23+
use libc;
2324

2425
use std::ffi::CStr;
2526
use std::io;
2627
use std::str;
2728

28-
use libc::{c_int, c_char, size_t};
29+
use libc::{c_int, c_char};
2930

3031
pub fn last_os_error() -> core::Error {
3132
from_raw_os_error(errno())
@@ -50,66 +51,62 @@ pub fn from_raw_os_error(errno: i32) -> core::Error {
5051

5152
const TMPBUF_SZ: usize = 128;
5253

53-
pub fn errno() -> i32 {
54-
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
55-
unsafe fn errno_location() -> *const c_int {
56-
extern { fn __error() -> *const c_int; }
57-
__error()
58-
}
59-
60-
#[cfg(target_os = "bitrig")]
61-
fn errno_location() -> *const c_int {
62-
extern {
63-
fn __errno() -> *const c_int;
64-
}
65-
unsafe {
66-
__errno()
67-
}
68-
}
69-
70-
#[cfg(target_os = "dragonfly")]
71-
unsafe fn errno_location() -> *const c_int {
72-
extern { fn __dfly_error() -> *const c_int; }
73-
__dfly_error()
74-
}
75-
76-
#[cfg(target_os = "openbsd")]
77-
unsafe fn errno_location() -> *const c_int {
78-
extern { fn __errno() -> *const c_int; }
79-
__errno()
80-
}
81-
82-
#[cfg(any(target_os = "linux", target_os = "android"))]
83-
unsafe fn errno_location() -> *const c_int {
84-
extern { fn __errno_location() -> *const c_int; }
85-
__errno_location()
86-
}
54+
extern {
55+
#[cfg(not(target_os = "dragonfly"))]
56+
#[cfg_attr(any(target_os = "linux",
57+
target_os = "emscripten",
58+
target_os = "fuchsia",
59+
target_os = "l4re"),
60+
link_name = "__errno_location")]
61+
#[cfg_attr(any(target_os = "bitrig",
62+
target_os = "netbsd",
63+
target_os = "openbsd",
64+
target_os = "android",
65+
target_env = "newlib"),
66+
link_name = "__errno")]
67+
#[cfg_attr(target_os = "solaris", link_name = "___errno")]
68+
#[cfg_attr(any(target_os = "macos",
69+
target_os = "ios",
70+
target_os = "freebsd"),
71+
link_name = "__error")]
72+
#[cfg_attr(target_os = "haiku", link_name = "_errnop")]
73+
fn errno_location() -> *mut c_int;
74+
}
8775

76+
#[cfg(not(target_os = "dragonfly"))]
77+
pub fn errno() -> i32 {
8878
unsafe {
8979
(*errno_location()) as i32
9080
}
9181
}
9282

93-
pub fn error_string(errno: i32) -> String {
94-
#[cfg(target_os = "linux")]
83+
#[cfg(target_os = "dragonfly")]
84+
pub fn errno() -> i32 {
9585
extern {
96-
#[link_name = "__xpg_strerror_r"]
97-
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int;
86+
#[thread_local]
87+
static errno: c_int;
9888
}
99-
#[cfg(not(target_os = "linux"))]
89+
90+
unsafe { errno as i32 }
91+
}
92+
93+
pub fn error_string(errno: i32) -> String {
10094
extern {
101-
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int;
95+
#[cfg_attr(any(target_os = "linux", target_env = "newlib"),
96+
link_name = "__xpg_strerror_r")]
97+
fn strerror_r(errnum: c_int, buf: *mut c_char,
98+
buflen: libc::size_t) -> c_int;
10299
}
103100

104101
let mut buf = [0 as c_char; TMPBUF_SZ];
105102

106103
let p = buf.as_mut_ptr();
107104
unsafe {
108-
if strerror_r(errno as c_int, p, buf.len() as size_t) < 0 {
105+
if strerror_r(errno as c_int, p, buf.len()) < 0 {
109106
panic!("strerror_r failure");
110107
}
111108

112109
let p = p as *const _;
113-
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_string()
110+
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
114111
}
115112
}

0 commit comments

Comments
 (0)