Skip to content

Commit

Permalink
Update handling of errno
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
dcuddeback committed Jun 22, 2018
1 parent dfc4efd commit a85da94
Showing 1 changed file with 40 additions and 43 deletions.
83 changes: 40 additions & 43 deletions serial-unix/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use core;
use libc;

use std::ffi::CStr;
use std::io;
use std::str;

use libc::{c_int, c_char, size_t};
use libc::{c_int, c_char};

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

const TMPBUF_SZ: usize = 128;

pub fn errno() -> i32 {
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
unsafe fn errno_location() -> *const c_int {
extern { fn __error() -> *const c_int; }
__error()
}

#[cfg(target_os = "bitrig")]
fn errno_location() -> *const c_int {
extern {
fn __errno() -> *const c_int;
}
unsafe {
__errno()
}
}

#[cfg(target_os = "dragonfly")]
unsafe fn errno_location() -> *const c_int {
extern { fn __dfly_error() -> *const c_int; }
__dfly_error()
}

#[cfg(target_os = "openbsd")]
unsafe fn errno_location() -> *const c_int {
extern { fn __errno() -> *const c_int; }
__errno()
}

#[cfg(any(target_os = "linux", target_os = "android"))]
unsafe fn errno_location() -> *const c_int {
extern { fn __errno_location() -> *const c_int; }
__errno_location()
}
extern {
#[cfg(not(target_os = "dragonfly"))]
#[cfg_attr(any(target_os = "linux",
target_os = "emscripten",
target_os = "fuchsia",
target_os = "l4re"),
link_name = "__errno_location")]
#[cfg_attr(any(target_os = "bitrig",
target_os = "netbsd",
target_os = "openbsd",
target_os = "android",
target_env = "newlib"),
link_name = "__errno")]
#[cfg_attr(target_os = "solaris", link_name = "___errno")]
#[cfg_attr(any(target_os = "macos",
target_os = "ios",
target_os = "freebsd"),
link_name = "__error")]
#[cfg_attr(target_os = "haiku", link_name = "_errnop")]
fn errno_location() -> *mut c_int;
}

#[cfg(not(target_os = "dragonfly"))]
pub fn errno() -> i32 {
unsafe {
(*errno_location()) as i32
}
}

pub fn error_string(errno: i32) -> String {
#[cfg(target_os = "linux")]
#[cfg(target_os = "dragonfly")]
pub fn errno() -> i32 {
extern {
#[link_name = "__xpg_strerror_r"]
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int;
#[thread_local]
static errno: c_int;
}
#[cfg(not(target_os = "linux"))]

unsafe { errno as i32 }
}

pub fn error_string(errno: i32) -> String {
extern {
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int;
#[cfg_attr(any(target_os = "linux", target_env = "newlib"),
link_name = "__xpg_strerror_r")]
fn strerror_r(errnum: c_int, buf: *mut c_char,
buflen: libc::size_t) -> c_int;
}

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

let p = buf.as_mut_ptr();
unsafe {
if strerror_r(errno as c_int, p, buf.len() as size_t) < 0 {
if strerror_r(errno as c_int, p, buf.len()) < 0 {
panic!("strerror_r failure");
}

let p = p as *const _;
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_string()
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
}
}

0 comments on commit a85da94

Please sign in to comment.