From c52e0596c5ef1d68bf0f283342fdb05db63248f9 Mon Sep 17 00:00:00 2001
From: joboet <jonasboettiger@icloud.com>
Date: Sun, 9 Feb 2025 18:42:07 +0100
Subject: [PATCH] std: move stdio to `sys`

As per #117276, this moves the platform definitions of `Stdout` and friends into `sys`. This PR also unifies the UNIX and Hermit implementations and moves the `__rust_print_err` function needed by libunwind on SGX into the dedicated module for such helper functions.
---
 library/std/src/sys/mod.rs                    |  1 +
 library/std/src/sys/pal/hermit/mod.rs         |  1 -
 library/std/src/sys/pal/hermit/stdio.rs       | 97 -------------------
 library/std/src/sys/pal/sgx/abi/mod.rs        |  2 +-
 .../src/sys/pal/sgx/libunwind_integration.rs  | 12 +++
 library/std/src/sys/pal/sgx/mod.rs            |  1 -
 library/std/src/sys/pal/solid/mod.rs          |  1 -
 library/std/src/sys/pal/teeos/mod.rs          |  1 -
 library/std/src/sys/pal/uefi/mod.rs           |  1 -
 library/std/src/sys/pal/unix/mod.rs           |  1 -
 library/std/src/sys/pal/unsupported/mod.rs    |  1 -
 library/std/src/sys/pal/wasi/mod.rs           |  1 -
 library/std/src/sys/pal/wasip2/mod.rs         |  2 -
 library/std/src/sys/pal/wasm/mod.rs           |  2 -
 library/std/src/sys/pal/windows/mod.rs        |  1 -
 library/std/src/sys/pal/xous/mod.rs           |  1 -
 library/std/src/sys/pal/zkvm/mod.rs           |  1 -
 library/std/src/sys/stdio/mod.rs              | 38 ++++++++
 .../sys/{pal/sgx/stdio.rs => stdio/sgx.rs}    | 20 +---
 .../{pal/solid/stdio.rs => stdio/solid.rs}    |  2 +-
 .../{pal/teeos/stdio.rs => stdio/teeos.rs}    |  0
 .../sys/{pal/uefi/stdio.rs => stdio/uefi.rs}  |  0
 .../sys/{pal/unix/stdio.rs => stdio/unix.rs}  | 33 ++++---
 .../stdio.rs => stdio/unsupported.rs}         |  0
 .../sys/{pal/wasi/stdio.rs => stdio/wasi.rs}  |  2 +-
 .../windows/stdio.rs => stdio/windows.rs}     |  2 +-
 .../windows/stdio => stdio/windows}/tests.rs  |  0
 .../sys/{pal/xous/stdio.rs => stdio/xous.rs}  |  0
 .../sys/{pal/zkvm/stdio.rs => stdio/zkvm.rs}  |  3 +-
 29 files changed, 77 insertions(+), 150 deletions(-)
 delete mode 100644 library/std/src/sys/pal/hermit/stdio.rs
 create mode 100644 library/std/src/sys/stdio/mod.rs
 rename library/std/src/sys/{pal/sgx/stdio.rs => stdio/sgx.rs} (71%)
 rename library/std/src/sys/{pal/solid/stdio.rs => stdio/solid.rs} (98%)
 rename library/std/src/sys/{pal/teeos/stdio.rs => stdio/teeos.rs} (100%)
 rename library/std/src/sys/{pal/uefi/stdio.rs => stdio/uefi.rs} (100%)
 rename library/std/src/sys/{pal/unix/stdio.rs => stdio/unix.rs} (59%)
 rename library/std/src/sys/{pal/unsupported/stdio.rs => stdio/unsupported.rs} (100%)
 rename library/std/src/sys/{pal/wasi/stdio.rs => stdio/wasi.rs} (98%)
 rename library/std/src/sys/{pal/windows/stdio.rs => stdio/windows.rs} (99%)
 rename library/std/src/sys/{pal/windows/stdio => stdio/windows}/tests.rs (100%)
 rename library/std/src/sys/{pal/xous/stdio.rs => stdio/xous.rs} (100%)
 rename library/std/src/sys/{pal/zkvm/stdio.rs => stdio/zkvm.rs} (97%)

diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index 9f8c1e53131..09677b9d642 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -18,6 +18,7 @@ pub mod net;
 pub mod os_str;
 pub mod path;
 pub mod random;
+pub mod stdio;
 pub mod sync;
 pub mod thread_local;
 
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index 5605c92db5b..608245bd430 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -27,7 +27,6 @@ pub mod os;
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
-pub mod stdio;
 pub mod thread;
 pub mod time;
 
diff --git a/library/std/src/sys/pal/hermit/stdio.rs b/library/std/src/sys/pal/hermit/stdio.rs
deleted file mode 100644
index 3ea00f5cc5e..00000000000
--- a/library/std/src/sys/pal/hermit/stdio.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-use super::hermit_abi;
-use crate::io;
-use crate::io::{IoSlice, IoSliceMut};
-use crate::mem::ManuallyDrop;
-use crate::os::hermit::io::FromRawFd;
-use crate::sys::fd::FileDesc;
-
-pub struct Stdin;
-pub struct Stdout;
-pub struct Stderr;
-
-impl Stdin {
-    pub const fn new() -> Stdin {
-        Stdin
-    }
-}
-
-impl io::Read for Stdin {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDIN_FILENO)).read(buf) }
-    }
-
-    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        unsafe {
-            ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDIN_FILENO)).read_vectored(bufs)
-        }
-    }
-
-    #[inline]
-    fn is_read_vectored(&self) -> bool {
-        true
-    }
-}
-
-impl Stdout {
-    pub const fn new() -> Stdout {
-        Stdout
-    }
-}
-
-impl io::Write for Stdout {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDOUT_FILENO)).write(buf) }
-    }
-
-    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        unsafe {
-            ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDOUT_FILENO)).write_vectored(bufs)
-        }
-    }
-
-    #[inline]
-    fn is_write_vectored(&self) -> bool {
-        true
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-impl Stderr {
-    pub const fn new() -> Stderr {
-        Stderr
-    }
-}
-
-impl io::Write for Stderr {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDERR_FILENO)).write(buf) }
-    }
-
-    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        unsafe {
-            ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDERR_FILENO)).write_vectored(bufs)
-        }
-    }
-
-    #[inline]
-    fn is_write_vectored(&self) -> bool {
-        true
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-pub const STDIN_BUF_SIZE: usize = 128;
-
-pub fn is_ebadf(err: &io::Error) -> bool {
-    err.raw_os_error() == Some(hermit_abi::EBADF)
-}
-
-pub fn panic_output() -> Option<impl io::Write> {
-    Some(Stderr::new())
-}
diff --git a/library/std/src/sys/pal/sgx/abi/mod.rs b/library/std/src/sys/pal/sgx/abi/mod.rs
index 90981bd6a6a..2c805a4d0af 100644
--- a/library/std/src/sys/pal/sgx/abi/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/mod.rs
@@ -6,7 +6,7 @@ use core::sync::atomic::{AtomicUsize, Ordering};
 use crate::io::Write;
 
 // runtime features
-pub(super) mod panic;
+pub mod panic;
 mod reloc;
 
 // library features
diff --git a/library/std/src/sys/pal/sgx/libunwind_integration.rs b/library/std/src/sys/pal/sgx/libunwind_integration.rs
index 6d0d78d1eb9..b5419ad05de 100644
--- a/library/std/src/sys/pal/sgx/libunwind_integration.rs
+++ b/library/std/src/sys/pal/sgx/libunwind_integration.rs
@@ -4,6 +4,7 @@
 #![cfg(not(test))]
 
 use crate::sys::sync::RwLock;
+use crate::{slice, str};
 
 // Verify that the byte pattern libunwind uses to initialize an RwLock is
 // equivalent to the value of RwLock::new(). If the value changes,
@@ -44,3 +45,14 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 {
     unsafe { (*p).write_unlock() };
     return 0;
 }
+
+#[unsafe(no_mangle)]
+pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
+    if s < 0 {
+        return;
+    }
+    let buf = unsafe { slice::from_raw_parts(m as *const u8, s as _) };
+    if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) {
+        eprint!("{s}");
+    }
+}
diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs
index 16aa5ab116a..bb419c2530e 100644
--- a/library/std/src/sys/pal/sgx/mod.rs
+++ b/library/std/src/sys/pal/sgx/mod.rs
@@ -18,7 +18,6 @@ pub mod os;
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
-pub mod stdio;
 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 2c3e50ed594..e4a61fdcfe3 100644
--- a/library/std/src/sys/pal/solid/mod.rs
+++ b/library/std/src/sys/pal/solid/mod.rs
@@ -27,7 +27,6 @@ pub mod os;
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
-pub mod stdio;
 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 2aeaf20134f..41b25121592 100644
--- a/library/std/src/sys/pal/teeos/mod.rs
+++ b/library/std/src/sys/pal/teeos/mod.rs
@@ -16,7 +16,6 @@ pub mod os;
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
-pub mod stdio;
 pub mod thread;
 #[allow(non_upper_case_globals)]
 #[path = "../unix/time.rs"]
diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
index 3dc83f6f654..714dc392688 100644
--- a/library/std/src/sys/pal/uefi/mod.rs
+++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -20,7 +20,6 @@ pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 pub mod process;
-pub mod stdio;
 pub mod thread;
 pub mod time;
 
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 0565e3ecfb9..419abe732ac 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -18,7 +18,6 @@ pub mod os;
 pub mod pipe;
 pub mod process;
 pub mod stack_overflow;
-pub mod stdio;
 pub mod sync;
 pub mod thread;
 pub mod thread_parking;
diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs
index 526e5008bd5..bcea699f3b2 100644
--- a/library/std/src/sys/pal/unsupported/mod.rs
+++ b/library/std/src/sys/pal/unsupported/mod.rs
@@ -5,7 +5,6 @@ pub mod env;
 pub mod os;
 pub mod pipe;
 pub mod process;
-pub mod stdio;
 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 a5ae1f513dc..c89832857dd 100644
--- a/library/std/src/sys/pal/wasi/mod.rs
+++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -25,7 +25,6 @@ pub mod os;
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
-pub mod stdio;
 pub mod thread;
 pub mod time;
 
diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs
index d4eb4369673..3008ba88753 100644
--- a/library/std/src/sys/pal/wasip2/mod.rs
+++ b/library/std/src/sys/pal/wasip2/mod.rs
@@ -22,8 +22,6 @@ pub mod os;
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
-#[path = "../wasi/stdio.rs"]
-pub mod stdio;
 #[path = "../wasi/thread.rs"]
 pub mod thread;
 #[path = "../wasi/time.rs"]
diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs
index cfadbdfe00c..175fe75357f 100644
--- a/library/std/src/sys/pal/wasm/mod.rs
+++ b/library/std/src/sys/pal/wasm/mod.rs
@@ -25,8 +25,6 @@ pub mod os;
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
-#[path = "../unsupported/stdio.rs"]
-pub mod stdio;
 #[path = "../unsupported/time.rs"]
 pub mod time;
 
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index bed79af395b..6eb68f3a3bc 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -23,7 +23,6 @@ pub mod handle;
 pub mod os;
 pub mod pipe;
 pub mod process;
-pub mod stdio;
 pub mod thread;
 pub mod time;
 cfg_if::cfg_if! {
diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs
index 3022d717b4a..7d823012ad1 100644
--- a/library/std/src/sys/pal/xous/mod.rs
+++ b/library/std/src/sys/pal/xous/mod.rs
@@ -8,7 +8,6 @@ pub mod os;
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
-pub mod stdio;
 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 ca5b479296d..499e2787201 100644
--- a/library/std/src/sys/pal/zkvm/mod.rs
+++ b/library/std/src/sys/pal/zkvm/mod.rs
@@ -19,7 +19,6 @@ pub mod os;
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
-pub mod stdio;
 #[path = "../unsupported/thread.rs"]
 pub mod thread;
 #[path = "../unsupported/time.rs"]
diff --git a/library/std/src/sys/stdio/mod.rs b/library/std/src/sys/stdio/mod.rs
new file mode 100644
index 00000000000..2a9167bfe96
--- /dev/null
+++ b/library/std/src/sys/stdio/mod.rs
@@ -0,0 +1,38 @@
+#![forbid(unsafe_op_in_unsafe_fn)]
+
+cfg_if::cfg_if! {
+    if #[cfg(any(
+        target_family = "unix",
+        target_os = "hermit"
+    ))] {
+        mod unix;
+        pub use unix::*;
+    } else if #[cfg(target_os = "windows")] {
+        mod windows;
+        pub use windows::*;
+    } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
+        mod sgx;
+        pub use sgx::*;
+    } else if #[cfg(target_os = "solid_asp3")] {
+        mod solid;
+        pub use solid::*;
+    } else if #[cfg(target_os = "teeos")] {
+        mod teeos;
+        pub use teeos::*;
+    } else if #[cfg(target_os = "uefi")] {
+        mod uefi;
+        pub use uefi::*;
+    } else if #[cfg(target_os = "wasi")] {
+        mod wasi;
+        pub use wasi::*;
+    } else if #[cfg(target_os = "xous")] {
+        mod xous;
+        pub use xous::*;
+    } else if #[cfg(target_os = "zkvm")] {
+        mod zkvm;
+        pub use zkvm::*;
+    } else {
+        mod unsupported;
+        pub use unsupported::*;
+    }
+}
diff --git a/library/std/src/sys/pal/sgx/stdio.rs b/library/std/src/sys/stdio/sgx.rs
similarity index 71%
rename from library/std/src/sys/pal/sgx/stdio.rs
rename to library/std/src/sys/stdio/sgx.rs
index 726a93acae4..03d754cb217 100644
--- a/library/std/src/sys/pal/sgx/stdio.rs
+++ b/library/std/src/sys/stdio/sgx.rs
@@ -1,10 +1,6 @@
 use fortanix_sgx_abi as abi;
 
 use crate::io;
-#[cfg(not(test))]
-use crate::slice;
-#[cfg(not(test))]
-use crate::str;
 use crate::sys::fd::FileDesc;
 
 pub struct Stdin(());
@@ -70,19 +66,5 @@ pub fn is_ebadf(err: &io::Error) -> bool {
 }
 
 pub fn panic_output() -> Option<impl io::Write> {
-    super::abi::panic::SgxPanicOutput::new()
-}
-
-// This function is needed by libunwind. The symbol is named in pre-link args
-// for the target specification, so keep that in sync.
-#[cfg(not(test))]
-#[unsafe(no_mangle)]
-pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
-    if s < 0 {
-        return;
-    }
-    let buf = unsafe { slice::from_raw_parts(m as *const u8, s as _) };
-    if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) {
-        eprint!("{s}");
-    }
+    crate::sys::pal::abi::panic::SgxPanicOutput::new()
 }
diff --git a/library/std/src/sys/pal/solid/stdio.rs b/library/std/src/sys/stdio/solid.rs
similarity index 98%
rename from library/std/src/sys/pal/solid/stdio.rs
rename to library/std/src/sys/stdio/solid.rs
index 50f0176967b..a2ff4bb212f 100644
--- a/library/std/src/sys/pal/solid/stdio.rs
+++ b/library/std/src/sys/stdio/solid.rs
@@ -1,5 +1,5 @@
-use super::abi;
 use crate::io;
+use crate::sys::pal::abi;
 
 pub struct Stdin;
 pub struct Stdout;
diff --git a/library/std/src/sys/pal/teeos/stdio.rs b/library/std/src/sys/stdio/teeos.rs
similarity index 100%
rename from library/std/src/sys/pal/teeos/stdio.rs
rename to library/std/src/sys/stdio/teeos.rs
diff --git a/library/std/src/sys/pal/uefi/stdio.rs b/library/std/src/sys/stdio/uefi.rs
similarity index 100%
rename from library/std/src/sys/pal/uefi/stdio.rs
rename to library/std/src/sys/stdio/uefi.rs
diff --git a/library/std/src/sys/pal/unix/stdio.rs b/library/std/src/sys/stdio/unix.rs
similarity index 59%
rename from library/std/src/sys/pal/unix/stdio.rs
rename to library/std/src/sys/stdio/unix.rs
index 8c2f61a40de..8d133857c59 100644
--- a/library/std/src/sys/pal/unix/stdio.rs
+++ b/library/std/src/sys/stdio/unix.rs
@@ -1,5 +1,15 @@
-use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
+#[cfg(target_os = "hermit")]
+use hermit_abi::{EBADF, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
+#[cfg(target_family = "unix")]
+use libc::{EBADF, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
+
+#[cfg(target_family = "unix")]
+use crate::io::BorrowedCursor;
+use crate::io::{self, IoSlice, IoSliceMut};
 use crate::mem::ManuallyDrop;
+#[cfg(target_os = "hermit")]
+use crate::os::hermit::io::FromRawFd;
+#[cfg(target_family = "unix")]
 use crate::os::unix::io::FromRawFd;
 use crate::sys::fd::FileDesc;
 
@@ -15,15 +25,16 @@ impl Stdin {
 
 impl io::Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read(buf) }
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDIN_FILENO)).read(buf) }
     }
 
+    #[cfg(not(target_os = "hermit"))]
     fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
-        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read_buf(buf) }
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDIN_FILENO)).read_buf(buf) }
     }
 
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read_vectored(bufs) }
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDIN_FILENO)).read_vectored(bufs) }
     }
 
     #[inline]
@@ -40,13 +51,11 @@ impl Stdout {
 
 impl io::Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDOUT_FILENO)).write(buf) }
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDOUT_FILENO)).write(buf) }
     }
 
     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        unsafe {
-            ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDOUT_FILENO)).write_vectored(bufs)
-        }
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDOUT_FILENO)).write_vectored(bufs) }
     }
 
     #[inline]
@@ -68,13 +77,11 @@ impl Stderr {
 
 impl io::Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDERR_FILENO)).write(buf) }
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDERR_FILENO)).write(buf) }
     }
 
     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        unsafe {
-            ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDERR_FILENO)).write_vectored(bufs)
-        }
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDERR_FILENO)).write_vectored(bufs) }
     }
 
     #[inline]
@@ -89,7 +96,7 @@ impl io::Write for Stderr {
 }
 
 pub fn is_ebadf(err: &io::Error) -> bool {
-    err.raw_os_error() == Some(libc::EBADF as i32)
+    err.raw_os_error() == Some(EBADF as i32)
 }
 
 pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
diff --git a/library/std/src/sys/pal/unsupported/stdio.rs b/library/std/src/sys/stdio/unsupported.rs
similarity index 100%
rename from library/std/src/sys/pal/unsupported/stdio.rs
rename to library/std/src/sys/stdio/unsupported.rs
diff --git a/library/std/src/sys/pal/wasi/stdio.rs b/library/std/src/sys/stdio/wasi.rs
similarity index 98%
rename from library/std/src/sys/pal/wasi/stdio.rs
rename to library/std/src/sys/stdio/wasi.rs
index fb21cb4d393..8105b0cfa2f 100644
--- a/library/std/src/sys/pal/wasi/stdio.rs
+++ b/library/std/src/sys/stdio/wasi.rs
@@ -1,10 +1,10 @@
 #![forbid(unsafe_op_in_unsafe_fn)]
 
-use super::fd::WasiFd;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::mem::ManuallyDrop;
 use crate::os::raw;
 use crate::os::wasi::io::{AsRawFd, FromRawFd};
+use crate::sys::pal::fd::WasiFd;
 
 pub struct Stdin;
 pub struct Stdout;
diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/stdio/windows.rs
similarity index 99%
rename from library/std/src/sys/pal/windows/stdio.rs
rename to library/std/src/sys/stdio/windows.rs
index 58d3406e138..9b27f76b9dd 100644
--- a/library/std/src/sys/pal/windows/stdio.rs
+++ b/library/std/src/sys/stdio/windows.rs
@@ -3,10 +3,10 @@
 use core::char::MAX_LEN_UTF8;
 use core::str::utf8_char_width;
 
-use super::api::{self, WinError};
 use crate::mem::MaybeUninit;
 use crate::os::windows::io::{FromRawHandle, IntoRawHandle};
 use crate::sys::handle::Handle;
+use crate::sys::pal::api::{self, WinError};
 use crate::sys::{c, cvt};
 use crate::{cmp, io, ptr, str};
 
diff --git a/library/std/src/sys/pal/windows/stdio/tests.rs b/library/std/src/sys/stdio/windows/tests.rs
similarity index 100%
rename from library/std/src/sys/pal/windows/stdio/tests.rs
rename to library/std/src/sys/stdio/windows/tests.rs
diff --git a/library/std/src/sys/pal/xous/stdio.rs b/library/std/src/sys/stdio/xous.rs
similarity index 100%
rename from library/std/src/sys/pal/xous/stdio.rs
rename to library/std/src/sys/stdio/xous.rs
diff --git a/library/std/src/sys/pal/zkvm/stdio.rs b/library/std/src/sys/stdio/zkvm.rs
similarity index 97%
rename from library/std/src/sys/pal/zkvm/stdio.rs
rename to library/std/src/sys/stdio/zkvm.rs
index 0bcb54744b0..f31c6c26e87 100644
--- a/library/std/src/sys/pal/zkvm/stdio.rs
+++ b/library/std/src/sys/stdio/zkvm.rs
@@ -1,6 +1,5 @@
-use super::abi;
-use super::abi::fileno;
 use crate::io::{self, BorrowedCursor};
+use crate::sys::pal::abi::{self, fileno};
 
 pub struct Stdin;
 pub struct Stdout;