diff options
Diffstat (limited to 'library/std/src/sys/unix')
-rw-r--r-- | library/std/src/sys/unix/alloc.rs | 6 | ||||
-rw-r--r-- | library/std/src/sys/unix/args.rs | 1 | ||||
-rw-r--r-- | library/std/src/sys/unix/env.rs | 11 | ||||
-rw-r--r-- | library/std/src/sys/unix/fd.rs | 18 | ||||
-rw-r--r-- | library/std/src/sys/unix/fs.rs | 62 | ||||
-rw-r--r-- | library/std/src/sys/unix/kernel_copy.rs | 4 | ||||
-rw-r--r-- | library/std/src/sys/unix/mod.rs | 11 | ||||
-rw-r--r-- | library/std/src/sys/unix/net.rs | 9 | ||||
-rw-r--r-- | library/std/src/sys/unix/os.rs | 15 | ||||
-rw-r--r-- | library/std/src/sys/unix/os_str.rs | 10 | ||||
-rw-r--r-- | library/std/src/sys/unix/os_str/tests.rs | 4 | ||||
-rw-r--r-- | library/std/src/sys/unix/path.rs | 2 | ||||
-rw-r--r-- | library/std/src/sys/unix/pipe.rs | 9 | ||||
-rw-r--r-- | library/std/src/sys/unix/process/process_common.rs | 51 | ||||
-rw-r--r-- | library/std/src/sys/unix/process/process_unix.rs | 15 | ||||
-rw-r--r-- | library/std/src/sys/unix/stack_overflow.rs | 2 | ||||
-rw-r--r-- | library/std/src/sys/unix/thread.rs | 37 | ||||
-rw-r--r-- | library/std/src/sys/unix/thread_local_dtor.rs | 4 | ||||
-rw-r--r-- | library/std/src/sys/unix/thread_parking/darwin.rs | 3 | ||||
-rw-r--r-- | library/std/src/sys/unix/time.rs | 2 |
20 files changed, 223 insertions, 53 deletions
diff --git a/library/std/src/sys/unix/alloc.rs b/library/std/src/sys/unix/alloc.rs index 8604b5398..af0089978 100644 --- a/library/std/src/sys/unix/alloc.rs +++ b/library/std/src/sys/unix/alloc.rs @@ -86,7 +86,11 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "wasi")] { #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { - libc::aligned_alloc(layout.align(), layout.size()) as *mut u8 + // C11 aligned_alloc requires that the size be a multiple of the alignment. + // Layout already checks that the size rounded up doesn't overflow isize::MAX. + let align = layout.align(); + let size = layout.size().next_multiple_of(align); + libc::aligned_alloc(align, size) as *mut u8 } } else { #[inline] diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs index eafd6821f..19334e2af 100644 --- a/library/std/src/sys/unix/args.rs +++ b/library/std/src/sys/unix/args.rs @@ -71,6 +71,7 @@ impl DoubleEndedIterator for Args { target_os = "vxworks", target_os = "horizon", target_os = "nto", + target_os = "hurd", ))] mod imp { use super::Args; diff --git a/library/std/src/sys/unix/env.rs b/library/std/src/sys/unix/env.rs index 929e9dae7..c6d8578a6 100644 --- a/library/std/src/sys/unix/env.rs +++ b/library/std/src/sys/unix/env.rs @@ -152,6 +152,17 @@ pub mod os { pub const EXE_EXTENSION: &str = "elf"; } +#[cfg(target_os = "hurd")] +pub mod os { + pub const FAMILY: &str = "unix"; + pub const OS: &str = "hurd"; + pub const DLL_PREFIX: &str = "lib"; + pub const DLL_SUFFIX: &str = ".so"; + pub const DLL_EXTENSION: &str = "so"; + pub const EXE_SUFFIX: &str = ""; + pub const EXE_EXTENSION: &str = ""; +} + #[cfg(target_os = "vita")] pub mod os { pub const FAMILY: &str = "unix"; diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index 85e020ae4..6c4f40842 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -13,14 +13,16 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; target_os = "android", target_os = "linux", target_os = "emscripten", - target_os = "l4re" + target_os = "l4re", + target_os = "hurd", ))] use libc::off64_t; #[cfg(not(any( target_os = "linux", target_os = "emscripten", target_os = "l4re", - target_os = "android" + target_os = "android", + target_os = "hurd", )))] use libc::off_t as off64_t; @@ -124,9 +126,9 @@ impl FileDesc { } pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> { - #[cfg(not(any(target_os = "linux", target_os = "android")))] + #[cfg(not(any(target_os = "linux", target_os = "android", target_os = "hurd")))] use libc::pread as pread64; - #[cfg(any(target_os = "linux", target_os = "android"))] + #[cfg(any(target_os = "linux", target_os = "android", target_os = "hurd"))] use libc::pread64; unsafe { @@ -160,6 +162,7 @@ impl FileDesc { target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "illumos", target_os = "linux", target_os = "netbsd", @@ -181,6 +184,7 @@ impl FileDesc { target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "illumos", target_os = "ios", target_os = "tvos", @@ -281,9 +285,9 @@ impl FileDesc { } pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> { - #[cfg(not(any(target_os = "linux", target_os = "android")))] + #[cfg(not(any(target_os = "linux", target_os = "android", target_os = "hurd")))] use libc::pwrite as pwrite64; - #[cfg(any(target_os = "linux", target_os = "android"))] + #[cfg(any(target_os = "linux", target_os = "android", target_os = "hurd"))] use libc::pwrite64; unsafe { @@ -301,6 +305,7 @@ impl FileDesc { target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "illumos", target_os = "linux", target_os = "netbsd", @@ -322,6 +327,7 @@ impl FileDesc { target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "illumos", target_os = "ios", target_os = "tvos", diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index a5604c92a..764e1f257 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -39,9 +39,14 @@ use libc::{c_int, mode_t}; all(target_os = "linux", target_env = "gnu") ))] use libc::c_char; -#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))] +#[cfg(any( + target_os = "linux", + target_os = "emscripten", + target_os = "android", + target_os = "hurd", +))] use libc::dirfd; -#[cfg(any(target_os = "linux", target_os = "emscripten"))] +#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "hurd"))] use libc::fstatat64; #[cfg(any( target_os = "android", @@ -53,7 +58,7 @@ use libc::fstatat64; target_os = "vita", ))] use libc::readdir as readdir64; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "hurd"))] use libc::readdir64; #[cfg(any(target_os = "emscripten", target_os = "l4re"))] use libc::readdir64_r; @@ -68,6 +73,7 @@ use libc::readdir64_r; target_os = "redox", target_os = "nto", target_os = "vita", + target_os = "hurd", )))] use libc::readdir_r as readdir64_r; #[cfg(target_os = "android")] @@ -79,13 +85,19 @@ use libc::{ target_os = "linux", target_os = "emscripten", target_os = "l4re", - target_os = "android" + target_os = "android", + target_os = "hurd", )))] use libc::{ dirent as dirent64, fstat as fstat64, ftruncate as ftruncate64, lseek as lseek64, lstat as lstat64, off_t as off64_t, open as open64, stat as stat64, }; -#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "l4re"))] +#[cfg(any( + target_os = "linux", + target_os = "emscripten", + target_os = "l4re", + target_os = "hurd" +))] use libc::{dirent64, fstat64, ftruncate64, lseek64, lstat64, off64_t, open64, stat64}; pub use crate::sys_common::fs::try_exists; @@ -277,7 +289,8 @@ unsafe impl Sync for Dir {} target_os = "fuchsia", target_os = "redox", target_os = "nto", - target_os = "vita" + target_os = "vita", + target_os = "hurd", ))] pub struct DirEntry { dir: Arc<InnerReadDir>, @@ -300,6 +313,7 @@ pub struct DirEntry { target_os = "redox", target_os = "nto", target_os = "vita", + target_os = "hurd", ))] struct dirent64_min { d_ino: u64, @@ -321,6 +335,7 @@ struct dirent64_min { target_os = "redox", target_os = "nto", target_os = "vita", + target_os = "hurd", )))] pub struct DirEntry { dir: Arc<InnerReadDir>, @@ -455,7 +470,8 @@ impl FileAttr { target_os = "vxworks", target_os = "espidf", target_os = "horizon", - target_os = "vita" + target_os = "vita", + target_os = "hurd", )))] pub fn modified(&self) -> io::Result<SystemTime> { #[cfg(target_pointer_width = "32")] @@ -473,7 +489,7 @@ impl FileAttr { Ok(SystemTime::new(self.stat.st_mtime as i64, 0)) } - #[cfg(target_os = "horizon")] + #[cfg(any(target_os = "horizon", target_os = "hurd"))] pub fn modified(&self) -> io::Result<SystemTime> { Ok(SystemTime::from(self.stat.st_mtim)) } @@ -482,7 +498,8 @@ impl FileAttr { target_os = "vxworks", target_os = "espidf", target_os = "horizon", - target_os = "vita" + target_os = "vita", + target_os = "hurd", )))] pub fn accessed(&self) -> io::Result<SystemTime> { #[cfg(target_pointer_width = "32")] @@ -500,7 +517,7 @@ impl FileAttr { Ok(SystemTime::new(self.stat.st_atime as i64, 0)) } - #[cfg(target_os = "horizon")] + #[cfg(any(target_os = "horizon", target_os = "hurd"))] pub fn accessed(&self) -> io::Result<SystemTime> { Ok(SystemTime::from(self.stat.st_atim)) } @@ -656,6 +673,7 @@ impl Iterator for ReadDir { target_os = "illumos", target_os = "nto", target_os = "vita", + target_os = "hurd", ))] fn next(&mut self) -> Option<io::Result<DirEntry>> { if self.end_of_stream { @@ -756,6 +774,7 @@ impl Iterator for ReadDir { target_os = "illumos", target_os = "nto", target_os = "vita", + target_os = "hurd", )))] fn next(&mut self) -> Option<io::Result<DirEntry>> { if self.end_of_stream { @@ -792,7 +811,7 @@ impl Drop for Dir { fn drop(&mut self) { let r = unsafe { libc::closedir(self.0) }; assert!( - r == 0 || crate::io::Error::last_os_error().kind() == crate::io::ErrorKind::Interrupted, + r == 0 || crate::io::Error::last_os_error().is_interrupted(), "unexpected error during closedir: {:?}", crate::io::Error::last_os_error() ); @@ -809,7 +828,12 @@ impl DirEntry { } #[cfg(all( - any(target_os = "linux", target_os = "emscripten", target_os = "android"), + any( + target_os = "linux", + target_os = "emscripten", + target_os = "android", + target_os = "hurd", + ), not(miri) ))] pub fn metadata(&self) -> io::Result<FileAttr> { @@ -833,7 +857,12 @@ impl DirEntry { } #[cfg(any( - not(any(target_os = "linux", target_os = "emscripten", target_os = "android")), + not(any( + target_os = "linux", + target_os = "emscripten", + target_os = "android", + target_os = "hurd", + )), miri ))] pub fn metadata(&self) -> io::Result<FileAttr> { @@ -892,6 +921,7 @@ impl DirEntry { target_os = "horizon", target_os = "vita", target_os = "nto", + target_os = "hurd", ))] pub fn ino(&self) -> u64 { self.entry.d_ino as u64 @@ -949,6 +979,7 @@ impl DirEntry { target_os = "redox", target_os = "nto", target_os = "vita", + target_os = "hurd", )))] fn name_cstr(&self) -> &CStr { unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()) } @@ -962,6 +993,7 @@ impl DirEntry { target_os = "redox", target_os = "nto", target_os = "vita", + target_os = "hurd", ))] fn name_cstr(&self) -> &CStr { &self.name @@ -1131,6 +1163,7 @@ impl File { target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_os = "hurd", ))] unsafe fn os_datasync(fd: c_int) -> c_int { libc::fdatasync(fd) @@ -1146,6 +1179,7 @@ impl File { target_os = "openbsd", target_os = "watchos", target_os = "nto", + target_os = "hurd", )))] unsafe fn os_datasync(fd: c_int) -> c_int { libc::fsync(fd) @@ -1456,6 +1490,7 @@ impl fmt::Debug for File { target_os = "linux", target_os = "macos", target_os = "freebsd", + target_os = "hurd", target_os = "netbsd", target_os = "openbsd", target_os = "vxworks" @@ -1477,6 +1512,7 @@ impl fmt::Debug for File { target_os = "linux", target_os = "macos", target_os = "freebsd", + target_os = "hurd", target_os = "netbsd", target_os = "openbsd", target_os = "vxworks" diff --git a/library/std/src/sys/unix/kernel_copy.rs b/library/std/src/sys/unix/kernel_copy.rs index 4d17a1b00..18acd5ecc 100644 --- a/library/std/src/sys/unix/kernel_copy.rs +++ b/library/std/src/sys/unix/kernel_copy.rs @@ -59,9 +59,9 @@ use crate::ptr; use crate::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use crate::sys::cvt; use crate::sys::weak::syscall; -#[cfg(not(all(target_os = "linux", target_env = "gnu")))] +#[cfg(not(any(all(target_os = "linux", target_env = "gnu"), target_os = "hurd")))] use libc::sendfile as sendfile64; -#[cfg(all(target_os = "linux", target_env = "gnu"))] +#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_os = "hurd"))] use libc::sendfile64; use libc::{EBADF, EINVAL, ENOSYS, EOPNOTSUPP, EOVERFLOW, EPERM, EXDEV}; diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 77ef086f2..3edafde71 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -204,6 +204,10 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { } if let Some(handler) = handler { rtassert!(signal(libc::SIGPIPE, handler) != libc::SIG_ERR); + #[cfg(target_os = "hurd")] + { + rtassert!(signal(libc::SIGLOST, handler) != libc::SIG_ERR); + } } } } @@ -240,6 +244,11 @@ pub use crate::sys::android::signal; #[cfg(not(target_os = "android"))] pub use libc::signal; +#[inline] +pub(crate) fn is_interrupted(errno: i32) -> bool { + errno == libc::EINTR +} + pub fn decode_error_kind(errno: i32) -> ErrorKind { use ErrorKind::*; match errno as libc::c_int { @@ -315,7 +324,7 @@ where { loop { match cvt(f()) { - Err(ref e) if e.kind() == ErrorKind::Interrupted => {} + Err(ref e) if e.is_interrupted() => {} other => return other, } } diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index 7258c222a..f450d708d 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -75,6 +75,7 @@ impl Socket { target_os = "dragonfly", target_os = "freebsd", target_os = "illumos", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -102,7 +103,7 @@ impl Socket { } } - #[cfg(not(target_os = "vxworks"))] + #[cfg(not(any(target_os = "vxworks", target_os = "vita")))] pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> { unsafe { let mut fds = [0, 0]; @@ -114,6 +115,7 @@ impl Socket { target_os = "freebsd", target_os = "illumos", target_os = "linux", + target_os = "hurd", target_os = "netbsd", target_os = "openbsd", target_os = "nto", @@ -133,7 +135,7 @@ impl Socket { } } - #[cfg(target_os = "vxworks")] + #[cfg(any(target_os = "vxworks", target_os = "vita"))] pub fn new_pair(_fam: c_int, _ty: c_int) -> io::Result<(Socket, Socket)> { unimplemented!() } @@ -184,7 +186,7 @@ impl Socket { match unsafe { libc::poll(&mut pollfd, 1, timeout) } { -1 => { let err = io::Error::last_os_error(); - if err.kind() != io::ErrorKind::Interrupted { + if !err.is_interrupted() { return Err(err); } } @@ -220,6 +222,7 @@ impl Socket { target_os = "freebsd", target_os = "illumos", target_os = "linux", + target_os = "hurd", target_os = "netbsd", target_os = "openbsd", ))] { diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 57e1a36da..01ff375d2 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -46,7 +46,8 @@ extern "C" { target_os = "linux", target_os = "emscripten", target_os = "fuchsia", - target_os = "l4re" + target_os = "l4re", + target_os = "hurd", ), link_name = "__errno_location" )] @@ -121,7 +122,10 @@ pub fn set_errno(e: i32) { pub fn error_string(errno: i32) -> String { extern "C" { #[cfg_attr( - all(any(target_os = "linux", target_env = "newlib"), not(target_env = "ohos")), + all( + any(target_os = "linux", target_os = "hurd", target_env = "newlib"), + not(target_env = "ohos") + ), link_name = "__xpg_strerror_r" )] fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int; @@ -359,7 +363,12 @@ pub fn current_exe() -> io::Result<PathBuf> { } } -#[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))] +#[cfg(any( + target_os = "linux", + target_os = "hurd", + target_os = "android", + target_os = "emscripten" +))] pub fn current_exe() -> io::Result<PathBuf> { match crate::fs::read_link("/proc/self/exe") { Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::const_io_error!( diff --git a/library/std/src/sys/unix/os_str.rs b/library/std/src/sys/unix/os_str.rs index 463b0a275..7bd2f656a 100644 --- a/library/std/src/sys/unix/os_str.rs +++ b/library/std/src/sys/unix/os_str.rs @@ -97,12 +97,12 @@ impl AsInner<[u8]> for Buf { impl Buf { #[inline] - pub fn into_os_str_bytes(self) -> Vec<u8> { + pub fn into_encoded_bytes(self) -> Vec<u8> { self.inner } #[inline] - pub unsafe fn from_os_str_bytes_unchecked(s: Vec<u8>) -> Self { + pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self { Self { inner: s } } @@ -203,18 +203,18 @@ impl Buf { impl Slice { #[inline] - pub fn as_os_str_bytes(&self) -> &[u8] { + pub fn as_encoded_bytes(&self) -> &[u8] { &self.inner } #[inline] - pub unsafe fn from_os_str_bytes_unchecked(s: &[u8]) -> &Slice { + pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice { unsafe { mem::transmute(s) } } #[inline] pub fn from_str(s: &str) -> &Slice { - unsafe { Slice::from_os_str_bytes_unchecked(s.as_bytes()) } + unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) } } pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> { diff --git a/library/std/src/sys/unix/os_str/tests.rs b/library/std/src/sys/unix/os_str/tests.rs index 91bc0e61a..e2a99045e 100644 --- a/library/std/src/sys/unix/os_str/tests.rs +++ b/library/std/src/sys/unix/os_str/tests.rs @@ -2,7 +2,7 @@ use super::*; #[test] fn slice_debug_output() { - let input = unsafe { Slice::from_os_str_bytes_unchecked(b"\xF0hello,\tworld") }; + let input = unsafe { Slice::from_encoded_bytes_unchecked(b"\xF0hello,\tworld") }; let expected = r#""\xF0hello,\tworld""#; let output = format!("{input:?}"); @@ -12,6 +12,6 @@ fn slice_debug_output() { #[test] fn display() { assert_eq!("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye", unsafe { - Slice::from_os_str_bytes_unchecked(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string() + Slice::from_encoded_bytes_unchecked(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string() },); } diff --git a/library/std/src/sys/unix/path.rs b/library/std/src/sys/unix/path.rs index 935245f63..837f68d3e 100644 --- a/library/std/src/sys/unix/path.rs +++ b/library/std/src/sys/unix/path.rs @@ -30,7 +30,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> { // Get the components, skipping the redundant leading "." component if it exists. let mut components = path.strip_prefix(".").unwrap_or(path).components(); - let path_os = path.as_os_str().as_os_str_bytes(); + let path_os = path.as_os_str().as_encoded_bytes(); let mut normalized = if path.is_absolute() { // "If a pathname begins with two successive <slash> characters, the diff --git a/library/std/src/sys/unix/pipe.rs b/library/std/src/sys/unix/pipe.rs index 938a46bfd..33db24e77 100644 --- a/library/std/src/sys/unix/pipe.rs +++ b/library/std/src/sys/unix/pipe.rs @@ -3,7 +3,7 @@ use crate::mem; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::sys::fd::FileDesc; use crate::sys::{cvt, cvt_r}; -use crate::sys_common::IntoInner; +use crate::sys_common::{FromInner, IntoInner}; //////////////////////////////////////////////////////////////////////////////// // Anonymous pipes @@ -21,6 +21,7 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { if #[cfg(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -158,3 +159,9 @@ impl FromRawFd for AnonPipe { Self(FromRawFd::from_raw_fd(raw_fd)) } } + +impl FromInner<FileDesc> for AnonPipe { + fn from_inner(fd: FileDesc) -> Self { + Self(fd) + } +} diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index 640648e87..1ca11a7f9 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -13,7 +13,7 @@ use crate::sys::fd::FileDesc; use crate::sys::fs::File; use crate::sys::pipe::{self, AnonPipe}; use crate::sys_common::process::{CommandEnv, CommandEnvs}; -use crate::sys_common::IntoInner; +use crate::sys_common::{FromInner, IntoInner}; #[cfg(not(target_os = "fuchsia"))] use crate::sys::fs::OpenOptions; @@ -150,6 +150,7 @@ pub enum Stdio { Null, MakePipe, Fd(FileDesc), + StaticFd(BorrowedFd<'static>), } #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -164,9 +165,9 @@ pub enum ProgramKind { impl ProgramKind { fn new(program: &OsStr) -> Self { - if program.as_os_str_bytes().starts_with(b"/") { + if program.as_encoded_bytes().starts_with(b"/") { Self::Absolute - } else if program.as_os_str_bytes().contains(&b'/') { + } else if program.as_encoded_bytes().contains(&b'/') { // If the program has more than one component in it, it is a relative path. Self::Relative } else { @@ -463,6 +464,11 @@ impl Stdio { } } + Stdio::StaticFd(fd) => { + let fd = FileDesc::from_inner(fd.try_clone_to_owned()?); + Ok((ChildStdio::Owned(fd), None)) + } + Stdio::MakePipe => { let (reader, writer) = pipe::anon_pipe()?; let (ours, theirs) = if readable { (writer, reader) } else { (reader, writer) }; @@ -497,6 +503,28 @@ impl From<File> for Stdio { } } +impl From<io::Stdout> for Stdio { + fn from(_: io::Stdout) -> Stdio { + // This ought really to be is Stdio::StaticFd(input_argument.as_fd()). + // But AsFd::as_fd takes its argument by reference, and yields + // a bounded lifetime, so it's no use here. There is no AsStaticFd. + // + // Additionally AsFd is only implemented for the *locked* versions. + // We don't want to lock them here. (The implications of not locking + // are the same as those for process::Stdio::inherit().) + // + // Arguably the hypothetical AsStaticFd and AsFd<'static> + // should be implemented for io::Stdout, not just for StdoutLocked. + Stdio::StaticFd(unsafe { BorrowedFd::borrow_raw(libc::STDOUT_FILENO) }) + } +} + +impl From<io::Stderr> for Stdio { + fn from(_: io::Stderr) -> Stdio { + Stdio::StaticFd(unsafe { BorrowedFd::borrow_raw(libc::STDERR_FILENO) }) + } +} + impl ChildStdio { pub fn fd(&self) -> Option<c_int> { match *self { @@ -558,6 +586,23 @@ impl fmt::Debug for Command { if let Some(ref cwd) = self.cwd { write!(f, "cd {cwd:?} && ")?; } + if self.env.does_clear() { + write!(f, "env -i ")?; + // Altered env vars will be printed next, that should exactly work as expected. + } else { + // Removed env vars need the command to be wrapped in `env`. + let mut any_removed = false; + for (key, value_opt) in self.get_envs() { + if value_opt.is_none() { + if !any_removed { + write!(f, "env ")?; + any_removed = true; + } + write!(f, "-u {} ", key.to_string_lossy())?; + } + } + } + // Altered env vars can just be added in front of the program. for (key, value_opt) in self.get_envs() { if let Some(value) = value_opt { write!(f, "{}={value:?} ", key.to_string_lossy())?; diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 3963e7f52..564f8c482 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -165,7 +165,7 @@ impl Command { assert!(p.wait().is_ok(), "wait() should either return Ok or panic"); return Err(Error::from_raw_os_error(errno)); } - Err(ref e) if e.kind() == ErrorKind::Interrupted => {} + Err(ref e) if e.is_interrupted() => {} Err(e) => { assert!(p.wait().is_ok(), "wait() should either return Ok or panic"); panic!("the CLOEXEC pipe failed: {e:?}") @@ -374,6 +374,13 @@ impl Command { return Err(io::Error::last_os_error()); } } + #[cfg(target_os = "hurd")] + { + let ret = sys::signal(libc::SIGLOST, libc::SIG_DFL); + if ret == libc::SIG_ERR { + return Err(io::Error::last_os_error()); + } + } } } @@ -620,6 +627,10 @@ impl Command { let mut default_set = MaybeUninit::<libc::sigset_t>::uninit(); cvt(sigemptyset(default_set.as_mut_ptr()))?; cvt(sigaddset(default_set.as_mut_ptr(), libc::SIGPIPE))?; + #[cfg(target_os = "hurd")] + { + cvt(sigaddset(default_set.as_mut_ptr(), libc::SIGLOST))?; + } cvt_nz(libc::posix_spawnattr_setsigdefault( attrs.0.as_mut_ptr(), default_set.as_ptr(), @@ -993,6 +1004,8 @@ fn signal_string(signal: i32) -> &'static str { target_os = "dragonfly" ))] libc::SIGINFO => " (SIGINFO)", + #[cfg(target_os = "hurd")] + libc::SIGLOST => " (SIGLOST)", _ => "", } } diff --git a/library/std/src/sys/unix/stack_overflow.rs b/library/std/src/sys/unix/stack_overflow.rs index b59d4ba26..73c530786 100644 --- a/library/std/src/sys/unix/stack_overflow.rs +++ b/library/std/src/sys/unix/stack_overflow.rs @@ -32,6 +32,7 @@ impl Drop for Handler { target_os = "macos", target_os = "dragonfly", target_os = "freebsd", + target_os = "hurd", target_os = "solaris", target_os = "illumos", target_os = "netbsd", @@ -193,6 +194,7 @@ mod imp { target_os = "macos", target_os = "dragonfly", target_os = "freebsd", + target_os = "hurd", target_os = "solaris", target_os = "illumos", target_os = "netbsd", diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 4f2d9cf36..311ed9502 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -182,6 +182,9 @@ impl Thread { } if let Some(f) = pthread_setname_np.get() { + #[cfg(target_os = "nto")] + let name = truncate_cstr::<{ libc::_NTO_THREAD_NAME_MAX as usize }>(name); + let res = unsafe { f(libc::pthread_self(), name.as_ptr()) }; debug_assert_eq!(res, 0); } @@ -213,7 +216,8 @@ impl Thread { target_os = "l4re", target_os = "emscripten", target_os = "redox", - target_os = "vxworks" + target_os = "vxworks", + target_os = "hurd", ))] pub fn set_name(_name: &CStr) { // Newlib, Emscripten, and VxWorks have no way to set a thread name. @@ -290,6 +294,7 @@ impl Drop for Thread { target_os = "ios", target_os = "tvos", target_os = "watchos", + target_os = "nto", ))] fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_WITH_NUL] { let mut result = [0; MAX_WITH_NUL]; @@ -305,6 +310,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> { target_os = "android", target_os = "emscripten", target_os = "fuchsia", + target_os = "hurd", target_os = "ios", target_os = "tvos", target_os = "linux", @@ -312,23 +318,38 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> { target_os = "solaris", target_os = "illumos", ))] { + #[allow(unused_assignments)] + #[allow(unused_mut)] + let mut quota = usize::MAX; + #[cfg(any(target_os = "android", target_os = "linux"))] { - let quota = cgroups::quota().max(1); + quota = cgroups::quota().max(1); let mut set: libc::cpu_set_t = unsafe { mem::zeroed() }; unsafe { if libc::sched_getaffinity(0, mem::size_of::<libc::cpu_set_t>(), &mut set) == 0 { let count = libc::CPU_COUNT(&set) as usize; let count = count.min(quota); - // SAFETY: affinity mask can't be empty and the quota gets clamped to a minimum of 1 - return Ok(NonZeroUsize::new_unchecked(count)); + + // According to sched_getaffinity's API it should always be non-zero, but + // some old MIPS kernels were buggy and zero-initialized the mask if + // none was explicitly set. + // In that case we use the sysconf fallback. + if let Some(count) = NonZeroUsize::new(count) { + return Ok(count) + } } } } match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { -1 => Err(io::Error::last_os_error()), 0 => Err(io::const_io_error!(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform")), - cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }), + cpus => { + let count = cpus as usize; + // Cover the unusual situation where we were able to get the quota but not the affinity mask + let count = count.min(quota); + Ok(unsafe { NonZeroUsize::new_unchecked(count) }) + } } } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] { use crate::ptr; @@ -686,6 +707,7 @@ mod cgroups { #[cfg(all( not(target_os = "linux"), not(target_os = "freebsd"), + not(target_os = "hurd"), not(target_os = "macos"), not(target_os = "netbsd"), not(target_os = "openbsd"), @@ -706,6 +728,7 @@ pub mod guard { #[cfg(any( target_os = "linux", target_os = "freebsd", + target_os = "hurd", target_os = "macos", target_os = "netbsd", target_os = "openbsd", @@ -762,6 +785,7 @@ pub mod guard { #[cfg(any( target_os = "android", target_os = "freebsd", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "l4re" @@ -899,6 +923,7 @@ pub mod guard { #[cfg(any( target_os = "android", target_os = "freebsd", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "l4re" @@ -930,7 +955,7 @@ pub mod guard { assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackptr, &mut size), 0); let stackaddr = stackptr.addr(); - ret = if cfg!(any(target_os = "freebsd", target_os = "netbsd")) { + ret = if cfg!(any(target_os = "freebsd", target_os = "netbsd", target_os = "hurd")) { Some(stackaddr - guardsize..stackaddr) } else if cfg!(all(target_os = "linux", target_env = "musl")) { Some(stackaddr - guardsize..stackaddr) diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs index 236d2f2ee..fba2a676f 100644 --- a/library/std/src/sys/unix/thread_local_dtor.rs +++ b/library/std/src/sys/unix/thread_local_dtor.rs @@ -11,7 +11,7 @@ // Note, however, that we run on lots older linuxes, as well as cross // compiling from a newer linux to an older linux, so we also have a // fallback implementation to use as well. -#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "redox"))] +#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "redox", target_os = "hurd"))] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { use crate::mem; use crate::sys_common::thread_local_dtor::register_dtor_fallback; @@ -48,7 +48,7 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { // workaround below is to register, via _tlv_atexit, a custom DTOR list once per // thread. thread_local dtors are pushed to the DTOR list without calling // _tlv_atexit. -#[cfg(target_os = "macos")] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { use crate::cell::Cell; use crate::mem; diff --git a/library/std/src/sys/unix/thread_parking/darwin.rs b/library/std/src/sys/unix/thread_parking/darwin.rs index b709fada3..8231f3cba 100644 --- a/library/std/src/sys/unix/thread_parking/darwin.rs +++ b/library/std/src/sys/unix/thread_parking/darwin.rs @@ -2,8 +2,7 @@ //! //! Darwin actually has futex syscalls (`__ulock_wait`/`__ulock_wake`), but they //! cannot be used in `std` because they are non-public (their use will lead to -//! rejection from the App Store) and because they are only available starting -//! with macOS version 10.12, even though the minimum target version is 10.7. +//! rejection from the App Store). //! //! Therefore, we need to look for other synchronization primitives. Luckily, Darwin //! supports semaphores, which allow us to implement the behaviour we need with diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index 17b4130c2..4fe61b284 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -35,7 +35,7 @@ pub(in crate::sys::unix) struct Timespec { } impl SystemTime { - #[cfg_attr(target_os = "horizon", allow(unused))] + #[cfg_attr(any(target_os = "horizon", target_os = "hurd"), allow(unused))] pub fn new(tv_sec: i64, tv_nsec: i64) -> SystemTime { SystemTime { t: Timespec::new(tv_sec, tv_nsec) } } |