about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/alloc.rs4
-rw-r--r--library/std/src/process.rs19
-rw-r--r--library/std/src/sys/pal/hermit/fd.rs39
-rw-r--r--library/std/src/sys/pal/hermit/fs.rs45
-rw-r--r--library/std/src/sys/pal/hermit/futex.rs2
-rw-r--r--library/std/src/sys/pal/hermit/io.rs82
-rw-r--r--library/std/src/sys/pal/hermit/mod.rs1
-rw-r--r--library/std/src/sys/pal/hermit/net.rs13
-rw-r--r--library/std/src/sys/pal/hermit/os.rs2
-rw-r--r--library/std/src/sys/pal/hermit/stdio.rs67
-rw-r--r--library/std/src/sys/pal/hermit/thread.rs2
-rw-r--r--library/std/src/sys/pal/hermit/time.rs18
-rw-r--r--library/std/src/sys/pal/unix/fs.rs21
13 files changed, 204 insertions, 111 deletions
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index b98fbbf762f..dc4924cdf58 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -73,7 +73,9 @@ pub use alloc_crate::alloc::*;
 /// work, such as to serve alignment requests greater than the alignment
 /// provided directly by the backing system allocator.
 ///
-/// This type implements the `GlobalAlloc` trait and Rust programs by default
+/// This type implements the [`GlobalAlloc`] trait. Currently the default
+/// global allocator is unspecified. Libraries, however, like `cdylib`s and
+/// `staticlib`s are guaranteed to use the [`System`] by default and as such
 /// work as if they had this definition:
 ///
 /// ```rust
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index c926c89f7a9..f351dab78dc 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -629,6 +629,25 @@ impl Command {
     ///     .spawn()
     ///     .expect("sh command failed to start");
     /// ```
+    ///
+    /// # Caveats
+    ///
+    /// [`Command::new`] is only intended to accept the path of the program. If you pass a program
+    /// path along with arguments like `Command::new("ls -l").spawn()`, it will try to search for
+    /// `ls -l` literally. The arguments need to be passed separately, such as via [`arg`] or
+    /// [`args`].
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// Command::new("ls")
+    ///     .arg("-l") // arg passed separately
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
+    /// ```
+    ///
+    /// [`arg`]: Self::arg
+    /// [`args`]: Self::args
     #[stable(feature = "process", since = "1.0.0")]
     pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
         Command { inner: imp::Command::new(program.as_ref()) }
diff --git a/library/std/src/sys/pal/hermit/fd.rs b/library/std/src/sys/pal/hermit/fd.rs
index d7dab08cfbd..3c52b85de23 100644
--- a/library/std/src/sys/pal/hermit/fd.rs
+++ b/library/std/src/sys/pal/hermit/fd.rs
@@ -1,7 +1,8 @@
 #![unstable(reason = "not public", issue = "none", feature = "fd")]
 
 use super::hermit_abi;
-use crate::io::{self, Read};
+use crate::cmp;
+use crate::io::{self, IoSlice, IoSliceMut, Read};
 use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd};
 use crate::sys::cvt;
 use crate::sys::unsupported;
@@ -9,6 +10,10 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
 
 use crate::os::hermit::io::*;
 
+const fn max_iov() -> usize {
+    hermit_abi::IOV_MAX
+}
+
 #[derive(Debug)]
 pub struct FileDesc {
     fd: OwnedFd,
@@ -21,6 +26,22 @@ impl FileDesc {
         Ok(result as usize)
     }
 
+    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        let ret = cvt(unsafe {
+            hermit_abi::readv(
+                self.as_raw_fd(),
+                bufs.as_mut_ptr() as *mut hermit_abi::iovec as *const hermit_abi::iovec,
+                cmp::min(bufs.len(), max_iov()),
+            )
+        })?;
+        Ok(ret as usize)
+    }
+
+    #[inline]
+    pub fn is_read_vectored(&self) -> bool {
+        true
+    }
+
     pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
         let mut me = self;
         (&mut me).read_to_end(buf)
@@ -32,6 +53,22 @@ impl FileDesc {
         Ok(result as usize)
     }
 
+    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        let ret = cvt(unsafe {
+            hermit_abi::writev(
+                self.as_raw_fd(),
+                bufs.as_ptr() as *const hermit_abi::iovec,
+                cmp::min(bufs.len(), max_iov()),
+            )
+        })?;
+        Ok(ret as usize)
+    }
+
+    #[inline]
+    pub fn is_write_vectored(&self) -> bool {
+        true
+    }
+
     pub fn duplicate(&self) -> io::Result<FileDesc> {
         self.duplicate_path(&[])
     }
diff --git a/library/std/src/sys/pal/hermit/fs.rs b/library/std/src/sys/pal/hermit/fs.rs
index a4a16e6e86b..a98a1006ef4 100644
--- a/library/std/src/sys/pal/hermit/fs.rs
+++ b/library/std/src/sys/pal/hermit/fs.rs
@@ -1,7 +1,7 @@
 use super::fd::FileDesc;
 use super::hermit_abi::{
     self, dirent64, stat as stat_struct, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT,
-    O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
+    O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
 };
 use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt;
@@ -62,7 +62,7 @@ pub struct DirEntry {
     /// 64-bit inode number
     ino: u64,
     /// File type
-    type_: u32,
+    type_: u8,
     /// name of the entry
     name: OsString,
 }
@@ -90,7 +90,7 @@ pub struct FilePermissions {
 
 #[derive(Copy, Clone, Eq, Debug)]
 pub struct FileType {
-    mode: u32,
+    mode: u8,
 }
 
 impl PartialEq for FileType {
@@ -112,31 +112,23 @@ pub struct DirBuilder {
 
 impl FileAttr {
     pub fn modified(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::new(
-            self.stat_val.st_mtime.try_into().unwrap(),
-            self.stat_val.st_mtime_nsec.try_into().unwrap(),
-        ))
+        Ok(SystemTime::new(self.stat_val.st_mtim.tv_sec, self.stat_val.st_mtim.tv_nsec))
     }
 
     pub fn accessed(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::new(
-            self.stat_val.st_atime.try_into().unwrap(),
-            self.stat_val.st_atime_nsec.try_into().unwrap(),
-        ))
+        Ok(SystemTime::new(self.stat_val.st_atim.tv_sec, self.stat_val.st_atim.tv_nsec))
     }
 
     pub fn created(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::new(
-            self.stat_val.st_ctime.try_into().unwrap(),
-            self.stat_val.st_ctime_nsec.try_into().unwrap(),
-        ))
+        Ok(SystemTime::new(self.stat_val.st_ctim.tv_sec, self.stat_val.st_ctim.tv_nsec))
     }
 
     pub fn size(&self) -> u64 {
         self.stat_val.st_size as u64
     }
+
     pub fn perm(&self) -> FilePermissions {
-        FilePermissions { mode: (self.stat_val.st_mode) }
+        FilePermissions { mode: self.stat_val.st_mode }
     }
 
     pub fn file_type(&self) -> FileType {
@@ -220,7 +212,7 @@ impl Iterator for ReadDir {
                 let entry = DirEntry {
                     root: self.inner.root.clone(),
                     ino: dir.d_ino,
-                    type_: dir.d_type as u32,
+                    type_: dir.d_type,
                     name: OsString::from_vec(name_bytes.to_vec()),
                 };
 
@@ -251,7 +243,7 @@ impl DirEntry {
     }
 
     pub fn file_type(&self) -> io::Result<FileType> {
-        Ok(FileType { mode: self.type_ as u32 })
+        Ok(FileType { mode: self.type_ })
     }
 
     #[allow(dead_code)]
@@ -385,12 +377,12 @@ impl File {
     }
 
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        crate::io::default_read_vectored(|buf| self.read(buf), bufs)
+        self.0.read_vectored(bufs)
     }
 
     #[inline]
     pub fn is_read_vectored(&self) -> bool {
-        false
+        self.0.is_read_vectored()
     }
 
     pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
@@ -402,12 +394,12 @@ impl File {
     }
 
     pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        crate::io::default_write_vectored(|buf| self.write(buf), bufs)
+        self.0.write_vectored(bufs)
     }
 
     #[inline]
     pub fn is_write_vectored(&self) -> bool {
-        false
+        self.0.is_write_vectored()
     }
 
     #[inline]
@@ -439,13 +431,13 @@ impl DirBuilder {
 
     pub fn mkdir(&self, path: &Path) -> io::Result<()> {
         run_path_with_cstr(path, &|path| {
-            cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode) }).map(|_| ())
+            cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode.into()) }).map(|_| ())
         })
     }
 
     #[allow(dead_code)]
     pub fn set_mode(&mut self, mode: u32) {
-        self.mode = mode as u32;
+        self.mode = mode;
     }
 }
 
@@ -501,8 +493,9 @@ impl FromRawFd for File {
 }
 
 pub fn readdir(path: &Path) -> io::Result<ReadDir> {
-    let fd_raw =
-        run_path_with_cstr(path, &|path| cvt(unsafe { hermit_abi::opendir(path.as_ptr()) }))?;
+    let fd_raw = run_path_with_cstr(path, &|path| {
+        cvt(unsafe { hermit_abi::open(path.as_ptr(), O_RDONLY | O_DIRECTORY, 0) })
+    })?;
     let fd = unsafe { FileDesc::from_raw_fd(fd_raw as i32) };
     let root = path.to_path_buf();
 
diff --git a/library/std/src/sys/pal/hermit/futex.rs b/library/std/src/sys/pal/hermit/futex.rs
index 571b2885658..b2d74d1311b 100644
--- a/library/std/src/sys/pal/hermit/futex.rs
+++ b/library/std/src/sys/pal/hermit/futex.rs
@@ -10,7 +10,7 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
     let timespec = timeout.and_then(|dur| {
         Some(hermit_abi::timespec {
             tv_sec: dur.as_secs().try_into().ok()?,
-            tv_nsec: dur.subsec_nanos().into(),
+            tv_nsec: dur.subsec_nanos().try_into().ok()?,
         })
     });
 
diff --git a/library/std/src/sys/pal/hermit/io.rs b/library/std/src/sys/pal/hermit/io.rs
new file mode 100644
index 00000000000..9de7b53e53c
--- /dev/null
+++ b/library/std/src/sys/pal/hermit/io.rs
@@ -0,0 +1,82 @@
+use crate::marker::PhantomData;
+use crate::os::hermit::io::{AsFd, AsRawFd};
+use crate::slice;
+
+use hermit_abi::{c_void, iovec};
+
+#[derive(Copy, Clone)]
+#[repr(transparent)]
+pub struct IoSlice<'a> {
+    vec: iovec,
+    _p: PhantomData<&'a [u8]>,
+}
+
+impl<'a> IoSlice<'a> {
+    #[inline]
+    pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
+        IoSlice {
+            vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
+            _p: PhantomData,
+        }
+    }
+
+    #[inline]
+    pub fn advance(&mut self, n: usize) {
+        if self.vec.iov_len < n {
+            panic!("advancing IoSlice beyond its length");
+        }
+
+        unsafe {
+            self.vec.iov_len -= n;
+            self.vec.iov_base = self.vec.iov_base.add(n);
+        }
+    }
+
+    #[inline]
+    pub fn as_slice(&self) -> &[u8] {
+        unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+    }
+}
+
+#[repr(transparent)]
+pub struct IoSliceMut<'a> {
+    vec: iovec,
+    _p: PhantomData<&'a mut [u8]>,
+}
+
+impl<'a> IoSliceMut<'a> {
+    #[inline]
+    pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
+        IoSliceMut {
+            vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
+            _p: PhantomData,
+        }
+    }
+
+    #[inline]
+    pub fn advance(&mut self, n: usize) {
+        if self.vec.iov_len < n {
+            panic!("advancing IoSliceMut beyond its length");
+        }
+
+        unsafe {
+            self.vec.iov_len -= n;
+            self.vec.iov_base = self.vec.iov_base.add(n);
+        }
+    }
+
+    #[inline]
+    pub fn as_slice(&self) -> &[u8] {
+        unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+    }
+
+    #[inline]
+    pub fn as_mut_slice(&mut self) -> &mut [u8] {
+        unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+    }
+}
+
+pub fn is_terminal(fd: &impl AsFd) -> bool {
+    let fd = fd.as_fd();
+    hermit_abi::isatty(fd.as_raw_fd())
+}
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index a64323a3a29..eca7351d54c 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -23,7 +23,6 @@ pub mod env;
 pub mod fd;
 pub mod fs;
 pub mod futex;
-#[path = "../unsupported/io.rs"]
 pub mod io;
 pub mod net;
 pub mod os;
diff --git a/library/std/src/sys/pal/hermit/net.rs b/library/std/src/sys/pal/hermit/net.rs
index 00dbca86a4b..6016d50eba0 100644
--- a/library/std/src/sys/pal/hermit/net.rs
+++ b/library/std/src/sys/pal/hermit/net.rs
@@ -175,12 +175,12 @@ impl Socket {
     }
 
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        crate::io::default_read_vectored(|b| self.read(b), bufs)
+        self.0.read_vectored(bufs)
     }
 
     #[inline]
     pub fn is_read_vectored(&self) -> bool {
-        false
+        self.0.is_read_vectored()
     }
 
     fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> {
@@ -209,16 +209,15 @@ impl Socket {
     }
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
-        let sz = cvt(unsafe { netc::write(self.0.as_raw_fd(), buf.as_ptr(), buf.len()) })?;
-        Ok(sz.try_into().unwrap())
+        self.0.write(buf)
     }
 
     pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        crate::io::default_write_vectored(|b| self.write(b), bufs)
+        self.0.write_vectored(bufs)
     }
 
     pub fn is_write_vectored(&self) -> bool {
-        false
+        self.0.is_write_vectored()
     }
 
     pub fn set_timeout(&self, dur: Option<Duration>, kind: i32) -> io::Result<()> {
@@ -265,7 +264,7 @@ impl Socket {
             Shutdown::Read => netc::SHUT_RD,
             Shutdown::Both => netc::SHUT_RDWR,
         };
-        cvt(unsafe { netc::shutdown_socket(self.as_raw_fd(), how) })?;
+        cvt(unsafe { netc::shutdown(self.as_raw_fd(), how) })?;
         Ok(())
     }
 
diff --git a/library/std/src/sys/pal/hermit/os.rs b/library/std/src/sys/pal/hermit/os.rs
index 91247d30462..a7a73c756f2 100644
--- a/library/std/src/sys/pal/hermit/os.rs
+++ b/library/std/src/sys/pal/hermit/os.rs
@@ -198,5 +198,5 @@ pub fn exit(code: i32) -> ! {
 }
 
 pub fn getpid() -> u32 {
-    unsafe { hermit_abi::getpid() }
+    unsafe { hermit_abi::getpid() as u32 }
 }
diff --git a/library/std/src/sys/pal/hermit/stdio.rs b/library/std/src/sys/pal/hermit/stdio.rs
index 777c57b391c..3ea00f5cc5e 100644
--- a/library/std/src/sys/pal/hermit/stdio.rs
+++ b/library/std/src/sys/pal/hermit/stdio.rs
@@ -1,6 +1,9 @@
 use super::hermit_abi;
 use crate::io;
 use crate::io::{IoSlice, IoSliceMut};
+use crate::mem::ManuallyDrop;
+use crate::os::hermit::io::FromRawFd;
+use crate::sys::fd::FileDesc;
 
 pub struct Stdin;
 pub struct Stdout;
@@ -13,12 +16,14 @@ impl Stdin {
 }
 
 impl io::Read for Stdin {
-    fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
-        self.read_vectored(&mut [IoSliceMut::new(data)])
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDIN_FILENO)).read(buf) }
     }
 
-    fn read_vectored(&mut self, _data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        Ok(0)
+    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        unsafe {
+            ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDIN_FILENO)).read_vectored(bufs)
+        }
     }
 
     #[inline]
@@ -34,27 +39,13 @@ impl Stdout {
 }
 
 impl io::Write for Stdout {
-    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-        let len;
-
-        unsafe { len = hermit_abi::write(1, data.as_ptr() as *const u8, data.len()) }
-
-        if len < 0 {
-            Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stdout is not able to print"))
-        } else {
-            Ok(len as usize)
-        }
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDOUT_FILENO)).write(buf) }
     }
 
-    fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
-        let len;
-
-        unsafe { len = hermit_abi::write(1, data.as_ptr() as *const u8, data.len()) }
-
-        if len < 0 {
-            Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stdout is not able to print"))
-        } else {
-            Ok(len as usize)
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        unsafe {
+            ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDOUT_FILENO)).write_vectored(bufs)
         }
     }
 
@@ -75,27 +66,13 @@ impl Stderr {
 }
 
 impl io::Write for Stderr {
-    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-        let len;
-
-        unsafe { len = hermit_abi::write(2, data.as_ptr() as *const u8, data.len()) }
-
-        if len < 0 {
-            Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stderr is not able to print"))
-        } else {
-            Ok(len as usize)
-        }
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDERR_FILENO)).write(buf) }
     }
 
-    fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
-        let len;
-
-        unsafe { len = hermit_abi::write(2, data.as_ptr() as *const u8, data.len()) }
-
-        if len < 0 {
-            Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stderr is not able to print"))
-        } else {
-            Ok(len as usize)
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        unsafe {
+            ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDERR_FILENO)).write_vectored(bufs)
         }
     }
 
@@ -109,10 +86,10 @@ impl io::Write for Stderr {
     }
 }
 
-pub const STDIN_BUF_SIZE: usize = 0;
+pub const STDIN_BUF_SIZE: usize = 128;
 
-pub fn is_ebadf(_err: &io::Error) -> bool {
-    true
+pub fn is_ebadf(err: &io::Error) -> bool {
+    err.raw_os_error() == Some(hermit_abi::EBADF)
 }
 
 pub fn panic_output() -> Option<impl io::Write> {
diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs
index b336dcd6860..07a843a597e 100644
--- a/library/std/src/sys/pal/hermit/thread.rs
+++ b/library/std/src/sys/pal/hermit/thread.rs
@@ -98,5 +98,5 @@ impl Thread {
 }
 
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
-    unsafe { Ok(NonZero::new_unchecked(hermit_abi::get_processor_count())) }
+    unsafe { Ok(NonZero::new_unchecked(hermit_abi::available_parallelism())) }
 }
diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs
index 2bf24462fa8..e0cb7c2aa98 100644
--- a/library/std/src/sys/pal/hermit/time.rs
+++ b/library/std/src/sys/pal/hermit/time.rs
@@ -1,11 +1,13 @@
 #![allow(dead_code)]
 
-use super::hermit_abi::{self, timespec, CLOCK_MONOTONIC, CLOCK_REALTIME, NSEC_PER_SEC};
+use super::hermit_abi::{self, timespec, CLOCK_MONOTONIC, CLOCK_REALTIME};
 use crate::cmp::Ordering;
 use crate::ops::{Add, AddAssign, Sub, SubAssign};
 use crate::time::Duration;
 use core::hash::{Hash, Hasher};
 
+const NSEC_PER_SEC: i32 = 1_000_000_000;
+
 #[derive(Copy, Clone, Debug)]
 struct Timespec {
     t: timespec,
@@ -16,8 +18,8 @@ impl Timespec {
         Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } }
     }
 
-    const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec {
-        assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64);
+    const fn new(tv_sec: i64, tv_nsec: i32) -> Timespec {
+        assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC);
         // SAFETY: The assert above checks tv_nsec is within the valid range
         Timespec { t: timespec { tv_sec: tv_sec, tv_nsec: tv_nsec } }
     }
@@ -32,7 +34,7 @@ impl Timespec {
             } else {
                 Duration::new(
                     (self.t.tv_sec - 1 - other.t.tv_sec) as u64,
-                    self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
+                    (self.t.tv_nsec + NSEC_PER_SEC - other.t.tv_nsec) as u32,
                 )
             })
         } else {
@@ -48,9 +50,9 @@ impl Timespec {
 
         // Nano calculations can't overflow because nanos are <1B which fit
         // in a u32.
-        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
-        if nsec >= NSEC_PER_SEC as u32 {
-            nsec -= NSEC_PER_SEC as u32;
+        let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap();
+        if nsec >= NSEC_PER_SEC.try_into().unwrap() {
+            nsec -= u32::try_from(NSEC_PER_SEC).unwrap();
             secs = secs.checked_add(1)?;
         }
         Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
@@ -200,7 +202,7 @@ pub struct SystemTime(Timespec);
 pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero());
 
 impl SystemTime {
-    pub fn new(tv_sec: i64, tv_nsec: i64) -> SystemTime {
+    pub fn new(tv_sec: i64, tv_nsec: i32) -> SystemTime {
         SystemTime(Timespec::new(tv_sec, tv_nsec))
     }
 
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 56a0f8e39c4..035c92bc84b 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -22,16 +22,12 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 
 #[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
 use crate::sys::weak::syscall;
-#[cfg(any(target_os = "android", target_os = "macos", target_os = "solaris"))]
+#[cfg(target_os = "android")]
 use crate::sys::weak::weak;
 
 use libc::{c_int, mode_t};
 
-#[cfg(any(
-    target_os = "solaris",
-    all(target_os = "linux", target_env = "gnu"),
-    target_vendor = "apple",
-))]
+#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
 use libc::c_char;
 #[cfg(any(
     all(target_os = "linux", not(target_env = "musl")),
@@ -1753,19 +1749,6 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
                     // Android has `linkat` on newer versions, but we happen to know `link`
                     // always has the correct behavior, so it's here as well.
                     cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
-                } else if #[cfg(any(target_os = "macos", target_os = "solaris"))] {
-                    // MacOS (<=10.9) and Solaris 10 lack support for linkat while newer
-                    // versions have it. We want to use linkat if it is available, so we use weak!
-                    // to check. `linkat` is preferable to `link` because it gives us a flag to
-                    // specify how symlinks should be handled. We pass 0 as the flags argument,
-                    // meaning it shouldn't follow symlinks.
-                    weak!(fn linkat(c_int, *const c_char, c_int, *const c_char, c_int) -> c_int);
-
-                    if let Some(f) = linkat.get() {
-                        cvt(unsafe { f(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
-                    } else {
-                        cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
-                    };
                 } else {
                     // Where we can, use `linkat` instead of `link`; see the comment above
                     // this one for details on why.