about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-04-02 22:22:18 +0000
committerGitHub <noreply@github.com>2025-04-02 22:22:18 +0000
commit5103bdeb29d7aa4d7ad4d811893c76baa8a98ab7 (patch)
treec989d04f4bcd32bcd93ed62208af68e1dbe36b6d /library/std/src
parent4858c3fe7d1a9a7484db4998199f6deb1e05185a (diff)
parente435ba32d85057070dba3f07fa8afd96799a0cfb (diff)
Merge pull request #4245 from RalfJung/rustup
Rustup
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/fs.rs34
-rw-r--r--library/std/src/fs/tests.rs17
-rw-r--r--library/std/src/io/mod.rs8
-rw-r--r--library/std/src/io/stdio.rs63
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/net/tcp/tests.rs8
-rw-r--r--library/std/src/os/fd/owned.rs9
-rw-r--r--library/std/src/os/fd/raw.rs9
-rw-r--r--library/std/src/process.rs2
-rw-r--r--library/std/src/sync/mod.rs2
-rw-r--r--library/std/src/sys/fs/mod.rs101
-rw-r--r--library/std/src/sys/fs/uefi.rs108
-rw-r--r--library/std/src/sys/fs/unix.rs195
-rw-r--r--library/std/src/sys/fs/windows.rs35
-rw-r--r--library/std/src/sys/mod.rs1
-rw-r--r--library/std/src/sys/net/connection/xous/tcpstream.rs2
-rw-r--r--library/std/src/sys/pal/hermit/mod.rs2
-rw-r--r--library/std/src/sys/pal/sgx/mod.rs2
-rw-r--r--library/std/src/sys/pal/solid/mod.rs2
-rw-r--r--library/std/src/sys/pal/teeos/mod.rs2
-rw-r--r--library/std/src/sys/pal/trusty/mod.rs2
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs86
-rw-r--r--library/std/src/sys/pal/uefi/mod.rs11
-rw-r--r--library/std/src/sys/pal/unix/fd.rs52
-rw-r--r--library/std/src/sys/pal/unix/fuchsia.rs (renamed from library/std/src/sys/pal/unix/process/zircon.rs)0
-rw-r--r--library/std/src/sys/pal/unix/kernel_copy.rs16
-rw-r--r--library/std/src/sys/pal/unix/mod.rs5
-rw-r--r--library/std/src/sys/pal/unix/os.rs8
-rw-r--r--library/std/src/sys/pal/unix/process/mod.rs27
-rw-r--r--library/std/src/sys/pal/unix/stack_overflow.rs117
-rw-r--r--library/std/src/sys/pal/unix/thread.rs18
-rw-r--r--library/std/src/sys/pal/unix/time.rs7
-rw-r--r--library/std/src/sys/pal/unix/weak.rs40
-rw-r--r--library/std/src/sys/pal/unsupported/mod.rs1
-rw-r--r--library/std/src/sys/pal/wasi/mod.rs2
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs2
-rw-r--r--library/std/src/sys/pal/wasip2/mod.rs2
-rw-r--r--library/std/src/sys/pal/wasm/atomics/thread.rs2
-rw-r--r--library/std/src/sys/pal/wasm/mod.rs2
-rw-r--r--library/std/src/sys/pal/windows/args.rs2
-rw-r--r--library/std/src/sys/pal/windows/mod.rs9
-rw-r--r--library/std/src/sys/pal/windows/pipe.rs28
-rw-r--r--library/std/src/sys/pal/xous/mod.rs2
-rw-r--r--library/std/src/sys/pal/zkvm/mod.rs2
-rw-r--r--library/std/src/sys/process/mod.rs19
-rw-r--r--library/std/src/sys/process/uefi.rs (renamed from library/std/src/sys/pal/uefi/process.rs)10
-rw-r--r--library/std/src/sys/process/unix/common.rs (renamed from library/std/src/sys/pal/unix/process/process_common.rs)2
-rw-r--r--library/std/src/sys/process/unix/common/tests.rs (renamed from library/std/src/sys/pal/unix/process/process_common/tests.rs)0
-rw-r--r--library/std/src/sys/process/unix/fuchsia.rs (renamed from library/std/src/sys/pal/unix/process/process_fuchsia.rs)14
-rw-r--r--library/std/src/sys/process/unix/mod.rs23
-rw-r--r--library/std/src/sys/process/unix/unix.rs (renamed from library/std/src/sys/pal/unix/process/process_unix.rs)60
-rw-r--r--library/std/src/sys/process/unix/unix/tests.rs (renamed from library/std/src/sys/pal/unix/process/process_unix/tests.rs)0
-rw-r--r--library/std/src/sys/process/unix/unsupported.rs (renamed from library/std/src/sys/pal/unix/process/process_unsupported.rs)4
-rw-r--r--library/std/src/sys/process/unix/unsupported/wait_status.rs (renamed from library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs)7
-rw-r--r--library/std/src/sys/process/unix/unsupported/wait_status/tests.rs (renamed from library/std/src/sys/pal/unix/process/process_unsupported/wait_status/tests.rs)2
-rw-r--r--library/std/src/sys/process/unix/vxworks.rs (renamed from library/std/src/sys/pal/unix/process/process_vxworks.rs)6
-rw-r--r--library/std/src/sys/process/unsupported.rs (renamed from library/std/src/sys/pal/unsupported/process.rs)0
-rw-r--r--library/std/src/sys/process/windows.rs (renamed from library/std/src/sys/pal/windows/process.rs)25
-rw-r--r--library/std/src/sys/process/windows/tests.rs (renamed from library/std/src/sys/pal/windows/process/tests.rs)0
-rw-r--r--library/std/src/sys/random/linux.rs8
-rw-r--r--library/std/src/sys/random/trusty.rs2
-rw-r--r--library/std/src/sys/stdio/sgx.rs12
-rw-r--r--library/std/src/sys/stdio/solid.rs59
-rw-r--r--library/std/src/sys/stdio/teeos.rs53
-rw-r--r--library/std/src/sys/stdio/unix.rs12
-rw-r--r--library/std/src/sys/stdio/unsupported.rs71
-rw-r--r--library/std/src/sys/stdio/xous.rs27
-rw-r--r--library/std/src/thread/spawnhook.rs23
-rw-r--r--library/std/src/thread/tests.rs5
69 files changed, 898 insertions, 592 deletions
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index f9a360585e8..801baf3d990 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -665,6 +665,7 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
+    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -673,7 +674,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
+    #[unstable(feature = "file_lock", issue = "130994")]
     pub fn lock(&self) -> io::Result<()> {
         self.inner.lock()
     }
@@ -717,6 +718,7 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
+    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -725,7 +727,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
+    #[unstable(feature = "file_lock", issue = "130994")]
     pub fn lock_shared(&self) -> io::Result<()> {
         self.inner.lock_shared()
     }
@@ -774,6 +776,7 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
+    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -782,7 +785,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
+    #[unstable(feature = "file_lock", issue = "130994")]
     pub fn try_lock(&self) -> io::Result<bool> {
         self.inner.try_lock()
     }
@@ -830,6 +833,7 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
+    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -838,7 +842,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
+    #[unstable(feature = "file_lock", issue = "130994")]
     pub fn try_lock_shared(&self) -> io::Result<bool> {
         self.inner.try_lock_shared()
     }
@@ -866,6 +870,7 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
+    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -875,7 +880,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
+    #[unstable(feature = "file_lock", issue = "130994")]
     pub fn unlock(&self) -> io::Result<()> {
         self.inner.unlock()
     }
@@ -1343,6 +1348,9 @@ impl Seek for Arc<File> {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         (&**self).seek(pos)
     }
+    fn stream_position(&mut self) -> io::Result<u64> {
+        (&**self).stream_position()
+    }
 }
 
 impl OpenOptions {
@@ -2362,7 +2370,7 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
 #[doc(alias = "rm", alias = "unlink", alias = "DeleteFile")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
-    fs_imp::unlink(path.as_ref())
+    fs_imp::remove_file(path.as_ref())
 }
 
 /// Given a path, queries the file system to get information about a file,
@@ -2401,7 +2409,7 @@ pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
 #[doc(alias = "stat")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
-    fs_imp::stat(path.as_ref()).map(Metadata)
+    fs_imp::metadata(path.as_ref()).map(Metadata)
 }
 
 /// Queries the metadata about a file without following symlinks.
@@ -2436,7 +2444,7 @@ pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
 #[doc(alias = "lstat")]
 #[stable(feature = "symlink_metadata", since = "1.1.0")]
 pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
-    fs_imp::lstat(path.as_ref()).map(Metadata)
+    fs_imp::symlink_metadata(path.as_ref()).map(Metadata)
 }
 
 /// Renames a file or directory to a new name, replacing the original file if
@@ -2590,7 +2598,7 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
 #[doc(alias = "CreateHardLink", alias = "linkat")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
-    fs_imp::link(original.as_ref(), link.as_ref())
+    fs_imp::hard_link(original.as_ref(), link.as_ref())
 }
 
 /// Creates a new symbolic link on the filesystem.
@@ -2656,7 +2664,7 @@ pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Re
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
-    fs_imp::readlink(path.as_ref())
+    fs_imp::read_link(path.as_ref())
 }
 
 /// Returns the canonical, absolute form of a path with all intermediate
@@ -2832,7 +2840,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 #[doc(alias = "rmdir", alias = "RemoveDirectory")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
-    fs_imp::rmdir(path.as_ref())
+    fs_imp::remove_dir(path.as_ref())
 }
 
 /// Removes a directory at this path, after removing all its contents. Use
@@ -2959,7 +2967,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 #[doc(alias = "ls", alias = "opendir", alias = "FindFirstFile", alias = "FindNextFile")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
-    fs_imp::readdir(path.as_ref()).map(ReadDir)
+    fs_imp::read_dir(path.as_ref()).map(ReadDir)
 }
 
 /// Changes the permissions found on a file or a directory.
@@ -2995,7 +3003,7 @@ pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
 #[doc(alias = "chmod", alias = "SetFileAttributes")]
 #[stable(feature = "set_permissions", since = "1.1.0")]
 pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()> {
-    fs_imp::set_perm(path.as_ref(), perm.0)
+    fs_imp::set_permissions(path.as_ref(), perm.0)
 }
 
 impl DirBuilder {
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 6dd18e4f4c8..4712e58980c 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1719,6 +1719,23 @@ fn test_eq_direntry_metadata() {
     }
 }
 
+/// Test that windows file type equality is not affected by attributes unrelated
+/// to the file type.
+#[test]
+#[cfg(target_os = "windows")]
+fn test_eq_windows_file_type() {
+    let tmpdir = tmpdir();
+    let file1 = File::create(tmpdir.join("file1")).unwrap();
+    let file2 = File::create(tmpdir.join("file2")).unwrap();
+    assert_eq!(file1.metadata().unwrap().file_type(), file2.metadata().unwrap().file_type());
+
+    // Change the readonly attribute of one file.
+    let mut perms = file1.metadata().unwrap().permissions();
+    perms.set_readonly(true);
+    file1.set_permissions(perms).unwrap();
+    assert_eq!(file1.metadata().unwrap().file_type(), file2.metadata().unwrap().file_type());
+}
+
 /// Regression test for https://github.com/rust-lang/rust/issues/50619.
 #[test]
 #[cfg(target_os = "linux")]
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 6579b6887aa..314cbb45d49 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -2989,11 +2989,11 @@ impl<T: Read> Read for Take<T> {
             return Ok(());
         }
 
-        if self.limit <= buf.capacity() as u64 {
-            // if we just use an as cast to convert, limit may wrap around on a 32 bit target
-            let limit = cmp::min(self.limit, usize::MAX as u64) as usize;
+        if self.limit < buf.capacity() as u64 {
+            // The condition above guarantees that `self.limit` fits in `usize`.
+            let limit = self.limit as usize;
 
-            let extra_init = cmp::min(limit as usize, buf.init_ref().len());
+            let extra_init = cmp::min(limit, buf.init_ref().len());
 
             // SAFETY: no uninit data is written to ibuf
             let ibuf = unsafe { &mut buf.as_mut()[..limit] };
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index ce46241f8e8..8fc16331339 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -97,15 +97,15 @@ const fn stderr_raw() -> StderrRaw {
 
 impl Read for StdinRaw {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        handle_ebadf(self.0.read(buf), 0)
+        handle_ebadf(self.0.read(buf), || Ok(0))
     }
 
     fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
-        handle_ebadf(self.0.read_buf(buf), ())
+        handle_ebadf(self.0.read_buf(buf), || Ok(()))
     }
 
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        handle_ebadf(self.0.read_vectored(bufs), 0)
+        handle_ebadf(self.0.read_vectored(bufs), || Ok(0))
     }
 
     #[inline]
@@ -113,23 +113,37 @@ impl Read for StdinRaw {
         self.0.is_read_vectored()
     }
 
+    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
+        if buf.is_empty() {
+            return Ok(());
+        }
+        handle_ebadf(self.0.read_exact(buf), || Err(io::Error::READ_EXACT_EOF))
+    }
+
+    fn read_buf_exact(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        if buf.capacity() == 0 {
+            return Ok(());
+        }
+        handle_ebadf(self.0.read_buf_exact(buf), || Err(io::Error::READ_EXACT_EOF))
+    }
+
     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
-        handle_ebadf(self.0.read_to_end(buf), 0)
+        handle_ebadf(self.0.read_to_end(buf), || Ok(0))
     }
 
     fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
-        handle_ebadf(self.0.read_to_string(buf), 0)
+        handle_ebadf(self.0.read_to_string(buf), || Ok(0))
     }
 }
 
 impl Write for StdoutRaw {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        handle_ebadf(self.0.write(buf), buf.len())
+        handle_ebadf(self.0.write(buf), || Ok(buf.len()))
     }
 
     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        let total = || bufs.iter().map(|b| b.len()).sum();
-        handle_ebadf_lazy(self.0.write_vectored(bufs), total)
+        let total = || Ok(bufs.iter().map(|b| b.len()).sum());
+        handle_ebadf(self.0.write_vectored(bufs), total)
     }
 
     #[inline]
@@ -138,30 +152,30 @@ impl Write for StdoutRaw {
     }
 
     fn flush(&mut self) -> io::Result<()> {
-        handle_ebadf(self.0.flush(), ())
+        handle_ebadf(self.0.flush(), || Ok(()))
     }
 
     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
-        handle_ebadf(self.0.write_all(buf), ())
+        handle_ebadf(self.0.write_all(buf), || Ok(()))
     }
 
     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
-        handle_ebadf(self.0.write_all_vectored(bufs), ())
+        handle_ebadf(self.0.write_all_vectored(bufs), || Ok(()))
     }
 
     fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
-        handle_ebadf(self.0.write_fmt(fmt), ())
+        handle_ebadf(self.0.write_fmt(fmt), || Ok(()))
     }
 }
 
 impl Write for StderrRaw {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        handle_ebadf(self.0.write(buf), buf.len())
+        handle_ebadf(self.0.write(buf), || Ok(buf.len()))
     }
 
     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        let total = || bufs.iter().map(|b| b.len()).sum();
-        handle_ebadf_lazy(self.0.write_vectored(bufs), total)
+        let total = || Ok(bufs.iter().map(|b| b.len()).sum());
+        handle_ebadf(self.0.write_vectored(bufs), total)
     }
 
     #[inline]
@@ -170,32 +184,25 @@ impl Write for StderrRaw {
     }
 
     fn flush(&mut self) -> io::Result<()> {
-        handle_ebadf(self.0.flush(), ())
+        handle_ebadf(self.0.flush(), || Ok(()))
     }
 
     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
-        handle_ebadf(self.0.write_all(buf), ())
+        handle_ebadf(self.0.write_all(buf), || Ok(()))
     }
 
     fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
-        handle_ebadf(self.0.write_all_vectored(bufs), ())
+        handle_ebadf(self.0.write_all_vectored(bufs), || Ok(()))
     }
 
     fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
-        handle_ebadf(self.0.write_fmt(fmt), ())
-    }
-}
-
-fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
-    match r {
-        Err(ref e) if stdio::is_ebadf(e) => Ok(default),
-        r => r,
+        handle_ebadf(self.0.write_fmt(fmt), || Ok(()))
     }
 }
 
-fn handle_ebadf_lazy<T>(r: io::Result<T>, default: impl FnOnce() -> T) -> io::Result<T> {
+fn handle_ebadf<T>(r: io::Result<T>, default: impl FnOnce() -> io::Result<T>) -> io::Result<T> {
     match r {
-        Err(ref e) if stdio::is_ebadf(e) => Ok(default()),
+        Err(ref e) if stdio::is_ebadf(e) => default(),
         r => r,
     }
 }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index ad005833ad5..9dcedaa13f6 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -297,6 +297,7 @@
 #![feature(extended_varargs_abi_support)]
 #![feature(f128)]
 #![feature(f16)]
+#![feature(ffi_const)]
 #![feature(formatting_options)]
 #![feature(if_let_guard)]
 #![feature(intra_doc_pointers)]
diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs
index a7b5cdf4ec0..03003037b29 100644
--- a/library/std/src/net/tcp/tests.rs
+++ b/library/std/src/net/tcp/tests.rs
@@ -315,12 +315,8 @@ fn read_buf() {
         let mut buf = BorrowedBuf::from(buf.as_mut_slice());
         t!(s.read_buf(buf.unfilled()));
         assert_eq!(buf.filled(), &[1, 2, 3, 4]);
-
-        // FIXME: sgx uses default_read_buf that initializes the buffer.
-        if cfg!(not(target_env = "sgx")) {
-            // TcpStream::read_buf should omit buffer initialization.
-            assert_eq!(buf.init_len(), 4);
-        }
+        // TcpStream::read_buf should omit buffer initialization.
+        assert_eq!(buf.init_len(), 4);
 
         t.join().ok().expect("thread panicked");
     })
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 2dcbfc96618..be73e7dee9c 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -15,9 +15,8 @@ use crate::mem::ManuallyDrop;
     target_os = "trusty"
 )))]
 use crate::sys::cvt;
-use crate::sys_common::FromInner;
 #[cfg(not(target_os = "trusty"))]
-use crate::sys_common::{AsInner, IntoInner};
+use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::{fmt, io};
 
 type ValidRawFd = core::num::niche_types::NotAllOnes<RawFd>;
@@ -507,6 +506,7 @@ impl<'a> AsFd for io::StderrLock<'a> {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl AsFd for io::PipeReader {
     fn as_fd(&self) -> BorrowedFd<'_> {
         self.0.as_fd()
@@ -514,6 +514,7 @@ impl AsFd for io::PipeReader {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl From<io::PipeReader> for OwnedFd {
     fn from(pipe: io::PipeReader) -> Self {
         pipe.0.into_inner()
@@ -521,6 +522,7 @@ impl From<io::PipeReader> for OwnedFd {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl AsFd for io::PipeWriter {
     fn as_fd(&self) -> BorrowedFd<'_> {
         self.0.as_fd()
@@ -528,6 +530,7 @@ impl AsFd for io::PipeWriter {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl From<io::PipeWriter> for OwnedFd {
     fn from(pipe: io::PipeWriter) -> Self {
         pipe.0.into_inner()
@@ -535,6 +538,7 @@ impl From<io::PipeWriter> for OwnedFd {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl From<OwnedFd> for io::PipeReader {
     fn from(owned_fd: OwnedFd) -> Self {
         Self(FromInner::from_inner(owned_fd))
@@ -542,6 +546,7 @@ impl From<OwnedFd> for io::PipeReader {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl From<OwnedFd> for io::PipeWriter {
     fn from(owned_fd: OwnedFd) -> Self {
         Self(FromInner::from_inner(owned_fd))
diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs
index 596b21a5204..c800c1489ad 100644
--- a/library/std/src/os/fd/raw.rs
+++ b/library/std/src/os/fd/raw.rs
@@ -18,9 +18,8 @@ use crate::os::unix::io::AsFd;
 use crate::os::unix::io::OwnedFd;
 #[cfg(target_os = "wasi")]
 use crate::os::wasi::io::OwnedFd;
-use crate::sys_common::FromInner;
 #[cfg(not(target_os = "trusty"))]
-use crate::sys_common::{AsInner, IntoInner};
+use crate::sys_common::{AsInner, FromInner, IntoInner};
 
 /// Raw file descriptors.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -287,6 +286,7 @@ impl<T: AsRawFd> AsRawFd for Box<T> {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl AsRawFd for io::PipeReader {
     fn as_raw_fd(&self) -> RawFd {
         self.0.as_raw_fd()
@@ -294,6 +294,7 @@ impl AsRawFd for io::PipeReader {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl FromRawFd for io::PipeReader {
     unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
         Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) })
@@ -301,6 +302,7 @@ impl FromRawFd for io::PipeReader {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl IntoRawFd for io::PipeReader {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_raw_fd()
@@ -308,6 +310,7 @@ impl IntoRawFd for io::PipeReader {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl AsRawFd for io::PipeWriter {
     fn as_raw_fd(&self) -> RawFd {
         self.0.as_raw_fd()
@@ -315,6 +318,7 @@ impl AsRawFd for io::PipeWriter {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl FromRawFd for io::PipeWriter {
     unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
         Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) })
@@ -322,6 +326,7 @@ impl FromRawFd for io::PipeWriter {
 }
 
 #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[cfg(not(target_os = "trusty"))]
 impl IntoRawFd for io::PipeWriter {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_raw_fd()
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index f81ce8e1a1a..3b765a9537b 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1836,7 +1836,7 @@ impl crate::sealed::Sealed for ExitStatusError {}
 /// # if cfg!(unix) {
 /// use std::process::{Command, ExitStatusError};
 ///
-/// fn run(cmd: &str) -> Result<(),ExitStatusError> {
+/// fn run(cmd: &str) -> Result<(), ExitStatusError> {
 ///     Command::new(cmd).status().unwrap().exit_ok()?;
 ///     Ok(())
 /// }
diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs
index 5b50a3c6ccf..e67b4f6f22f 100644
--- a/library/std/src/sync/mod.rs
+++ b/library/std/src/sync/mod.rs
@@ -176,6 +176,8 @@ pub use core::sync::Exclusive;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::sync::atomic;
 
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+pub use alloc_crate::sync::UniqueArc;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use alloc_crate::sync::{Arc, Weak};
 
diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs
index c2e19eb393a..3b176d0d16c 100644
--- a/library/std/src/sys/fs/mod.rs
+++ b/library/std/src/sys/fs/mod.rs
@@ -1,28 +1,115 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 
+use crate::io;
+use crate::path::{Path, PathBuf};
+
 pub mod common;
 
 cfg_if::cfg_if! {
     if #[cfg(target_family = "unix")] {
         mod unix;
-        pub use unix::*;
+        use unix as imp;
+        pub use unix::{chown, fchown, lchown};
+        #[cfg(not(target_os = "fuchsia"))]
+        pub use unix::chroot;
+        pub(crate) use unix::debug_assert_fd_is_open;
+        #[cfg(any(target_os = "linux", target_os = "android"))]
+        pub(crate) use unix::CachedFileMetadata;
+        use crate::sys::common::small_c_string::run_path_with_cstr as with_native_path;
     } else if #[cfg(target_os = "windows")] {
         mod windows;
-        pub use windows::*;
+        use windows as imp;
+        pub use windows::{symlink_inner, junction_point};
     } else if #[cfg(target_os = "hermit")] {
         mod hermit;
-        pub use hermit::*;
+        use hermit as imp;
     } else if #[cfg(target_os = "solid_asp3")] {
         mod solid;
-        pub use solid::*;
+        use solid as imp;
     } else if #[cfg(target_os = "uefi")] {
         mod uefi;
-        pub use uefi::*;
+        use uefi as imp;
     } else if #[cfg(target_os = "wasi")] {
         mod wasi;
-        pub use wasi::*;
+        use wasi as imp;
     } else {
         mod unsupported;
-        pub use unsupported::*;
+        use unsupported as imp;
     }
 }
+
+// FIXME: Replace this with platform-specific path conversion functions.
+#[cfg(not(target_family = "unix"))]
+#[inline]
+pub fn with_native_path<T>(path: &Path, f: &dyn Fn(&Path) -> io::Result<T>) -> io::Result<T> {
+    f(path)
+}
+
+pub use imp::{
+    DirBuilder, DirEntry, File, FileAttr, FilePermissions, FileTimes, FileType, OpenOptions,
+    ReadDir,
+};
+
+pub fn read_dir(path: &Path) -> io::Result<ReadDir> {
+    // FIXME: use with_native_path
+    imp::readdir(path)
+}
+
+pub fn remove_file(path: &Path) -> io::Result<()> {
+    with_native_path(path, &imp::unlink)
+}
+
+pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
+    with_native_path(old, &|old| with_native_path(new, &|new| imp::rename(old, new)))
+}
+
+pub fn remove_dir(path: &Path) -> io::Result<()> {
+    with_native_path(path, &imp::rmdir)
+}
+
+pub fn remove_dir_all(path: &Path) -> io::Result<()> {
+    // FIXME: use with_native_path
+    imp::remove_dir_all(path)
+}
+
+pub fn read_link(path: &Path) -> io::Result<PathBuf> {
+    with_native_path(path, &imp::readlink)
+}
+
+pub fn symlink(original: &Path, link: &Path) -> io::Result<()> {
+    with_native_path(original, &|original| {
+        with_native_path(link, &|link| imp::symlink(original, link))
+    })
+}
+
+pub fn hard_link(original: &Path, link: &Path) -> io::Result<()> {
+    with_native_path(original, &|original| {
+        with_native_path(link, &|link| imp::link(original, link))
+    })
+}
+
+pub fn metadata(path: &Path) -> io::Result<FileAttr> {
+    with_native_path(path, &imp::stat)
+}
+
+pub fn symlink_metadata(path: &Path) -> io::Result<FileAttr> {
+    with_native_path(path, &imp::lstat)
+}
+
+pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> {
+    with_native_path(path, &|path| imp::set_perm(path, perm.clone()))
+}
+
+pub fn canonicalize(path: &Path) -> io::Result<PathBuf> {
+    with_native_path(path, &imp::canonicalize)
+}
+
+pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
+    // FIXME: use with_native_path
+    imp::copy(from, to)
+}
+
+pub fn exists(path: &Path) -> io::Result<bool> {
+    // FIXME: use with_native_path
+    imp::exists(path)
+}
diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs
index defc1681d38..d6ae86bd3d2 100644
--- a/library/std/src/sys/fs/uefi.rs
+++ b/library/std/src/sys/fs/uefi.rs
@@ -1,3 +1,5 @@
+use r_efi::protocols::file;
+
 use crate::ffi::OsString;
 use crate::fmt;
 use crate::hash::Hash;
@@ -22,7 +24,12 @@ pub struct ReadDir(!);
 pub struct DirEntry(!);
 
 #[derive(Clone, Debug)]
-pub struct OpenOptions {}
+pub struct OpenOptions {
+    mode: u64,
+    append: bool,
+    truncate: bool,
+    create_new: bool,
+}
 
 #[derive(Copy, Clone, Debug, Default)]
 pub struct FileTimes {}
@@ -36,7 +43,7 @@ pub struct FilePermissions(bool);
 pub struct FileType(bool);
 
 #[derive(Debug)]
-pub struct DirBuilder {}
+pub struct DirBuilder;
 
 impl FileAttr {
     pub fn size(&self) -> u64 {
@@ -141,15 +148,58 @@ impl DirEntry {
 
 impl OpenOptions {
     pub fn new() -> OpenOptions {
-        OpenOptions {}
+        OpenOptions { mode: 0, append: false, create_new: false, truncate: false }
+    }
+
+    pub fn read(&mut self, read: bool) {
+        if read {
+            self.mode |= file::MODE_READ;
+        } else {
+            self.mode &= !file::MODE_READ;
+        }
+    }
+
+    pub fn write(&mut self, write: bool) {
+        if write {
+            // Valid Combinations: Read, Read/Write, Read/Write/Create
+            self.read(true);
+            self.mode |= file::MODE_WRITE;
+        } else {
+            self.mode &= !file::MODE_WRITE;
+        }
+    }
+
+    pub fn append(&mut self, append: bool) {
+        // Docs state that `.write(true).append(true)` has the same effect as `.append(true)`
+        if append {
+            self.write(true);
+        }
+        self.append = append;
+    }
+
+    pub fn truncate(&mut self, truncate: bool) {
+        self.truncate = truncate;
+    }
+
+    pub fn create(&mut self, create: bool) {
+        if create {
+            self.mode |= file::MODE_CREATE;
+        } else {
+            self.mode &= !file::MODE_CREATE;
+        }
     }
 
-    pub fn read(&mut self, _read: bool) {}
-    pub fn write(&mut self, _write: bool) {}
-    pub fn append(&mut self, _append: bool) {}
-    pub fn truncate(&mut self, _truncate: bool) {}
-    pub fn create(&mut self, _create: bool) {}
-    pub fn create_new(&mut self, _create_new: bool) {}
+    pub fn create_new(&mut self, create_new: bool) {
+        self.create_new = create_new;
+    }
+
+    #[expect(dead_code)]
+    const fn is_mode_valid(&self) -> bool {
+        // Valid Combinations: Read, Read/Write, Read/Write/Create
+        self.mode == file::MODE_READ
+            || self.mode == (file::MODE_READ | file::MODE_WRITE)
+            || self.mode == (file::MODE_READ | file::MODE_WRITE | file::MODE_CREATE)
+    }
 }
 
 impl File {
@@ -248,11 +298,11 @@ impl File {
 
 impl DirBuilder {
     pub fn new() -> DirBuilder {
-        DirBuilder {}
+        DirBuilder
     }
 
-    pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
-        unsupported()
+    pub fn mkdir(&self, p: &Path) -> io::Result<()> {
+        uefi_fs::mkdir(p)
     }
 }
 
@@ -311,12 +361,12 @@ pub fn stat(_p: &Path) -> io::Result<FileAttr> {
     unsupported()
 }
 
-pub fn lstat(_p: &Path) -> io::Result<FileAttr> {
-    unsupported()
+pub fn lstat(p: &Path) -> io::Result<FileAttr> {
+    stat(p)
 }
 
-pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
-    unsupported()
+pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
+    crate::path::absolute(p)
 }
 
 pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> {
@@ -452,4 +502,30 @@ mod uefi_fs {
             }
         }
     }
+
+    /// An implementation of mkdir to allow creating new directory without having to open the
+    /// volume twice (once for checking and once for creating)
+    pub(crate) fn mkdir(path: &Path) -> io::Result<()> {
+        let absolute = crate::path::absolute(path)?;
+
+        let p = helpers::OwnedDevicePath::from_text(absolute.as_os_str())?;
+        let (vol, mut path_remaining) = File::open_volume_from_device_path(p.borrow())?;
+
+        // Check if file exists
+        match vol.open(&mut path_remaining, file::MODE_READ, 0) {
+            Ok(_) => {
+                return Err(io::Error::new(io::ErrorKind::AlreadyExists, "Path already exists"));
+            }
+            Err(e) if e.kind() == io::ErrorKind::NotFound => {}
+            Err(e) => return Err(e),
+        }
+
+        let _ = vol.open(
+            &mut path_remaining,
+            file::MODE_READ | file::MODE_WRITE | file::MODE_CREATE,
+            file::DIRECTORY,
+        )?;
+
+        Ok(())
+    }
 }
diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs
index 7c3ed8029f7..87865be0387 100644
--- a/library/std/src/sys/fs/unix.rs
+++ b/library/std/src/sys/fs/unix.rs
@@ -155,15 +155,15 @@ cfg_has_statx! {{
         enum STATX_STATE{ Unknown = 0, Present, Unavailable }
         static STATX_SAVED_STATE: AtomicU8 = AtomicU8::new(STATX_STATE::Unknown as u8);
 
-        syscall! {
+        syscall!(
             fn statx(
                 fd: c_int,
                 pathname: *const c_char,
                 flags: c_int,
                 mask: libc::c_uint,
-                statxbuf: *mut libc::statx
-            ) -> c_int
-        }
+                statxbuf: *mut libc::statx,
+            ) -> c_int;
+        );
 
         let statx_availability = STATX_SAVED_STATE.load(Ordering::Relaxed);
         if statx_availability == STATX_STATE::Unavailable as u8 {
@@ -926,7 +926,7 @@ impl DirEntry {
         miri
     ))]
     pub fn metadata(&self) -> io::Result<FileAttr> {
-        lstat(&self.path())
+        run_path_with_cstr(&self.path(), &lstat)
     }
 
     #[cfg(any(
@@ -1540,7 +1540,9 @@ impl File {
                 let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
                 // futimens requires Android API level 19
                 cvt(unsafe {
-                    weak!(fn futimens(c_int, *const libc::timespec) -> c_int);
+                    weak!(
+                        fn futimens(fd: c_int, times: *const libc::timespec) -> c_int;
+                    );
                     match futimens.get() {
                         Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()),
                         None => return Err(io::const_error!(
@@ -1556,7 +1558,9 @@ impl File {
                     use crate::sys::{time::__timespec64, weak::weak};
 
                     // Added in glibc 2.34
-                    weak!(fn __futimens64(libc::c_int, *const __timespec64) -> libc::c_int);
+                    weak!(
+                        fn __futimens64(fd: c_int, times: *const __timespec64) -> c_int;
+                    );
 
                     if let Some(futimens64) = __futimens64.get() {
                         let to_timespec = |time: Option<SystemTime>| time.map(|time| time.t.to_timespec64())
@@ -1653,7 +1657,7 @@ impl fmt::Debug for File {
         fn get_path(fd: c_int) -> Option<PathBuf> {
             let mut p = PathBuf::from("/proc/self/fd");
             p.push(&fd.to_string());
-            readlink(&p).ok()
+            run_path_with_cstr(&p, &readlink).ok()
         }
 
         #[cfg(any(target_vendor = "apple", target_os = "netbsd"))]
@@ -1671,7 +1675,7 @@ impl fmt::Debug for File {
                         // fallback to procfs as last resort
                         let mut p = PathBuf::from("/proc/self/fd");
                         p.push(&fd.to_string());
-                        return readlink(&p).ok();
+                        return run_path_with_cstr(&p, &readlink).ok()
                     } else {
                         return None;
                     }
@@ -1826,127 +1830,106 @@ pub fn readdir(path: &Path) -> io::Result<ReadDir> {
     }
 }
 
-pub fn unlink(p: &Path) -> io::Result<()> {
-    run_path_with_cstr(p, &|p| cvt(unsafe { libc::unlink(p.as_ptr()) }).map(|_| ()))
+pub fn unlink(p: &CStr) -> io::Result<()> {
+    cvt(unsafe { libc::unlink(p.as_ptr()) }).map(|_| ())
 }
 
-pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
-    run_path_with_cstr(old, &|old| {
-        run_path_with_cstr(new, &|new| {
-            cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }).map(|_| ())
-        })
-    })
+pub fn rename(old: &CStr, new: &CStr) -> io::Result<()> {
+    cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }).map(|_| ())
 }
 
-pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
-    run_path_with_cstr(p, &|p| cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }).map(|_| ()))
+pub fn set_perm(p: &CStr, perm: FilePermissions) -> io::Result<()> {
+    cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }).map(|_| ())
 }
 
-pub fn rmdir(p: &Path) -> io::Result<()> {
-    run_path_with_cstr(p, &|p| cvt(unsafe { libc::rmdir(p.as_ptr()) }).map(|_| ()))
+pub fn rmdir(p: &CStr) -> io::Result<()> {
+    cvt(unsafe { libc::rmdir(p.as_ptr()) }).map(|_| ())
 }
 
-pub fn readlink(p: &Path) -> io::Result<PathBuf> {
-    run_path_with_cstr(p, &|c_path| {
-        let p = c_path.as_ptr();
+pub fn readlink(c_path: &CStr) -> io::Result<PathBuf> {
+    let p = c_path.as_ptr();
 
-        let mut buf = Vec::with_capacity(256);
+    let mut buf = Vec::with_capacity(256);
 
-        loop {
-            let buf_read =
-                cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })?
-                    as usize;
-
-            unsafe {
-                buf.set_len(buf_read);
-            }
+    loop {
+        let buf_read =
+            cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })? as usize;
 
-            if buf_read != buf.capacity() {
-                buf.shrink_to_fit();
+        unsafe {
+            buf.set_len(buf_read);
+        }
 
-                return Ok(PathBuf::from(OsString::from_vec(buf)));
-            }
+        if buf_read != buf.capacity() {
+            buf.shrink_to_fit();
 
-            // Trigger the internal buffer resizing logic of `Vec` by requiring
-            // more space than the current capacity. The length is guaranteed to be
-            // the same as the capacity due to the if statement above.
-            buf.reserve(1);
+            return Ok(PathBuf::from(OsString::from_vec(buf)));
         }
-    })
+
+        // Trigger the internal buffer resizing logic of `Vec` by requiring
+        // more space than the current capacity. The length is guaranteed to be
+        // the same as the capacity due to the if statement above.
+        buf.reserve(1);
+    }
 }
 
-pub fn symlink(original: &Path, link: &Path) -> io::Result<()> {
-    run_path_with_cstr(original, &|original| {
-        run_path_with_cstr(link, &|link| {
-            cvt(unsafe { libc::symlink(original.as_ptr(), link.as_ptr()) }).map(|_| ())
-        })
-    })
+pub fn symlink(original: &CStr, link: &CStr) -> io::Result<()> {
+    cvt(unsafe { libc::symlink(original.as_ptr(), link.as_ptr()) }).map(|_| ())
 }
 
-pub fn link(original: &Path, link: &Path) -> io::Result<()> {
-    run_path_with_cstr(original, &|original| {
-        run_path_with_cstr(link, &|link| {
-            cfg_if::cfg_if! {
-                if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_env = "nto70"))] {
-                    // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
-                    // it implementation-defined whether `link` follows symlinks, so rely on the
-                    // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.
-                    // 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 {
-                    // Where we can, use `linkat` instead of `link`; see the comment above
-                    // this one for details on why.
-                    cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
-                }
-            }
-            Ok(())
-        })
-    })
+pub fn link(original: &CStr, link: &CStr) -> io::Result<()> {
+    cfg_if::cfg_if! {
+        if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_env = "nto70"))] {
+            // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
+            // it implementation-defined whether `link` follows symlinks, so rely on the
+            // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.
+            // 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 {
+            // Where we can, use `linkat` instead of `link`; see the comment above
+            // this one for details on why.
+            cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
+        }
+    }
+    Ok(())
 }
 
-pub fn stat(p: &Path) -> io::Result<FileAttr> {
-    run_path_with_cstr(p, &|p| {
-        cfg_has_statx! {
-            if let Some(ret) = unsafe { try_statx(
-                libc::AT_FDCWD,
-                p.as_ptr(),
-                libc::AT_STATX_SYNC_AS_STAT,
-                libc::STATX_BASIC_STATS | libc::STATX_BTIME,
-            ) } {
-                return ret;
-            }
+pub fn stat(p: &CStr) -> io::Result<FileAttr> {
+    cfg_has_statx! {
+        if let Some(ret) = unsafe { try_statx(
+            libc::AT_FDCWD,
+            p.as_ptr(),
+            libc::AT_STATX_SYNC_AS_STAT,
+            libc::STATX_BASIC_STATS | libc::STATX_BTIME,
+        ) } {
+            return ret;
         }
+    }
 
-        let mut stat: stat64 = unsafe { mem::zeroed() };
-        cvt(unsafe { stat64(p.as_ptr(), &mut stat) })?;
-        Ok(FileAttr::from_stat64(stat))
-    })
+    let mut stat: stat64 = unsafe { mem::zeroed() };
+    cvt(unsafe { stat64(p.as_ptr(), &mut stat) })?;
+    Ok(FileAttr::from_stat64(stat))
 }
 
-pub fn lstat(p: &Path) -> io::Result<FileAttr> {
-    run_path_with_cstr(p, &|p| {
-        cfg_has_statx! {
-            if let Some(ret) = unsafe { try_statx(
-                libc::AT_FDCWD,
-                p.as_ptr(),
-                libc::AT_SYMLINK_NOFOLLOW | libc::AT_STATX_SYNC_AS_STAT,
-                libc::STATX_BASIC_STATS | libc::STATX_BTIME,
-            ) } {
-                return ret;
-            }
+pub fn lstat(p: &CStr) -> io::Result<FileAttr> {
+    cfg_has_statx! {
+        if let Some(ret) = unsafe { try_statx(
+            libc::AT_FDCWD,
+            p.as_ptr(),
+            libc::AT_SYMLINK_NOFOLLOW | libc::AT_STATX_SYNC_AS_STAT,
+            libc::STATX_BASIC_STATS | libc::STATX_BTIME,
+        ) } {
+            return ret;
         }
+    }
 
-        let mut stat: stat64 = unsafe { mem::zeroed() };
-        cvt(unsafe { lstat64(p.as_ptr(), &mut stat) })?;
-        Ok(FileAttr::from_stat64(stat))
-    })
+    let mut stat: stat64 = unsafe { mem::zeroed() };
+    cvt(unsafe { lstat64(p.as_ptr(), &mut stat) })?;
+    Ok(FileAttr::from_stat64(stat))
 }
 
-pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
-    let r = run_path_with_cstr(p, &|path| unsafe {
-        Ok(libc::realpath(path.as_ptr(), ptr::null_mut()))
-    })?;
+pub fn canonicalize(path: &CStr) -> io::Result<PathBuf> {
+    let r = unsafe { libc::realpath(path.as_ptr(), ptr::null_mut()) };
     if r.is_null() {
         return Err(io::Error::last_os_error());
     }
@@ -2324,19 +2307,19 @@ mod remove_dir_impl {
         Ok(())
     }
 
-    fn remove_dir_all_modern(p: &Path) -> io::Result<()> {
+    fn remove_dir_all_modern(p: &CStr) -> io::Result<()> {
         // We cannot just call remove_dir_all_recursive() here because that would not delete a passed
         // symlink. No need to worry about races, because remove_dir_all_recursive() does not recurse
         // into symlinks.
         let attr = lstat(p)?;
         if attr.file_type().is_symlink() {
-            crate::fs::remove_file(p)
+            super::unlink(p)
         } else {
-            run_path_with_cstr(p, &|p| remove_dir_all_recursive(None, &p))
+            remove_dir_all_recursive(None, &p)
         }
     }
 
     pub fn remove_dir_all(p: &Path) -> io::Result<()> {
-        remove_dir_all_modern(p)
+        run_path_with_cstr(p, &remove_dir_all_modern)
     }
 }
diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs
index 362e64abf1a..15727c99683 100644
--- a/library/std/src/sys/fs/windows.rs
+++ b/library/std/src/sys/fs/windows.rs
@@ -41,8 +41,8 @@ pub struct FileAttr {
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct FileType {
-    attributes: u32,
-    reparse_tag: u32,
+    is_directory: bool,
+    is_symlink: bool,
 }
 
 pub struct ReadDir {
@@ -547,7 +547,7 @@ impl File {
             ))?;
             attr.file_size = info.AllocationSize as u64;
             attr.number_of_links = Some(info.NumberOfLinks);
-            if attr.file_type().is_reparse_point() {
+            if attr.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
                 let mut attr_tag: c::FILE_ATTRIBUTE_TAG_INFO = mem::zeroed();
                 cvt(c::GetFileInformationByHandleEx(
                     self.handle.as_raw_handle(),
@@ -1111,32 +1111,29 @@ impl FileTimes {
 }
 
 impl FileType {
-    fn new(attrs: u32, reparse_tag: u32) -> FileType {
-        FileType { attributes: attrs, reparse_tag }
+    fn new(attributes: u32, reparse_tag: u32) -> FileType {
+        let is_directory = attributes & c::FILE_ATTRIBUTE_DIRECTORY != 0;
+        let is_symlink = {
+            let is_reparse_point = attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0;
+            let is_reparse_tag_name_surrogate = reparse_tag & 0x20000000 != 0;
+            is_reparse_point && is_reparse_tag_name_surrogate
+        };
+        FileType { is_directory, is_symlink }
     }
     pub fn is_dir(&self) -> bool {
-        !self.is_symlink() && self.is_directory()
+        !self.is_symlink && self.is_directory
     }
     pub fn is_file(&self) -> bool {
-        !self.is_symlink() && !self.is_directory()
+        !self.is_symlink && !self.is_directory
     }
     pub fn is_symlink(&self) -> bool {
-        self.is_reparse_point() && self.is_reparse_tag_name_surrogate()
+        self.is_symlink
     }
     pub fn is_symlink_dir(&self) -> bool {
-        self.is_symlink() && self.is_directory()
+        self.is_symlink && self.is_directory
     }
     pub fn is_symlink_file(&self) -> bool {
-        self.is_symlink() && !self.is_directory()
-    }
-    fn is_directory(&self) -> bool {
-        self.attributes & c::FILE_ATTRIBUTE_DIRECTORY != 0
-    }
-    fn is_reparse_point(&self) -> bool {
-        self.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0
-    }
-    fn is_reparse_tag_name_surrogate(&self) -> bool {
-        self.reparse_tag & 0x20000000 != 0
+        self.is_symlink && !self.is_directory
     }
 }
 
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index 09677b9d642..f0cfb9b2773 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -17,6 +17,7 @@ pub mod io;
 pub mod net;
 pub mod os_str;
 pub mod path;
+pub mod process;
 pub mod random;
 pub mod stdio;
 pub mod sync;
diff --git a/library/std/src/sys/net/connection/xous/tcpstream.rs b/library/std/src/sys/net/connection/xous/tcpstream.rs
index 283b1fe9a33..e8aea8b706a 100644
--- a/library/std/src/sys/net/connection/xous/tcpstream.rs
+++ b/library/std/src/sys/net/connection/xous/tcpstream.rs
@@ -324,7 +324,7 @@ impl TcpStream {
                 }
                 Ok(SocketAddr::V6(SocketAddrV6::new(new_addr.into(), self.local_port, 0, 0)))
             }
-            _ => Err(io::const_error!(io::ErrorKind::InvalidInput, "tnternal error")),
+            _ => Err(io::const_error!(io::ErrorKind::InvalidInput, "internal error")),
         }
     }
 
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index 608245bd430..67eab96fa40 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -25,8 +25,6 @@ pub mod futex;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
 pub mod thread;
 pub mod time;
 
diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs
index bb419c2530e..fe43cfd2caf 100644
--- a/library/std/src/sys/pal/sgx/mod.rs
+++ b/library/std/src/sys/pal/sgx/mod.rs
@@ -16,8 +16,6 @@ mod libunwind_integration;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
 pub mod thread;
 pub mod thread_parking;
 pub mod time;
diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs
index e4a61fdcfe3..22052a168fd 100644
--- a/library/std/src/sys/pal/solid/mod.rs
+++ b/library/std/src/sys/pal/solid/mod.rs
@@ -25,8 +25,6 @@ pub(crate) mod error;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
 pub use self::itron::{thread, thread_parking};
 pub mod time;
 
diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs
index 41b25121592..c1921a2f40d 100644
--- a/library/std/src/sys/pal/teeos/mod.rs
+++ b/library/std/src/sys/pal/teeos/mod.rs
@@ -14,8 +14,6 @@ pub mod env;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
 pub mod thread;
 #[allow(non_upper_case_globals)]
 #[path = "../unix/time.rs"]
diff --git a/library/std/src/sys/pal/trusty/mod.rs b/library/std/src/sys/pal/trusty/mod.rs
index 7034b643d8e..5295d3fdc91 100644
--- a/library/std/src/sys/pal/trusty/mod.rs
+++ b/library/std/src/sys/pal/trusty/mod.rs
@@ -11,8 +11,6 @@ pub mod env;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
 #[path = "../unsupported/thread.rs"]
 pub mod thread;
 #[path = "../unsupported/time.rs"]
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index 2faa733f23f..309022bcccf 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -120,39 +120,6 @@ pub(crate) fn open_protocol<T>(
     }
 }
 
-pub(crate) fn create_event(
-    signal: u32,
-    tpl: efi::Tpl,
-    handler: Option<efi::EventNotify>,
-    context: *mut crate::ffi::c_void,
-) -> io::Result<NonNull<crate::ffi::c_void>> {
-    let boot_services: NonNull<efi::BootServices> =
-        boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
-    let mut event: r_efi::efi::Event = crate::ptr::null_mut();
-    let r = unsafe {
-        let create_event = (*boot_services.as_ptr()).create_event;
-        (create_event)(signal, tpl, handler, context, &mut event)
-    };
-    if r.is_error() {
-        Err(crate::io::Error::from_raw_os_error(r.as_usize()))
-    } else {
-        NonNull::new(event).ok_or(const_error!(io::ErrorKind::Other, "null protocol"))
-    }
-}
-
-/// # SAFETY
-/// - The supplied event must be valid
-pub(crate) unsafe fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result<()> {
-    let boot_services: NonNull<efi::BootServices> =
-        boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
-    let r = unsafe {
-        let close_event = (*boot_services.as_ptr()).close_event;
-        (close_event)(evt.as_ptr())
-    };
-
-    if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
-}
-
 /// Gets the Protocol for current system handle.
 ///
 /// Note: Some protocols need to be manually freed. It is the caller's responsibility to do so.
@@ -735,3 +702,56 @@ impl Drop for ServiceProtocol {
         }
     }
 }
+
+#[repr(transparent)]
+pub(crate) struct OwnedEvent(NonNull<crate::ffi::c_void>);
+
+impl OwnedEvent {
+    pub(crate) fn new(
+        signal: u32,
+        tpl: efi::Tpl,
+        handler: Option<efi::EventNotify>,
+        context: Option<NonNull<crate::ffi::c_void>>,
+    ) -> io::Result<Self> {
+        let boot_services: NonNull<efi::BootServices> =
+            boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
+        let mut event: r_efi::efi::Event = crate::ptr::null_mut();
+        let context = context.map(NonNull::as_ptr).unwrap_or(crate::ptr::null_mut());
+
+        let r = unsafe {
+            let create_event = (*boot_services.as_ptr()).create_event;
+            (create_event)(signal, tpl, handler, context, &mut event)
+        };
+
+        if r.is_error() {
+            Err(crate::io::Error::from_raw_os_error(r.as_usize()))
+        } else {
+            NonNull::new(event)
+                .ok_or(const_error!(io::ErrorKind::Other, "failed to create event"))
+                .map(Self)
+        }
+    }
+
+    pub(crate) fn into_raw(self) -> *mut crate::ffi::c_void {
+        let r = self.0.as_ptr();
+        crate::mem::forget(self);
+        r
+    }
+
+    /// SAFETY: Assumes that ptr is a non-null valid UEFI event
+    pub(crate) unsafe fn from_raw(ptr: *mut crate::ffi::c_void) -> Self {
+        Self(unsafe { NonNull::new_unchecked(ptr) })
+    }
+}
+
+impl Drop for OwnedEvent {
+    fn drop(&mut self) {
+        if let Some(boot_services) = boot_services() {
+            let bt: NonNull<r_efi::efi::BootServices> = boot_services.cast();
+            unsafe {
+                let close_event = (*bt.as_ptr()).close_event;
+                (close_event)(self.0.as_ptr())
+            };
+        }
+    }
+}
diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
index 714dc392688..9760a23084a 100644
--- a/library/std/src/sys/pal/uefi/mod.rs
+++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -19,7 +19,6 @@ pub mod helpers;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-pub mod process;
 pub mod thread;
 pub mod time;
 
@@ -47,17 +46,17 @@ pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
     unsafe { uefi::env::init_globals(image_handle, system_table) };
 
     // Register exit boot services handler
-    match helpers::create_event(
+    match helpers::OwnedEvent::new(
         r_efi::efi::EVT_SIGNAL_EXIT_BOOT_SERVICES,
         r_efi::efi::TPL_NOTIFY,
         Some(exit_boot_service_handler),
-        crate::ptr::null_mut(),
+        None,
     ) {
         Ok(x) => {
             if EXIT_BOOT_SERVICE_EVENT
                 .compare_exchange(
                     crate::ptr::null_mut(),
-                    x.as_ptr(),
+                    x.into_raw(),
                     Ordering::Release,
                     Ordering::Acquire,
                 )
@@ -77,7 +76,7 @@ pub unsafe fn cleanup() {
     if let Some(exit_boot_service_event) =
         NonNull::new(EXIT_BOOT_SERVICE_EVENT.swap(crate::ptr::null_mut(), Ordering::Acquire))
     {
-        let _ = unsafe { helpers::close_event(exit_boot_service_event) };
+        let _ = unsafe { helpers::OwnedEvent::from_raw(exit_boot_service_event.as_ptr()) };
     }
 }
 
@@ -143,7 +142,7 @@ pub fn abort_internal() -> ! {
     if let Some(exit_boot_service_event) =
         NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire))
     {
-        let _ = unsafe { helpers::close_event(exit_boot_service_event) };
+        let _ = unsafe { helpers::OwnedEvent::from_raw(exit_boot_service_event.as_ptr()) };
     }
 
     if let (Some(boot_services), Some(handle)) =
diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs
index f03c440e30e..2ec8d01c13f 100644
--- a/library/std/src/sys/pal/unix/fd.rs
+++ b/library/std/src/sys/pal/unix/fd.rs
@@ -232,14 +232,14 @@ impl FileDesc {
     // implementation if `preadv` is not available.
     #[cfg(all(target_os = "android", target_pointer_width = "64"))]
     pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::syscall! {
+        super::weak::syscall!(
             fn preadv(
                 fd: libc::c_int,
                 iovec: *const libc::iovec,
                 n_iovec: libc::c_int,
-                offset: off64_t
-            ) -> isize
-        }
+                offset: off64_t,
+            ) -> isize;
+        );
 
         let ret = cvt(unsafe {
             preadv(
@@ -257,7 +257,14 @@ impl FileDesc {
     // and its metadata from LLVM IR.
     #[no_sanitize(cfi)]
     pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
+        super::weak::weak!(
+            fn preadv64(
+                fd: libc::c_int,
+                iovec: *const libc::iovec,
+                n_iovec: libc::c_int,
+                offset: off64_t,
+            ) -> isize;
+        );
 
         match preadv64.get() {
             Some(preadv) => {
@@ -286,7 +293,14 @@ impl FileDesc {
     // use "weak" linking.
     #[cfg(target_vendor = "apple")]
     pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::weak!(fn preadv(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
+        super::weak::weak!(
+            fn preadv(
+                fd: libc::c_int,
+                iovec: *const libc::iovec,
+                n_iovec: libc::c_int,
+                offset: off64_t,
+            ) -> isize;
+        );
 
         match preadv.get() {
             Some(preadv) => {
@@ -428,14 +442,14 @@ impl FileDesc {
     // implementation if `pwritev` is not available.
     #[cfg(all(target_os = "android", target_pointer_width = "64"))]
     pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::syscall! {
+        super::weak::syscall!(
             fn pwritev(
                 fd: libc::c_int,
                 iovec: *const libc::iovec,
                 n_iovec: libc::c_int,
-                offset: off64_t
-            ) -> isize
-        }
+                offset: off64_t,
+            ) -> isize;
+        );
 
         let ret = cvt(unsafe {
             pwritev(
@@ -450,7 +464,14 @@ impl FileDesc {
 
     #[cfg(all(target_os = "android", target_pointer_width = "32"))]
     pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::weak!(fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
+        super::weak::weak!(
+            fn pwritev64(
+                fd: libc::c_int,
+                iovec: *const libc::iovec,
+                n_iovec: libc::c_int,
+                offset: off64_t,
+            ) -> isize;
+        );
 
         match pwritev64.get() {
             Some(pwritev) => {
@@ -479,7 +500,14 @@ impl FileDesc {
     // use "weak" linking.
     #[cfg(target_vendor = "apple")]
     pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
-        super::weak::weak!(fn pwritev(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
+        super::weak::weak!(
+            fn pwritev(
+                fd: libc::c_int,
+                iovec: *const libc::iovec,
+                n_iovec: libc::c_int,
+                offset: off64_t,
+            ) -> isize;
+        );
 
         match pwritev.get() {
             Some(pwritev) => {
diff --git a/library/std/src/sys/pal/unix/process/zircon.rs b/library/std/src/sys/pal/unix/fuchsia.rs
index 7932bd26d76..7932bd26d76 100644
--- a/library/std/src/sys/pal/unix/process/zircon.rs
+++ b/library/std/src/sys/pal/unix/fuchsia.rs
diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs
index bbf29f32523..d42a7e2a7fc 100644
--- a/library/std/src/sys/pal/unix/kernel_copy.rs
+++ b/library/std/src/sys/pal/unix/kernel_copy.rs
@@ -604,16 +604,16 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) ->
         _ => true,
     };
 
-    syscall! {
+    syscall!(
         fn copy_file_range(
             fd_in: libc::c_int,
             off_in: *mut libc::loff_t,
             fd_out: libc::c_int,
             off_out: *mut libc::loff_t,
             len: libc::size_t,
-            flags: libc::c_uint
-        ) -> libc::ssize_t
-    }
+            flags: libc::c_uint,
+        ) -> libc::ssize_t;
+    );
 
     fn probe_copy_file_range_support() -> u8 {
         // In some cases, we cannot determine availability from the first
@@ -727,16 +727,16 @@ fn sendfile_splice(mode: SpliceMode, reader: RawFd, writer: RawFd, len: u64) ->
     // Android builds use feature level 14, but the libc wrapper for splice is
     // gated on feature level 21+, so we have to invoke the syscall directly.
     #[cfg(target_os = "android")]
-    syscall! {
+    syscall!(
         fn splice(
             srcfd: libc::c_int,
             src_offset: *const i64,
             dstfd: libc::c_int,
             dst_offset: *const i64,
             len: libc::size_t,
-            flags: libc::c_int
-        ) -> libc::ssize_t
-    }
+            flags: libc::c_int,
+        ) -> libc::ssize_t;
+    );
 
     #[cfg(target_os = "linux")]
     use libc::splice;
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index e2e537b7bd3..413fda1d8d8 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -9,6 +9,8 @@ pub mod weak;
 pub mod args;
 pub mod env;
 pub mod fd;
+#[cfg(target_os = "fuchsia")]
+pub mod fuchsia;
 pub mod futex;
 #[cfg(any(target_os = "linux", target_os = "android"))]
 pub mod kernel_copy;
@@ -16,7 +18,6 @@ pub mod kernel_copy;
 pub mod linux;
 pub mod os;
 pub mod pipe;
-pub mod process;
 pub mod stack_overflow;
 pub mod sync;
 pub mod thread;
@@ -419,7 +420,7 @@ cfg_if::cfg_if! {
 }
 
 #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))]
-mod unsupported {
+pub mod unsupported {
     use crate::io;
 
     pub fn unsupported<T>() -> io::Result<T> {
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index 30282fbf655..f47421c6705 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -59,11 +59,14 @@ unsafe extern "C" {
     #[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")]
     #[cfg_attr(target_os = "haiku", link_name = "_errnop")]
     #[cfg_attr(target_os = "aix", link_name = "_Errno")]
+    // SAFETY: this will always return the same pointer on a given thread.
+    #[unsafe(ffi_const)]
     fn errno_location() -> *mut c_int;
 }
 
 /// Returns the platform-specific value of errno
 #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
+#[inline]
 pub fn errno() -> i32 {
     unsafe { (*errno_location()) as i32 }
 }
@@ -72,16 +75,19 @@ pub fn errno() -> i32 {
 // needed for readdir and syscall!
 #[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))]
 #[allow(dead_code)] // but not all target cfgs actually end up using it
+#[inline]
 pub fn set_errno(e: i32) {
     unsafe { *errno_location() = e as c_int }
 }
 
 #[cfg(target_os = "vxworks")]
+#[inline]
 pub fn errno() -> i32 {
     unsafe { libc::errnoGet() }
 }
 
 #[cfg(target_os = "rtems")]
+#[inline]
 pub fn errno() -> i32 {
     unsafe extern "C" {
         #[thread_local]
@@ -92,6 +98,7 @@ pub fn errno() -> i32 {
 }
 
 #[cfg(target_os = "dragonfly")]
+#[inline]
 pub fn errno() -> i32 {
     unsafe extern "C" {
         #[thread_local]
@@ -103,6 +110,7 @@ pub fn errno() -> i32 {
 
 #[cfg(target_os = "dragonfly")]
 #[allow(dead_code)]
+#[inline]
 pub fn set_errno(e: i32) {
     unsafe extern "C" {
         #[thread_local]
diff --git a/library/std/src/sys/pal/unix/process/mod.rs b/library/std/src/sys/pal/unix/process/mod.rs
deleted file mode 100644
index 2751d51c44d..00000000000
--- a/library/std/src/sys/pal/unix/process/mod.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-pub use self::process_common::{Command, CommandArgs, ExitCode, Stdio, StdioPipes};
-pub use self::process_inner::{ExitStatus, ExitStatusError, Process};
-pub use crate::ffi::OsString as EnvKey;
-
-#[cfg_attr(any(target_os = "espidf", target_os = "horizon", target_os = "nuttx"), allow(unused))]
-mod process_common;
-
-#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))]
-mod process_unsupported;
-
-cfg_if::cfg_if! {
-    if #[cfg(target_os = "fuchsia")] {
-        #[path = "process_fuchsia.rs"]
-        mod process_inner;
-        mod zircon;
-    } else if #[cfg(target_os = "vxworks")] {
-        #[path = "process_vxworks.rs"]
-        mod process_inner;
-    } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] {
-        mod process_inner {
-            pub use super::process_unsupported::*;
-        }
-    } else {
-        #[path = "process_unix.rs"]
-        mod process_inner;
-    }
-}
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs
index 0ecccdc8812..34b3948e3f6 100644
--- a/library/std/src/sys/pal/unix/stack_overflow.rs
+++ b/library/std/src/sys/pal/unix/stack_overflow.rs
@@ -424,18 +424,32 @@ mod imp {
 
         let pages = PAGES.get_or_init(|| {
             use crate::sys::weak::dlsym;
-            dlsym!(fn sysctlbyname(*const libc::c_char, *mut libc::c_void, *mut libc::size_t, *const libc::c_void, libc::size_t) -> libc::c_int);
+            dlsym!(
+                fn sysctlbyname(
+                    name: *const libc::c_char,
+                    oldp: *mut libc::c_void,
+                    oldlenp: *mut libc::size_t,
+                    newp: *const libc::c_void,
+                    newlen: libc::size_t,
+                ) -> libc::c_int;
+            );
             let mut guard: usize = 0;
             let mut size = size_of_val(&guard);
             let oid = c"security.bsd.stack_guard_page";
             match sysctlbyname.get() {
-                Some(fcn) if unsafe {
-                    fcn(oid.as_ptr(),
-                        (&raw mut guard).cast(),
-                        &raw mut size,
-                        ptr::null_mut(),
-                        0) == 0
-                } => guard,
+                Some(fcn)
+                    if unsafe {
+                        fcn(
+                            oid.as_ptr(),
+                            (&raw mut guard).cast(),
+                            &raw mut size,
+                            ptr::null_mut(),
+                            0,
+                        ) == 0
+                    } =>
+                {
+                    guard
+                }
                 _ => 1,
             }
         });
@@ -585,6 +599,7 @@ mod imp {
     target_os = "openbsd",
     target_os = "solaris",
     target_os = "illumos",
+    target_os = "cygwin",
 )))]
 mod imp {
     pub unsafe fn init() {}
@@ -597,3 +612,89 @@ mod imp {
 
     pub unsafe fn drop_handler(_data: *mut libc::c_void) {}
 }
+
+#[cfg(target_os = "cygwin")]
+mod imp {
+    mod c {
+        pub type PVECTORED_EXCEPTION_HANDLER =
+            Option<unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32>;
+        pub type NTSTATUS = i32;
+        pub type BOOL = i32;
+
+        unsafe extern "system" {
+            pub fn AddVectoredExceptionHandler(
+                first: u32,
+                handler: PVECTORED_EXCEPTION_HANDLER,
+            ) -> *mut core::ffi::c_void;
+            pub fn SetThreadStackGuarantee(stacksizeinbytes: *mut u32) -> BOOL;
+        }
+
+        pub const EXCEPTION_STACK_OVERFLOW: NTSTATUS = 0xC00000FD_u32 as _;
+        pub const EXCEPTION_CONTINUE_SEARCH: i32 = 1i32;
+
+        #[repr(C)]
+        #[derive(Clone, Copy)]
+        pub struct EXCEPTION_POINTERS {
+            pub ExceptionRecord: *mut EXCEPTION_RECORD,
+            // We don't need this field here
+            // pub Context: *mut CONTEXT,
+        }
+        #[repr(C)]
+        #[derive(Clone, Copy)]
+        pub struct EXCEPTION_RECORD {
+            pub ExceptionCode: NTSTATUS,
+            pub ExceptionFlags: u32,
+            pub ExceptionRecord: *mut EXCEPTION_RECORD,
+            pub ExceptionAddress: *mut core::ffi::c_void,
+            pub NumberParameters: u32,
+            pub ExceptionInformation: [usize; 15],
+        }
+    }
+
+    /// Reserve stack space for use in stack overflow exceptions.
+    fn reserve_stack() {
+        let result = unsafe { c::SetThreadStackGuarantee(&mut 0x5000) };
+        // Reserving stack space is not critical so we allow it to fail in the released build of libstd.
+        // We still use debug assert here so that CI will test that we haven't made a mistake calling the function.
+        debug_assert_ne!(result, 0, "failed to reserve stack space for exception handling");
+    }
+
+    unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> i32 {
+        // SAFETY: It's up to the caller (which in this case is the OS) to ensure that `ExceptionInfo` is valid.
+        unsafe {
+            let rec = &(*(*ExceptionInfo).ExceptionRecord);
+            let code = rec.ExceptionCode;
+
+            if code == c::EXCEPTION_STACK_OVERFLOW {
+                crate::thread::with_current_name(|name| {
+                    let name = name.unwrap_or("<unknown>");
+                    rtprintpanic!("\nthread '{name}' has overflowed its stack\n");
+                });
+            }
+            c::EXCEPTION_CONTINUE_SEARCH
+        }
+    }
+
+    pub unsafe fn init() {
+        // SAFETY: `vectored_handler` has the correct ABI and is safe to call during exception handling.
+        unsafe {
+            let result = c::AddVectoredExceptionHandler(0, Some(vectored_handler));
+            // Similar to the above, adding the stack overflow handler is allowed to fail
+            // but a debug assert is used so CI will still test that it normally works.
+            debug_assert!(!result.is_null(), "failed to install exception handler");
+        }
+        // Set the thread stack guarantee for the main thread.
+        reserve_stack();
+    }
+
+    pub unsafe fn cleanup() {}
+
+    pub unsafe fn make_handler(main_thread: bool) -> super::Handler {
+        if !main_thread {
+            reserve_stack();
+        }
+        super::Handler::null()
+    }
+
+    pub unsafe fn drop_handler(_data: *mut libc::c_void) {}
+}
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index bffe2536299..9078dd1c231 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -143,8 +143,8 @@ impl Thread {
     pub fn set_name(name: &CStr) {
         unsafe {
             cfg_if::cfg_if! {
-                if #[cfg(target_os = "linux")] {
-                    // Linux limits the allowed length of the name.
+                if #[cfg(any(target_os = "linux", target_os = "cygwin"))] {
+                    // Linux and Cygwin limits the allowed length of the name.
                     const TASK_COMM_LEN: usize = 16;
                     let name = truncate_cstr::<{ TASK_COMM_LEN }>(name);
                 } else {
@@ -193,11 +193,12 @@ impl Thread {
     // and its metadata from LLVM IR.
     #[no_sanitize(cfi)]
     pub fn set_name(name: &CStr) {
-        weak! {
+        weak!(
             fn pthread_setname_np(
-                libc::pthread_t, *const libc::c_char
-            ) -> libc::c_int
-        }
+                thread: libc::pthread_t,
+                name: *const libc::c_char,
+            ) -> libc::c_int;
+        );
 
         if let Some(f) = pthread_setname_np.get() {
             #[cfg(target_os = "nto")]
@@ -346,6 +347,7 @@ impl Drop for Thread {
     target_os = "solaris",
     target_os = "illumos",
     target_os = "vxworks",
+    target_os = "cygwin",
     target_vendor = "apple",
 ))]
 fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_WITH_NUL] {
@@ -761,7 +763,9 @@ unsafe fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
     // We use dlsym to avoid an ELF version dependency on GLIBC_PRIVATE. (#23628)
     // We shouldn't really be using such an internal symbol, but there's currently
     // no other way to account for the TLS size.
-    dlsym!(fn __pthread_get_minstack(*const libc::pthread_attr_t) -> libc::size_t);
+    dlsym!(
+        fn __pthread_get_minstack(attr: *const libc::pthread_attr_t) -> libc::size_t;
+    );
 
     match __pthread_get_minstack.get() {
         None => libc::PTHREAD_STACK_MIN,
diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs
index c0a3044660b..b8469b1681f 100644
--- a/library/std/src/sys/pal/unix/time.rs
+++ b/library/std/src/sys/pal/unix/time.rs
@@ -123,7 +123,12 @@ impl Timespec {
 
             // __clock_gettime64 was added to 32-bit arches in glibc 2.34,
             // and it handles both vDSO calls and ENOSYS fallbacks itself.
-            weak!(fn __clock_gettime64(libc::clockid_t, *mut __timespec64) -> libc::c_int);
+            weak!(
+                fn __clock_gettime64(
+                    clockid: libc::clockid_t,
+                    tp: *mut __timespec64,
+                ) -> libc::c_int;
+            );
 
             if let Some(clock_gettime64) = __clock_gettime64.get() {
                 let mut t = MaybeUninit::uninit();
diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs
index ce3f66a8374..e7f4e005cc4 100644
--- a/library/std/src/sys/pal/unix/weak.rs
+++ b/library/std/src/sys/pal/unix/weak.rs
@@ -29,7 +29,7 @@ use crate::{mem, ptr};
 // We can use true weak linkage on ELF targets.
 #[cfg(all(unix, not(target_vendor = "apple")))]
 pub(crate) macro weak {
-    (fn $name:ident($($t:ty),*) -> $ret:ty) => (
+    (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
         let ref $name: ExternWeak<unsafe extern "C" fn($($t),*) -> $ret> = {
             unsafe extern "C" {
                 #[linkage = "extern_weak"]
@@ -62,10 +62,16 @@ impl<F: Copy> ExternWeak<F> {
 }
 
 pub(crate) macro dlsym {
-    (fn $name:ident($($t:ty),*) -> $ret:ty) => (
-         dlsym!(fn $name($($t),*) -> $ret, stringify!($name));
+    (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
+         dlsym!(
+            #[link_name = stringify!($name)]
+            fn $name($($param : $t),*) -> $ret;
+        );
     ),
-    (fn $name:ident($($t:ty),*) -> $ret:ty, $sym:expr) => (
+    (
+        #[link_name = $sym:expr]
+        fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;
+    ) => (
         static DLSYM: DlsymWeak<unsafe extern "C" fn($($t),*) -> $ret> =
             DlsymWeak::new(concat!($sym, '\0'));
         let $name = &DLSYM;
@@ -143,15 +149,15 @@ unsafe fn fetch(name: &str) -> *mut libc::c_void {
 
 #[cfg(not(any(target_os = "linux", target_os = "android")))]
 pub(crate) macro syscall {
-    (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => (
+    (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
         // FIXME(#115199): Rust currently omits weak function definitions
         // and its metadata from LLVM IR.
         #[no_sanitize(cfi)]
-        unsafe fn $name($($arg_name: $t),*) -> $ret {
-            weak! { fn $name($($t),*) -> $ret }
+        unsafe fn $name($($param: $t),*) -> $ret {
+            weak!(fn $name($($param: $t),*) -> $ret;);
 
             if let Some(fun) = $name.get() {
-                fun($($arg_name),*)
+                fun($($param),*)
             } else {
                 super::os::set_errno(libc::ENOSYS);
                 -1
@@ -162,16 +168,18 @@ pub(crate) macro syscall {
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
 pub(crate) macro syscall {
-    (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => (
-        unsafe fn $name($($arg_name:$t),*) -> $ret {
-            weak! { fn $name($($t),*) -> $ret }
+    (
+        fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;
+    ) => (
+        unsafe fn $name($($param: $t),*) -> $ret {
+            weak!(fn $name($($param: $t),*) -> $ret;);
 
             // Use a weak symbol from libc when possible, allowing `LD_PRELOAD`
             // interposition, but if it's not found just use a raw syscall.
             if let Some(fun) = $name.get() {
-                fun($($arg_name),*)
+                fun($($param),*)
             } else {
-                libc::syscall(libc::${concat(SYS_, $name)}, $($arg_name),*) as $ret
+                libc::syscall(libc::${concat(SYS_, $name)}, $($param),*) as $ret
             }
         }
     )
@@ -179,9 +187,9 @@ pub(crate) macro syscall {
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
 pub(crate) macro raw_syscall {
-    (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => (
-        unsafe fn $name($($arg_name:$t),*) -> $ret {
-            libc::syscall(libc::${concat(SYS_, $name)}, $($arg_name),*) as $ret
+    (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
+        unsafe fn $name($($param: $t),*) -> $ret {
+            libc::syscall(libc::${concat(SYS_, $name)}, $($param),*) as $ret
         }
     )
 }
diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs
index bcea699f3b2..38838b915b5 100644
--- a/library/std/src/sys/pal/unsupported/mod.rs
+++ b/library/std/src/sys/pal/unsupported/mod.rs
@@ -4,7 +4,6 @@ pub mod args;
 pub mod env;
 pub mod os;
 pub mod pipe;
-pub mod process;
 pub mod thread;
 pub mod time;
 
diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs
index c89832857dd..cdd613f76b6 100644
--- a/library/std/src/sys/pal/wasi/mod.rs
+++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -23,8 +23,6 @@ pub mod futex;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
 pub mod thread;
 pub mod time;
 
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index c85b03d4a89..cc569bb3daf 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -67,7 +67,7 @@ cfg_if::cfg_if! {
     }
 }
 
-pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024;
+pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs
index 3008ba88753..6ac28f1bf4f 100644
--- a/library/std/src/sys/pal/wasip2/mod.rs
+++ b/library/std/src/sys/pal/wasip2/mod.rs
@@ -20,8 +20,6 @@ pub mod futex;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
 #[path = "../wasi/thread.rs"]
 pub mod thread;
 #[path = "../wasi/time.rs"]
diff --git a/library/std/src/sys/pal/wasm/atomics/thread.rs b/library/std/src/sys/pal/wasm/atomics/thread.rs
index afdb159fe6f..dd5aff391fd 100644
--- a/library/std/src/sys/pal/wasm/atomics/thread.rs
+++ b/library/std/src/sys/pal/wasm/atomics/thread.rs
@@ -6,7 +6,7 @@ use crate::time::Duration;
 
 pub struct Thread(!);
 
-pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024;
+pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs
index 175fe75357f..8d39b70d039 100644
--- a/library/std/src/sys/pal/wasm/mod.rs
+++ b/library/std/src/sys/pal/wasm/mod.rs
@@ -23,8 +23,6 @@ pub mod env;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
 #[path = "../unsupported/time.rs"]
 pub mod time;
 
diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs
index 3447a0157e4..d973743639a 100644
--- a/library/std/src/sys/pal/windows/args.rs
+++ b/library/std/src/sys/pal/windows/args.rs
@@ -6,13 +6,13 @@
 #[cfg(test)]
 mod tests;
 
+use super::ensure_no_nuls;
 use super::os::current_exe;
 use crate::ffi::{OsStr, OsString};
 use crate::num::NonZero;
 use crate::os::windows::prelude::*;
 use crate::path::{Path, PathBuf};
 use crate::sys::path::get_long_path;
-use crate::sys::process::ensure_no_nuls;
 use crate::sys::{c, to_u16s};
 use crate::sys_common::AsInner;
 use crate::sys_common::wstr::WStrUnits;
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 6eb68f3a3bc..bdf0cc2c59c 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -22,7 +22,6 @@ pub mod futex;
 pub mod handle;
 pub mod os;
 pub mod pipe;
-pub mod process;
 pub mod thread;
 pub mod time;
 cfg_if::cfg_if! {
@@ -287,6 +286,14 @@ pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] {
     }
 }
 
+pub fn ensure_no_nuls<T: AsRef<OsStr>>(s: T) -> crate::io::Result<T> {
+    if s.as_ref().encode_wide().any(|b| b == 0) {
+        Err(crate::io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data"))
+    } else {
+        Ok(s)
+    }
+}
+
 pub trait IsZero {
     fn is_zero(&self) -> bool;
 }
diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs
index 8521cf4162f..c7852464922 100644
--- a/library/std/src/sys/pal/windows/pipe.rs
+++ b/library/std/src/sys/pal/windows/pipe.rs
@@ -74,7 +74,6 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
         let ours;
         let mut name;
         let mut tries = 0;
-        let mut reject_remote_clients_flag = c::PIPE_REJECT_REMOTE_CLIENTS;
         loop {
             tries += 1;
             name = format!(
@@ -96,7 +95,7 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
                 c::PIPE_TYPE_BYTE
                     | c::PIPE_READMODE_BYTE
                     | c::PIPE_WAIT
-                    | reject_remote_clients_flag,
+                    | c::PIPE_REJECT_REMOTE_CLIENTS,
                 1,
                 PIPE_BUFFER_CAPACITY,
                 PIPE_BUFFER_CAPACITY,
@@ -112,30 +111,15 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
             //
             // Don't try again too much though as this could also perhaps be a
             // legit error.
-            // If `ERROR_INVALID_PARAMETER` is returned, this probably means we're
-            // running on pre-Vista version where `PIPE_REJECT_REMOTE_CLIENTS` is
-            // not supported, so we continue retrying without it. This implies
-            // reduced security on Windows versions older than Vista by allowing
-            // connections to this pipe from remote machines.
-            // Proper fix would increase the number of FFI imports and introduce
-            // significant amount of Windows XP specific code with no clean
-            // testing strategy
-            // For more info, see https://github.com/rust-lang/rust/pull/37677.
             if handle == c::INVALID_HANDLE_VALUE {
                 let error = api::get_last_error();
-                if tries < 10 {
-                    if error == WinError::ACCESS_DENIED {
-                        continue;
-                    } else if reject_remote_clients_flag != 0
-                        && error == WinError::INVALID_PARAMETER
-                    {
-                        reject_remote_clients_flag = 0;
-                        tries -= 1;
-                        continue;
-                    }
+                if tries < 10 && error == WinError::ACCESS_DENIED {
+                    continue;
+                } else {
+                    return Err(io::Error::from_raw_os_error(error.code as i32));
                 }
-                return Err(io::Error::from_raw_os_error(error.code as i32));
             }
+
             ours = Handle::from_raw_handle(handle);
             break;
         }
diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs
index 7d823012ad1..58926e2beb1 100644
--- a/library/std/src/sys/pal/xous/mod.rs
+++ b/library/std/src/sys/pal/xous/mod.rs
@@ -6,8 +6,6 @@ pub mod env;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
 pub mod thread;
 pub mod time;
 
diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs
index 499e2787201..4659dad16e8 100644
--- a/library/std/src/sys/pal/zkvm/mod.rs
+++ b/library/std/src/sys/pal/zkvm/mod.rs
@@ -17,8 +17,6 @@ pub mod env;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
 #[path = "../unsupported/thread.rs"]
 pub mod thread;
 #[path = "../unsupported/time.rs"]
diff --git a/library/std/src/sys/process/mod.rs b/library/std/src/sys/process/mod.rs
new file mode 100644
index 00000000000..92cfac7f47c
--- /dev/null
+++ b/library/std/src/sys/process/mod.rs
@@ -0,0 +1,19 @@
+cfg_if::cfg_if! {
+    if #[cfg(target_family = "unix")] {
+        mod unix;
+        use unix as imp;
+    } else if #[cfg(target_os = "windows")] {
+        mod windows;
+        use windows as imp;
+    } else if #[cfg(target_os = "uefi")] {
+        mod uefi;
+        use uefi as imp;
+    } else {
+        mod unsupported;
+        use unsupported as imp;
+    }
+}
+
+pub use imp::{
+    Command, CommandArgs, EnvKey, ExitCode, ExitStatus, ExitStatusError, Process, Stdio, StdioPipes,
+};
diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/process/uefi.rs
index 1203d51e531..b46418ae9bb 100644
--- a/library/std/src/sys/pal/uefi/process.rs
+++ b/library/std/src/sys/process/uefi.rs
@@ -1,12 +1,13 @@
 use r_efi::protocols::simple_text_output;
 
-use super::helpers;
 use crate::collections::BTreeMap;
 pub use crate::ffi::OsString as EnvKey;
 use crate::ffi::{OsStr, OsString};
 use crate::num::{NonZero, NonZeroI32};
 use crate::path::Path;
 use crate::sys::fs::File;
+use crate::sys::pal::helpers;
+use crate::sys::pal::os::error_string;
 use crate::sys::pipe::AnonPipe;
 use crate::sys::unsupported;
 use crate::sys_common::process::{CommandEnv, CommandEnvs};
@@ -225,7 +226,7 @@ impl ExitStatus {
 
 impl fmt::Display for ExitStatus {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let err_str = super::os::error_string(self.0.as_usize());
+        let err_str = error_string(self.0.as_usize());
         write!(f, "{}", err_str)
     }
 }
@@ -241,7 +242,7 @@ pub struct ExitStatusError(r_efi::efi::Status);
 
 impl fmt::Debug for ExitStatusError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let err_str = super::os::error_string(self.0.as_usize());
+        let err_str = error_string(self.0.as_usize());
         write!(f, "{}", err_str)
     }
 }
@@ -335,7 +336,6 @@ impl<'a> fmt::Debug for CommandArgs<'a> {
 mod uefi_command_internal {
     use r_efi::protocols::{loaded_image, simple_text_output};
 
-    use super::super::helpers;
     use crate::ffi::{OsStr, OsString};
     use crate::io::{self, const_error};
     use crate::mem::MaybeUninit;
@@ -343,7 +343,7 @@ mod uefi_command_internal {
     use crate::os::uefi::ffi::{OsStrExt, OsStringExt};
     use crate::ptr::NonNull;
     use crate::slice;
-    use crate::sys::pal::uefi::helpers::OwnedTable;
+    use crate::sys::pal::helpers::{self, OwnedTable};
     use crate::sys_common::wstr::WStrUnits;
 
     pub struct Image {
diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/process/unix/common.rs
index a1c747c8df4..8bc17f31491 100644
--- a/library/std/src/sys/pal/unix/process/process_common.rs
+++ b/library/std/src/sys/process/unix/common.rs
@@ -54,7 +54,7 @@ cfg_if::cfg_if! {
 
             let bit = (signum - 1) as usize;
             if set.is_null() || bit >= (8 * size_of::<sigset_t>()) {
-                crate::sys::pal::unix::os::set_errno(libc::EINVAL);
+                crate::sys::pal::os::set_errno(libc::EINVAL);
                 return -1;
             }
             let raw = slice::from_raw_parts_mut(
diff --git a/library/std/src/sys/pal/unix/process/process_common/tests.rs b/library/std/src/sys/process/unix/common/tests.rs
index e5c8dd6e341..e5c8dd6e341 100644
--- a/library/std/src/sys/pal/unix/process/process_common/tests.rs
+++ b/library/std/src/sys/process/unix/common/tests.rs
diff --git a/library/std/src/sys/pal/unix/process/process_fuchsia.rs b/library/std/src/sys/process/unix/fuchsia.rs
index 05c9ace470e..0de32ecffd4 100644
--- a/library/std/src/sys/pal/unix/process/process_fuchsia.rs
+++ b/library/std/src/sys/process/unix/fuchsia.rs
@@ -1,8 +1,8 @@
 use libc::{c_int, size_t};
 
+use super::common::*;
 use crate::num::NonZero;
-use crate::sys::process::process_common::*;
-use crate::sys::process::zircon::{Handle, zx_handle_t};
+use crate::sys::pal::fuchsia::*;
 use crate::{fmt, io, mem, ptr};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -58,8 +58,6 @@ impl Command {
         stdio: ChildPipes,
         maybe_envp: Option<&CStringArray>,
     ) -> io::Result<zx_handle_t> {
-        use crate::sys::process::zircon::*;
-
         let envp = match maybe_envp {
             // None means to clone the current environment, which is done in the
             // flags below.
@@ -152,8 +150,6 @@ impl Process {
     }
 
     pub fn kill(&mut self) -> io::Result<()> {
-        use crate::sys::process::zircon::*;
-
         unsafe {
             zx_cvt(zx_task_kill(self.handle.raw()))?;
         }
@@ -162,8 +158,6 @@ impl Process {
     }
 
     pub fn wait(&mut self) -> io::Result<ExitStatus> {
-        use crate::sys::process::zircon::*;
-
         let mut proc_info: zx_info_process_t = Default::default();
         let mut actual: size_t = 0;
         let mut avail: size_t = 0;
@@ -194,8 +188,6 @@ impl Process {
     }
 
     pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
-        use crate::sys::process::zircon::*;
-
         let mut proc_info: zx_info_process_t = Default::default();
         let mut actual: size_t = 0;
         let mut avail: size_t = 0;
@@ -251,7 +243,7 @@ impl ExitStatus {
         None
     }
 
-    // FIXME: The actually-Unix implementation in process_unix.rs uses WSTOPSIG, WCOREDUMP et al.
+    // FIXME: The actually-Unix implementation in unix.rs uses WSTOPSIG, WCOREDUMP et al.
     // I infer from the implementation of `success`, `code` and `signal` above that these are not
     // available on Fuchsia.
     //
diff --git a/library/std/src/sys/process/unix/mod.rs b/library/std/src/sys/process/unix/mod.rs
new file mode 100644
index 00000000000..2e8b38f7de1
--- /dev/null
+++ b/library/std/src/sys/process/unix/mod.rs
@@ -0,0 +1,23 @@
+#[cfg_attr(any(target_os = "espidf", target_os = "horizon", target_os = "nuttx"), allow(unused))]
+mod common;
+
+cfg_if::cfg_if! {
+    if #[cfg(target_os = "fuchsia")] {
+        mod fuchsia;
+        use fuchsia as imp;
+    } else if #[cfg(target_os = "vxworks")] {
+        mod vxworks;
+        use vxworks as imp;
+    } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] {
+        mod unsupported;
+        use unsupported as imp;
+    } else {
+        mod unix;
+        use unix as imp;
+    }
+}
+
+pub use imp::{ExitStatus, ExitStatusError, Process};
+
+pub use self::common::{Command, CommandArgs, ExitCode, Stdio, StdioPipes};
+pub use crate::ffi::OsString as EnvKey;
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/process/unix/unix.rs
index f19512233d8..191a09c8da9 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/process/unix/unix.rs
@@ -10,12 +10,12 @@ use libc::{c_int, pid_t};
 )))]
 use libc::{gid_t, uid_t};
 
+use super::common::*;
 use crate::io::{self, Error, ErrorKind};
 use crate::num::NonZero;
 use crate::sys::cvt;
 #[cfg(target_os = "linux")]
-use crate::sys::pal::unix::linux::pidfd::PidFd;
-use crate::sys::process::process_common::*;
+use crate::sys::pal::linux::pidfd::PidFd;
 use crate::{fmt, mem, sys};
 
 cfg_if::cfg_if! {
@@ -461,18 +461,20 @@ impl Command {
             if #[cfg(target_os = "linux")] {
                 use crate::sys::weak::weak;
 
-                weak! {
+                weak!(
                     fn pidfd_spawnp(
-                        *mut libc::c_int,
-                        *const libc::c_char,
-                        *const libc::posix_spawn_file_actions_t,
-                        *const libc::posix_spawnattr_t,
-                        *const *mut libc::c_char,
-                        *const *mut libc::c_char
-                    ) -> libc::c_int
-                }
+                        pidfd: *mut libc::c_int,
+                        path: *const libc::c_char,
+                        file_actions: *const libc::posix_spawn_file_actions_t,
+                        attrp: *const libc::posix_spawnattr_t,
+                        argv: *const *mut libc::c_char,
+                        envp: *const *mut libc::c_char,
+                    ) -> libc::c_int;
+                );
 
-                weak! { fn pidfd_getpid(libc::c_int) -> libc::c_int }
+                weak!(
+                    fn pidfd_getpid(pidfd: libc::c_int) -> libc::c_int;
+                );
 
                 static PIDFD_SUPPORTED: AtomicU8 = AtomicU8::new(0);
                 const UNKNOWN: u8 = 0;
@@ -593,19 +595,19 @@ impl Command {
             // https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addchdir.html.
             // The _np version is more widely available, though, so try that first.
 
-            weak! {
+            weak!(
                 fn posix_spawn_file_actions_addchdir_np(
-                    *mut libc::posix_spawn_file_actions_t,
-                    *const libc::c_char
-                ) -> libc::c_int
-            }
+                    file_actions: *mut libc::posix_spawn_file_actions_t,
+                    path: *const libc::c_char,
+                ) -> libc::c_int;
+            );
 
-            weak! {
+            weak!(
                 fn posix_spawn_file_actions_addchdir(
-                    *mut libc::posix_spawn_file_actions_t,
-                    *const libc::c_char
-                ) -> libc::c_int
-            }
+                    file_actions: *mut libc::posix_spawn_file_actions_t,
+                    path: *const libc::c_char,
+                ) -> libc::c_int;
+            );
 
             posix_spawn_file_actions_addchdir_np
                 .get()
@@ -1051,7 +1053,7 @@ impl ExitStatus {
         // true on all actual versions of Unix, is widely assumed, and is specified in SuS
         // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
         // true for a platform pretending to be Unix, the tests (our doctests, and also
-        // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
+        // unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
         match NonZero::try_from(self.0) {
             /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)),
             /* was zero, couldn't convert */ Err(_) => Ok(()),
@@ -1232,10 +1234,9 @@ impl ExitStatusError {
 
 #[cfg(target_os = "linux")]
 mod linux_child_ext {
-
+    use crate::io::ErrorKind;
     use crate::os::linux::process as os;
-    use crate::sys::pal::unix::ErrorKind;
-    use crate::sys::pal::unix::linux::pidfd as imp;
+    use crate::sys::pal::linux::pidfd as imp;
     use crate::sys_common::FromInner;
     use crate::{io, mem};
 
@@ -1261,10 +1262,9 @@ mod linux_child_ext {
 }
 
 #[cfg(test)]
-#[path = "process_unix/tests.rs"]
 mod tests;
 
-// See [`process_unsupported_wait_status::compare_with_linux`];
+// See [`unsupported_wait_status::compare_with_linux`];
 #[cfg(all(test, target_os = "linux"))]
-#[path = "process_unsupported/wait_status.rs"]
-mod process_unsupported_wait_status;
+#[path = "unsupported/wait_status.rs"]
+mod unsupported_wait_status;
diff --git a/library/std/src/sys/pal/unix/process/process_unix/tests.rs b/library/std/src/sys/process/unix/unix/tests.rs
index f4d6ac6b4e3..f4d6ac6b4e3 100644
--- a/library/std/src/sys/pal/unix/process/process_unix/tests.rs
+++ b/library/std/src/sys/process/unix/unix/tests.rs
diff --git a/library/std/src/sys/pal/unix/process/process_unsupported.rs b/library/std/src/sys/process/unix/unsupported.rs
index c58548835ff..78d270923cf 100644
--- a/library/std/src/sys/pal/unix/process/process_unsupported.rs
+++ b/library/std/src/sys/process/unix/unsupported.rs
@@ -1,9 +1,9 @@
 use libc::{c_int, pid_t};
 
+use super::common::*;
 use crate::io;
 use crate::num::NonZero;
-use crate::sys::pal::unix::unsupported::*;
-use crate::sys::process::process_common::*;
+use crate::sys::pal::unsupported::*;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Command
diff --git a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs b/library/std/src/sys/process/unix/unsupported/wait_status.rs
index f04036bde49..f348d557e4b 100644
--- a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs
+++ b/library/std/src/sys/process/unix/unsupported/wait_status.rs
@@ -7,7 +7,7 @@ use crate::ffi::c_int;
 use crate::fmt;
 use crate::num::NonZero;
 
-/// Emulated wait status for use by `process_unsupported.rs`
+/// Emulated wait status for use by `unsupported.rs`
 ///
 /// Uses the "traditional unix" encoding.  For use on platfors which are `#[cfg(unix)]`
 /// but do not actually support subprocesses at all.
@@ -48,7 +48,7 @@ impl ExitStatus {
         // true on all actual versions of Unix, is widely assumed, and is specified in SuS
         // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
         // true for a platform pretending to be Unix, the tests (our doctests, and also
-        // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
+        // unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
         match NonZero::try_from(self.wait_status) {
             /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)),
             /* was zero, couldn't convert */ Err(_) => Ok(()),
@@ -79,5 +79,6 @@ impl ExitStatus {
 }
 
 #[cfg(test)]
-#[path = "wait_status/tests.rs"] // needed because of strange layout of process_unsupported
+#[path = "wait_status/tests.rs"]
+// needed because this module is also imported through #[path] for testing purposes
 mod tests;
diff --git a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status/tests.rs b/library/std/src/sys/process/unix/unsupported/wait_status/tests.rs
index 5132eab10a1..0d9232fac5e 100644
--- a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status/tests.rs
+++ b/library/std/src/sys/process/unix/unsupported/wait_status/tests.rs
@@ -1,4 +1,4 @@
-// Note that tests in this file are run on Linux as well as on platforms using process_unsupported
+// Note that tests in this file are run on Linux as well as on platforms using unsupported
 
 // Test that our emulation exactly matches Linux
 //
diff --git a/library/std/src/sys/pal/unix/process/process_vxworks.rs b/library/std/src/sys/process/unix/vxworks.rs
index e2c1b6a0326..5f1727789a1 100644
--- a/library/std/src/sys/pal/unix/process/process_vxworks.rs
+++ b/library/std/src/sys/process/unix/vxworks.rs
@@ -1,11 +1,11 @@
 #![forbid(unsafe_op_in_unsafe_fn)]
 use libc::{self, RTP_ID, c_char, c_int};
 
+use super::common::*;
 use crate::io::{self, ErrorKind};
 use crate::num::NonZero;
 use crate::sys::cvt;
-use crate::sys::pal::unix::thread;
-use crate::sys::process::process_common::*;
+use crate::sys::pal::thread;
 use crate::{fmt, sys};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -200,7 +200,7 @@ impl ExitStatus {
         // true on all actual versions of Unix, is widely assumed, and is specified in SuS
         // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
         // true for a platform pretending to be Unix, the tests (our doctests, and also
-        // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
+        // unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
         match NonZero::try_from(self.0) {
             Ok(failure) => Err(ExitStatusError(failure)),
             Err(_) => Ok(()),
diff --git a/library/std/src/sys/pal/unsupported/process.rs b/library/std/src/sys/process/unsupported.rs
index fee81744f09..fee81744f09 100644
--- a/library/std/src/sys/pal/unsupported/process.rs
+++ b/library/std/src/sys/process/unsupported.rs
diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/process/windows.rs
index 50e4baba607..06c15e08f3f 100644
--- a/library/std/src/sys/pal/windows/process.rs
+++ b/library/std/src/sys/process/windows.rs
@@ -5,11 +5,10 @@ mod tests;
 
 use core::ffi::c_void;
 
-use super::api::{self, WinError};
 use crate::collections::BTreeMap;
 use crate::env::consts::{EXE_EXTENSION, EXE_SUFFIX};
 use crate::ffi::{OsStr, OsString};
-use crate::io::{self, Error, ErrorKind};
+use crate::io::{self, Error};
 use crate::num::NonZero;
 use crate::os::windows::ffi::{OsStrExt, OsStringExt};
 use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle};
@@ -20,6 +19,8 @@ use crate::sys::args::{self, Arg};
 use crate::sys::c::{self, EXIT_FAILURE, EXIT_SUCCESS};
 use crate::sys::fs::{File, OpenOptions};
 use crate::sys::handle::Handle;
+use crate::sys::pal::api::{self, WinError};
+use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf};
 use crate::sys::pipe::{self, AnonPipe};
 use crate::sys::{cvt, path, stdio};
 use crate::sys_common::IntoInner;
@@ -142,14 +143,6 @@ impl AsRef<OsStr> for EnvKey {
     }
 }
 
-pub(crate) fn ensure_no_nuls<T: AsRef<OsStr>>(s: T) -> io::Result<T> {
-    if s.as_ref().encode_wide().any(|b| b == 0) {
-        Err(io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data"))
-    } else {
-        Ok(s)
-    }
-}
-
 pub struct Command {
     program: OsString,
     args: Vec<Arg>,
@@ -279,7 +272,7 @@ impl Command {
         let is_batch_file = if path::is_verbatim(&program) {
             has_bat_extension(&program[..program.len() - 1])
         } else {
-            super::fill_utf16_buf(
+            fill_utf16_buf(
                 |buffer, size| unsafe {
                     // resolve the path so we can test the final file name.
                     c::GetFullPathNameW(program.as_ptr(), size, buffer, ptr::null_mut())
@@ -521,7 +514,7 @@ where
     // 3 & 4. System paths
     // SAFETY: This uses `fill_utf16_buf` to safely call the OS functions.
     unsafe {
-        if let Ok(Some(path)) = super::fill_utf16_buf(
+        if let Ok(Some(path)) = fill_utf16_buf(
             |buf, size| c::GetSystemDirectoryW(buf, size),
             |buf| exists(PathBuf::from(OsString::from_wide(buf))),
         ) {
@@ -529,7 +522,7 @@ where
         }
         #[cfg(not(target_vendor = "uwp"))]
         {
-            if let Ok(Some(path)) = super::fill_utf16_buf(
+            if let Ok(Some(path)) = fill_utf16_buf(
                 |buf, size| c::GetWindowsDirectoryW(buf, size),
                 |buf| exists(PathBuf::from(OsString::from_wide(buf))),
             ) {
@@ -851,10 +844,8 @@ fn make_command_line(argv0: &OsStr, args: &[Arg], force_quotes: bool) -> io::Res
 
 // Get `cmd.exe` for use with bat scripts, encoded as a UTF-16 string.
 fn command_prompt() -> io::Result<Vec<u16>> {
-    let mut system: Vec<u16> = super::fill_utf16_buf(
-        |buf, size| unsafe { c::GetSystemDirectoryW(buf, size) },
-        |buf| buf.into(),
-    )?;
+    let mut system: Vec<u16> =
+        fill_utf16_buf(|buf, size| unsafe { c::GetSystemDirectoryW(buf, size) }, |buf| buf.into())?;
     system.extend("\\cmd.exe".encode_utf16().chain([0]));
     Ok(system)
 }
diff --git a/library/std/src/sys/pal/windows/process/tests.rs b/library/std/src/sys/process/windows/tests.rs
index 1377e12162f..1377e12162f 100644
--- a/library/std/src/sys/pal/windows/process/tests.rs
+++ b/library/std/src/sys/process/windows/tests.rs
diff --git a/library/std/src/sys/random/linux.rs b/library/std/src/sys/random/linux.rs
index e3cb79285cd..c0591ec0c15 100644
--- a/library/std/src/sys/random/linux.rs
+++ b/library/std/src/sys/random/linux.rs
@@ -73,13 +73,13 @@ fn getrandom(mut bytes: &mut [u8], insecure: bool) {
     // A weak symbol allows interposition, e.g. for perf measurements that want to
     // disable randomness for consistency. Otherwise, we'll try a raw syscall.
     // (`getrandom` was added in glibc 2.25, musl 1.1.20, android API level 28)
-    syscall! {
+    syscall!(
         fn getrandom(
             buffer: *mut libc::c_void,
             length: libc::size_t,
-            flags: libc::c_uint
-        ) -> libc::ssize_t
-    }
+            flags: libc::c_uint,
+        ) -> libc::ssize_t;
+    );
 
     static GETRANDOM_AVAILABLE: AtomicBool = AtomicBool::new(true);
     static GRND_INSECURE_AVAILABLE: AtomicBool = AtomicBool::new(true);
diff --git a/library/std/src/sys/random/trusty.rs b/library/std/src/sys/random/trusty.rs
index da6ca3eea24..e4db24695f8 100644
--- a/library/std/src/sys/random/trusty.rs
+++ b/library/std/src/sys/random/trusty.rs
@@ -1,4 +1,4 @@
-extern "C" {
+unsafe extern "C" {
     fn trusty_rng_secure_rand(randomBuffer: *mut core::ffi::c_void, randomBufferLen: libc::size_t);
 }
 
diff --git a/library/std/src/sys/stdio/sgx.rs b/library/std/src/sys/stdio/sgx.rs
index 1894c098d18..2cf47f49192 100644
--- a/library/std/src/sys/stdio/sgx.rs
+++ b/library/std/src/sys/stdio/sgx.rs
@@ -3,9 +3,9 @@ use fortanix_sgx_abi as abi;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::sys::fd::FileDesc;
 
-pub struct Stdin(());
-pub struct Stdout(());
-pub struct Stderr(());
+pub struct Stdin;
+pub struct Stdout;
+pub struct Stderr;
 
 fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R {
     let fd = FileDesc::new(fd);
@@ -16,7 +16,7 @@ fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R {
 
 impl Stdin {
     pub const fn new() -> Stdin {
-        Stdin(())
+        Stdin
     }
 }
 
@@ -41,7 +41,7 @@ impl io::Read for Stdin {
 
 impl Stdout {
     pub const fn new() -> Stdout {
-        Stdout(())
+        Stdout
     }
 }
 
@@ -66,7 +66,7 @@ impl io::Write for Stdout {
 
 impl Stderr {
     pub const fn new() -> Stderr {
-        Stderr(())
+        Stderr
     }
 }
 
diff --git a/library/std/src/sys/stdio/solid.rs b/library/std/src/sys/stdio/solid.rs
index a2ff4bb212f..55daf0b54b9 100644
--- a/library/std/src/sys/stdio/solid.rs
+++ b/library/std/src/sys/stdio/solid.rs
@@ -1,22 +1,13 @@
+#[expect(dead_code)]
+#[path = "unsupported.rs"]
+mod unsupported_stdio;
+
 use crate::io;
 use crate::sys::pal::abi;
 
-pub struct Stdin;
+pub type Stdin = unsupported_stdio::Stdin;
 pub struct Stdout;
-pub struct Stderr;
-struct PanicOutput;
-
-impl Stdin {
-    pub const fn new() -> Stdin {
-        Stdin
-    }
-}
-
-impl io::Read for Stdin {
-    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
-        Ok(0)
-    }
-}
+pub type Stderr = Stdout;
 
 impl Stdout {
     pub const fn new() -> Stdout {
@@ -35,46 +26,12 @@ impl io::Write for Stdout {
     }
 }
 
-impl Stderr {
-    pub const fn new() -> Stderr {
-        Stderr
-    }
-}
-
-impl io::Write for Stderr {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        unsafe { abi::SOLID_LOG_write(buf.as_ptr(), buf.len()) };
-        Ok(buf.len())
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-impl PanicOutput {
-    pub const fn new() -> PanicOutput {
-        PanicOutput
-    }
-}
-
-impl io::Write for PanicOutput {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        unsafe { abi::SOLID_LOG_write(buf.as_ptr(), buf.len()) };
-        Ok(buf.len())
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-pub const STDIN_BUF_SIZE: usize = 0;
+pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE;
 
 pub fn is_ebadf(_err: &io::Error) -> bool {
     true
 }
 
 pub fn panic_output() -> Option<impl io::Write> {
-    Some(PanicOutput::new())
+    Some(Stderr::new())
 }
diff --git a/library/std/src/sys/stdio/teeos.rs b/library/std/src/sys/stdio/teeos.rs
index 67e251812da..27b3292bf8f 100644
--- a/library/std/src/sys/stdio/teeos.rs
+++ b/library/std/src/sys/stdio/teeos.rs
@@ -1,12 +1,16 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 
+#[expect(dead_code)]
+#[path = "unsupported.rs"]
+mod unsupported_stdio;
+
 use core::arch::asm;
 
 use crate::io;
 
-pub struct Stdin;
+pub type Stdin = unsupported_stdio::Stdin;
 pub struct Stdout;
-pub struct Stderr;
+pub type Stderr = Stdout;
 
 const KCALL_DEBUG_CMD_PUT_BYTES: i64 = 2;
 
@@ -25,27 +29,6 @@ unsafe fn debug_call(cap_ref: u64, call_no: i64, arg1: u64, arg2: u64) -> i32 {
     ret as i32
 }
 
-fn print_buf(s: &[u8]) -> io::Result<usize> {
-    // Corresponds to `HM_DEBUG_PUT_BYTES_LIMIT`.
-    const MAX_LEN: usize = 512;
-    let len = if s.len() > MAX_LEN { MAX_LEN } else { s.len() };
-    let result = unsafe { debug_call(0, KCALL_DEBUG_CMD_PUT_BYTES, s.as_ptr() as u64, len as u64) };
-
-    if result == 0 { Ok(len) } else { Err(io::Error::from(io::ErrorKind::InvalidInput)) }
-}
-
-impl Stdin {
-    pub const fn new() -> Stdin {
-        Stdin
-    }
-}
-
-impl io::Read for Stdin {
-    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
-        Ok(0)
-    }
-}
-
 impl Stdout {
     pub const fn new() -> Stdout {
         Stdout
@@ -54,23 +37,13 @@ impl Stdout {
 
 impl io::Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        print_buf(buf)
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
+        // Corresponds to `HM_DEBUG_PUT_BYTES_LIMIT`.
+        const MAX_LEN: usize = 512;
+        let len = buf.len().min(MAX_LEN);
+        let result =
+            unsafe { debug_call(0, KCALL_DEBUG_CMD_PUT_BYTES, buf.as_ptr() as u64, len as u64) };
 
-impl Stderr {
-    pub const fn new() -> Stderr {
-        Stderr
-    }
-}
-
-impl io::Write for Stderr {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        print_buf(buf)
+        if result == 0 { Ok(len) } else { Err(io::Error::from(io::ErrorKind::InvalidInput)) }
     }
 
     fn flush(&mut self) -> io::Result<()> {
@@ -78,7 +51,7 @@ impl io::Write for Stderr {
     }
 }
 
-pub const STDIN_BUF_SIZE: usize = 0;
+pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE;
 
 pub fn is_ebadf(err: &io::Error) -> bool {
     err.raw_os_error() == Some(libc::EBADF as i32)
diff --git a/library/std/src/sys/stdio/unix.rs b/library/std/src/sys/stdio/unix.rs
index 08a06e0da9f..8535e3539e9 100644
--- a/library/std/src/sys/stdio/unix.rs
+++ b/library/std/src/sys/stdio/unix.rs
@@ -11,13 +11,13 @@ use crate::os::hermit::io::FromRawFd;
 use crate::os::unix::io::FromRawFd;
 use crate::sys::fd::FileDesc;
 
-pub struct Stdin(());
-pub struct Stdout(());
-pub struct Stderr(());
+pub struct Stdin;
+pub struct Stdout;
+pub struct Stderr;
 
 impl Stdin {
     pub const fn new() -> Stdin {
-        Stdin(())
+        Stdin
     }
 }
 
@@ -42,7 +42,7 @@ impl io::Read for Stdin {
 
 impl Stdout {
     pub const fn new() -> Stdout {
-        Stdout(())
+        Stdout
     }
 }
 
@@ -68,7 +68,7 @@ impl io::Write for Stdout {
 
 impl Stderr {
     pub const fn new() -> Stderr {
-        Stderr(())
+        Stderr
     }
 }
 
diff --git a/library/std/src/sys/stdio/unsupported.rs b/library/std/src/sys/stdio/unsupported.rs
index b5e3f5be988..177264f5c10 100644
--- a/library/std/src/sys/stdio/unsupported.rs
+++ b/library/std/src/sys/stdio/unsupported.rs
@@ -1,8 +1,8 @@
-use crate::io;
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 
 pub struct Stdin;
 pub struct Stdout;
-pub struct Stderr;
+pub type Stderr = Stdout;
 
 impl Stdin {
     pub const fn new() -> Stdin {
@@ -11,9 +11,47 @@ impl Stdin {
 }
 
 impl io::Read for Stdin {
+    #[inline]
     fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
         Ok(0)
     }
+
+    #[inline]
+    fn read_buf(&mut self, _cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
+    fn read_vectored(&mut self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        Ok(0)
+    }
+
+    #[inline]
+    fn is_read_vectored(&self) -> bool {
+        // Do not force `Chain<Empty, T>` or `Chain<T, Empty>` to use vectored
+        // reads, unless the other reader is vectored.
+        false
+    }
+
+    #[inline]
+    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
+        if !buf.is_empty() { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) }
+    }
+
+    #[inline]
+    fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        if cursor.capacity() != 0 { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) }
+    }
+
+    #[inline]
+    fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
+        Ok(0)
+    }
+
+    #[inline]
+    fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
+        Ok(0)
+    }
 }
 
 impl Stdout {
@@ -23,26 +61,35 @@ impl Stdout {
 }
 
 impl io::Write for Stdout {
+    #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         Ok(buf.len())
     }
 
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
+    #[inline]
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        let total_len = bufs.iter().map(|b| b.len()).sum();
+        Ok(total_len)
     }
-}
 
-impl Stderr {
-    pub const fn new() -> Stderr {
-        Stderr
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
     }
-}
 
-impl io::Write for Stderr {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        Ok(buf.len())
+    #[inline]
+    fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
+        Ok(())
     }
 
+    #[inline]
+    fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
+        Ok(())
+    }
+
+    // Keep the default write_fmt so the `fmt::Arguments` are still evaluated.
+
+    #[inline]
     fn flush(&mut self) -> io::Result<()> {
         Ok(())
     }
diff --git a/library/std/src/sys/stdio/xous.rs b/library/std/src/sys/stdio/xous.rs
index 71736145221..a92167642b7 100644
--- a/library/std/src/sys/stdio/xous.rs
+++ b/library/std/src/sys/stdio/xous.rs
@@ -1,27 +1,18 @@
-use crate::io;
-
-pub struct Stdin;
-pub struct Stdout {}
-pub struct Stderr;
+#[expect(dead_code)]
+#[path = "unsupported.rs"]
+mod unsupported_stdio;
 
+use crate::io;
 use crate::os::xous::ffi::{Connection, lend, try_lend, try_scalar};
 use crate::os::xous::services::{LogLend, LogScalar, log_server, try_connect};
 
-impl Stdin {
-    pub const fn new() -> Stdin {
-        Stdin
-    }
-}
-
-impl io::Read for Stdin {
-    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
-        Ok(0)
-    }
-}
+pub type Stdin = unsupported_stdio::Stdin;
+pub struct Stdout;
+pub struct Stderr;
 
 impl Stdout {
     pub const fn new() -> Stdout {
-        Stdout {}
+        Stdout
     }
 }
 
@@ -73,7 +64,7 @@ impl io::Write for Stderr {
     }
 }
 
-pub const STDIN_BUF_SIZE: usize = 0;
+pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE;
 
 pub fn is_ebadf(_err: &io::Error) -> bool {
     true
diff --git a/library/std/src/thread/spawnhook.rs b/library/std/src/thread/spawnhook.rs
index 99b5ad9cb9f..98f471ad54b 100644
--- a/library/std/src/thread/spawnhook.rs
+++ b/library/std/src/thread/spawnhook.rs
@@ -113,18 +113,23 @@ where
 pub(super) fn run_spawn_hooks(thread: &Thread) -> ChildSpawnHooks {
     // Get a snapshot of the spawn hooks.
     // (Increments the refcount to the first node.)
-    let hooks = SPAWN_HOOKS.with(|hooks| {
+    if let Ok(hooks) = SPAWN_HOOKS.try_with(|hooks| {
         let snapshot = hooks.take();
         hooks.set(snapshot.clone());
         snapshot
-    });
-    // Iterate over the hooks, run them, and collect the results in a vector.
-    let to_run: Vec<_> = iter::successors(hooks.first.as_deref(), |hook| hook.next.as_deref())
-        .map(|hook| (hook.hook)(thread))
-        .collect();
-    // Pass on the snapshot of the hooks and the results to the new thread,
-    // which will then run SpawnHookResults::run().
-    ChildSpawnHooks { hooks, to_run }
+    }) {
+        // Iterate over the hooks, run them, and collect the results in a vector.
+        let to_run: Vec<_> = iter::successors(hooks.first.as_deref(), |hook| hook.next.as_deref())
+            .map(|hook| (hook.hook)(thread))
+            .collect();
+        // Pass on the snapshot of the hooks and the results to the new thread,
+        // which will then run SpawnHookResults::run().
+        ChildSpawnHooks { hooks, to_run }
+    } else {
+        // TLS has been destroyed. Skip running the hooks.
+        // See https://github.com/rust-lang/rust/issues/138696
+        ChildSpawnHooks::default()
+    }
 }
 
 /// The results of running the spawn hooks.
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index 06c347af181..59ec48a57d1 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -108,6 +108,7 @@ fn test_is_finished() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_join_panic() {
     match thread::spawn(move || panic!()).join() {
         result::Result::Err(_) => (),
@@ -210,6 +211,7 @@ fn test_simple_newsched_spawn() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_try_panic_message_string_literal() {
     match thread::spawn(move || {
         panic!("static string");
@@ -226,6 +228,7 @@ fn test_try_panic_message_string_literal() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_try_panic_any_message_owned_str() {
     match thread::spawn(move || {
         panic_any("owned string".to_string());
@@ -242,6 +245,7 @@ fn test_try_panic_any_message_owned_str() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_try_panic_any_message_any() {
     match thread::spawn(move || {
         panic_any(Box::new(413u16) as Box<dyn Any + Send>);
@@ -260,6 +264,7 @@ fn test_try_panic_any_message_any() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_try_panic_any_message_unit_struct() {
     struct Juju;