Skip to content

std: fix readdir errors for solaris #34776

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/libstd/sys/common/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,23 @@ use time::Duration;

#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
target_os = "ios", target_os = "macos",
target_os = "openbsd", target_os = "netbsd"))]
target_os = "openbsd", target_os = "netbsd",
target_os = "solaris"))]
use sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
target_os = "ios", target_os = "macos",
target_os = "openbsd", target_os = "netbsd")))]
target_os = "openbsd", target_os = "netbsd",
target_os = "solaris")))]
use sys::net::netc::IPV6_ADD_MEMBERSHIP;
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
target_os = "ios", target_os = "macos",
target_os = "openbsd", target_os = "netbsd"))]
target_os = "openbsd", target_os = "netbsd",
target_os = "solaris"))]
use sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
target_os = "ios", target_os = "macos",
target_os = "openbsd", target_os = "netbsd")))]
target_os = "openbsd", target_os = "netbsd",
target_os = "solaris")))]
use sys::net::netc::IPV6_DROP_MEMBERSHIP;

////////////////////////////////////////////////////////////////////////////////
Expand Down
8 changes: 7 additions & 1 deletion src/libstd/sys/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,15 @@ impl Iterator for ReadDir {
// of the thread safety, on Illumos the readdir(3C) function is safe to use
// in threaded applications and it is generally preferred over the
// readdir_r(3C) function.
super::os::set_errno(0);
let entry_ptr = libc::readdir(self.dirp.0);
if entry_ptr.is_null() {
return None
// NULL can mean either the end is reached or an error occurred.
// So we had to clear errno beforehand to check for an error now.
return match super::os::errno() {
0 => None,
e => Some(Err(Error::from_raw_os_error(e))),
}
}

let name = (*entry_ptr).d_name.as_ptr();
Expand Down
41 changes: 25 additions & 16 deletions src/libstd/sys/unix/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,37 @@ use vec;
const TMPBUF_SZ: usize = 128;
static ENV_LOCK: Mutex = Mutex::new();


extern {
#[cfg_attr(any(target_os = "linux", target_os = "emscripten"),
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")]
fn errno_location() -> *mut c_int;
}

/// Returns the platform-specific value of errno
#[cfg(not(target_os = "dragonfly"))]
pub fn errno() -> i32 {
extern {
#[cfg_attr(any(target_os = "linux", target_os = "emscripten"),
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")]
fn errno_location() -> *const c_int;
unsafe {
(*errno_location()) as i32
}
}

/// Sets the platform-specific value of errno
#[cfg(target_os = "solaris")] // only needed for readdir so far
pub fn set_errno(e: i32) {
unsafe {
(*errno_location()) as i32
*errno_location() = e as c_int
}
}

Expand Down
1 change: 0 additions & 1 deletion src/libstd/sys/unix/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use prelude::v1::*;

use alloc::boxed::FnBox;
use cmp;
#[cfg(not(any(target_env = "newlib", target_os = "solaris")))]
use ffi::CStr;
use io;
use libc;
Expand Down