diff options
| author | Laurențiu Nicola <lnicola@dend.ro> | 2024-10-17 10:04:49 +0300 |
|---|---|---|
| committer | Laurențiu Nicola <lnicola@dend.ro> | 2024-10-17 10:04:49 +0300 |
| commit | 1b7cd2bed6efac6ecbe78e9006a9f60878d4a450 (patch) | |
| tree | ddd444e2cdf64d53dc4d522ca38f1a5e631623a2 /library/std/src/sys | |
| parent | aff69ccfb2b7da9374dd47f13e626a980ce8338a (diff) | |
| parent | dd5127615ad626741a1116d022cf784637ac05df (diff) | |
| download | rust-1b7cd2bed6efac6ecbe78e9006a9f60878d4a450.tar.gz rust-1b7cd2bed6efac6ecbe78e9006a9f60878d4a450.zip | |
Merge from rust-lang/rust
Diffstat (limited to 'library/std/src/sys')
| -rw-r--r-- | library/std/src/sys/pal/sgx/net.rs | 14 | ||||
| -rw-r--r-- | library/std/src/sys/pal/uefi/helpers.rs | 24 | ||||
| -rw-r--r-- | library/std/src/sys/pal/uefi/os.rs | 63 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/fs.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/process/process_common.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/process/process_unix.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/process/process_vxworks.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/pal/wasip2/net.rs | 74 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/args.rs | 19 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/c.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/compat.rs | 8 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/mod.rs | 1 | ||||
| -rw-r--r-- | library/std/src/sys/sync/once_box.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/sync/thread_parking/mod.rs | 1 |
14 files changed, 153 insertions, 71 deletions
diff --git a/library/std/src/sys/pal/sgx/net.rs b/library/std/src/sys/pal/sgx/net.rs index 44913ffe3a9..c966886d163 100644 --- a/library/std/src/sys/pal/sgx/net.rs +++ b/library/std/src/sys/pal/sgx/net.rs @@ -78,9 +78,8 @@ fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> { } } -fn addr_to_sockaddr(addr: &Option<String>) -> io::Result<SocketAddr> { - addr.as_ref() - .ok_or(io::ErrorKind::AddrNotAvailable)? +fn addr_to_sockaddr(addr: Option<&str>) -> io::Result<SocketAddr> { + addr.ok_or(io::ErrorKind::AddrNotAvailable)? .to_socket_addrs() // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry .map(|mut it| it.next().unwrap()) @@ -161,11 +160,11 @@ impl TcpStream { } pub fn peer_addr(&self) -> io::Result<SocketAddr> { - addr_to_sockaddr(&self.peer_addr) + addr_to_sockaddr(self.peer_addr.as_deref()) } pub fn socket_addr(&self) -> io::Result<SocketAddr> { - addr_to_sockaddr(&self.inner.local_addr) + addr_to_sockaddr(self.inner.local_addr.as_deref()) } pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { @@ -255,13 +254,14 @@ impl TcpListener { } pub fn socket_addr(&self) -> io::Result<SocketAddr> { - addr_to_sockaddr(&self.inner.local_addr) + addr_to_sockaddr(self.inner.local_addr.as_deref()) } pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { let (fd, local_addr, peer_addr) = usercalls::accept_stream(self.inner.inner.raw())?; let peer_addr = Some(peer_addr); - let ret_peer = addr_to_sockaddr(&peer_addr).unwrap_or_else(|_| ([0; 4], 0).into()); + let ret_peer = + addr_to_sockaddr(peer_addr.as_deref()).unwrap_or_else(|_| ([0; 4], 0).into()); Ok((TcpStream { inner: Socket::new(fd, local_addr), peer_addr }, ret_peer)) } diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index bd8a6684b64..4ced7065c82 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -177,16 +177,8 @@ pub(crate) fn device_path_to_text(path: NonNull<device_path::Protocol>) -> io::R ) }; - // SAFETY: `convert_device_path_to_text` returns a pointer to a null-terminated UTF-16 - // string, and that string cannot be deallocated prior to dropping the `WStrUnits`, so - // it's safe for `WStrUnits` to use. - let path_len = unsafe { - WStrUnits::new(path_ptr) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))? - .count() - }; - - let path = OsString::from_wide(unsafe { slice::from_raw_parts(path_ptr.cast(), path_len) }); + let path = os_string_from_raw(path_ptr) + .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?; if let Some(boot_services) = crate::os::uefi::env::boot_services() { let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast(); @@ -420,3 +412,15 @@ impl<T> Drop for OwnedTable<T> { unsafe { crate::alloc::dealloc(self.ptr as *mut u8, self.layout) }; } } + +/// Create OsString from a pointer to NULL terminated UTF-16 string +pub(crate) fn os_string_from_raw(ptr: *mut r_efi::efi::Char16) -> Option<OsString> { + let path_len = unsafe { WStrUnits::new(ptr)?.count() }; + Some(OsString::from_wide(unsafe { slice::from_raw_parts(ptr.cast(), path_len) })) +} + +/// Create NULL terminated UTF-16 string +pub(crate) fn os_string_to_raw(s: &OsStr) -> Option<Box<[r_efi::efi::Char16]>> { + let temp = s.encode_wide().chain(Some(0)).collect::<Box<[r_efi::efi::Char16]>>(); + if temp[..temp.len() - 1].contains(&0) { None } else { Some(temp) } +} diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs index 9aee67d622f..4eb7698b43a 100644 --- a/library/std/src/sys/pal/uefi/os.rs +++ b/library/std/src/sys/pal/uefi/os.rs @@ -1,7 +1,7 @@ use r_efi::efi::Status; use r_efi::efi::protocols::{device_path, loaded_image_device_path}; -use super::{RawOsError, helpers, unsupported}; +use super::{RawOsError, helpers, unsupported_err}; use crate::error::Error as StdError; use crate::ffi::{OsStr, OsString}; use crate::marker::PhantomData; @@ -125,11 +125,32 @@ pub fn error_string(errno: RawOsError) -> String { } pub fn getcwd() -> io::Result<PathBuf> { - unsupported() + match uefi_shell::open_shell() { + Some(shell) => { + // SAFETY: path_ptr is managed by UEFI shell and should not be deallocated + let path_ptr = unsafe { ((*shell.as_ptr()).get_cur_dir)(crate::ptr::null_mut()) }; + helpers::os_string_from_raw(path_ptr) + .map(PathBuf::from) + .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path")) + } + None => { + let mut t = current_exe()?; + // SAFETY: This should never fail since the disk prefix will be present even for root + // executables + assert!(t.pop()); + Ok(t) + } + } } -pub fn chdir(_: &path::Path) -> io::Result<()> { - unsupported() +pub fn chdir(p: &path::Path) -> io::Result<()> { + let shell = uefi_shell::open_shell().ok_or(unsupported_err())?; + + let mut p = helpers::os_string_to_raw(p.as_os_str()) + .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?; + + let r = unsafe { ((*shell.as_ptr()).set_cur_dir)(crate::ptr::null_mut(), p.as_mut_ptr()) }; + if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); @@ -239,3 +260,37 @@ pub fn exit(code: i32) -> ! { pub fn getpid() -> u32 { panic!("no pids on this platform") } + +mod uefi_shell { + use r_efi::protocols::shell; + + use super::super::helpers; + use crate::ptr::NonNull; + use crate::sync::atomic::{AtomicPtr, Ordering}; + + pub fn open_shell() -> Option<NonNull<shell::Protocol>> { + static LAST_VALID_HANDLE: AtomicPtr<crate::ffi::c_void> = + AtomicPtr::new(crate::ptr::null_mut()); + + if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) { + if let Ok(protocol) = helpers::open_protocol::<shell::Protocol>( + handle, + r_efi::protocols::shell::PROTOCOL_GUID, + ) { + return Some(protocol); + } + } + + let handles = helpers::locate_handles(shell::PROTOCOL_GUID).ok()?; + for handle in handles { + if let Ok(protocol) = + helpers::open_protocol::<shell::Protocol>(handle, shell::PROTOCOL_GUID) + { + LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release); + return Some(protocol); + } + } + + None + } +} diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 39aabf0b2d6..567577b2b4d 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -899,7 +899,7 @@ impl DirEntry { target_os = "android", target_os = "hurd" ), - not(miri) + not(miri) // no dirfd on Miri ))] pub fn metadata(&self) -> io::Result<FileAttr> { let fd = cvt(unsafe { dirfd(self.dir.dirp.0) })?; @@ -1538,7 +1538,7 @@ impl fmt::Debug for File { Some(PathBuf::from(OsString::from_vec(buf))) } - #[cfg(all(target_os = "freebsd", target_arch = "x86_64"))] + #[cfg(target_os = "freebsd")] fn get_path(fd: c_int) -> Option<PathBuf> { let info = Box::<libc::kinfo_file>::new_zeroed(); let mut info = unsafe { info.assume_init() }; @@ -1566,7 +1566,7 @@ impl fmt::Debug for File { #[cfg(not(any( target_os = "linux", target_os = "vxworks", - all(target_os = "freebsd", target_arch = "x86_64"), + target_os = "freebsd", target_os = "netbsd", target_os = "illumos", target_os = "solaris", diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/pal/unix/process/process_common.rs index d9c41d43487..13290fed762 100644 --- a/library/std/src/sys/pal/unix/process/process_common.rs +++ b/library/std/src/sys/pal/unix/process/process_common.rs @@ -312,8 +312,8 @@ impl Command { } #[allow(dead_code)] - pub fn get_cwd(&self) -> &Option<CString> { - &self.cwd + pub fn get_cwd(&self) -> Option<&CStr> { + self.cwd.as_deref() } #[allow(dead_code)] pub fn get_uid(&self) -> Option<uid_t> { diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 5d30f388da1..4551d49e841 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -335,7 +335,7 @@ impl Command { cvt(libc::setuid(u as uid_t))?; } } - if let Some(ref cwd) = *self.get_cwd() { + if let Some(cwd) = self.get_cwd() { cvt(libc::chdir(cwd.as_ptr()))?; } diff --git a/library/std/src/sys/pal/unix/process/process_vxworks.rs b/library/std/src/sys/pal/unix/process/process_vxworks.rs index 2d9a304c495..38daf6af918 100644 --- a/library/std/src/sys/pal/unix/process/process_vxworks.rs +++ b/library/std/src/sys/pal/unix/process/process_vxworks.rs @@ -57,7 +57,7 @@ impl Command { t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))); } - if let Some(ref cwd) = *self.get_cwd() { + if let Some(cwd) = self.get_cwd() { t!(cvt(libc::chdir(cwd.as_ptr()))); } diff --git a/library/std/src/sys/pal/wasip2/net.rs b/library/std/src/sys/pal/wasip2/net.rs index c40eb229ba9..06e623df843 100644 --- a/library/std/src/sys/pal/wasip2/net.rs +++ b/library/std/src/sys/pal/wasip2/net.rs @@ -2,13 +2,12 @@ use libc::{c_int, c_void, size_t}; -use super::fd::WasiFd; use crate::ffi::CStr; use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut}; use crate::net::{Shutdown, SocketAddr}; -use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::sys::unsupported; -use crate::sys_common::net::{TcpListener, getsockopt, setsockopt, sockaddr_to_addr}; +use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr}; use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::{Duration, Instant}; use crate::{cmp, mem, str}; @@ -71,7 +70,9 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> { pub fn init() {} -pub struct Socket(WasiFd); +pub struct WasiSocket(OwnedFd); + +pub struct Socket(WasiSocket); impl Socket { pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> { @@ -327,53 +328,90 @@ impl Socket { } } -impl AsInner<WasiFd> for Socket { +impl AsInner<OwnedFd> for WasiSocket { #[inline] - fn as_inner(&self) -> &WasiFd { + fn as_inner(&self) -> &OwnedFd { &self.0 } } -impl IntoInner<WasiFd> for Socket { - fn into_inner(self) -> WasiFd { +impl IntoInner<OwnedFd> for WasiSocket { + fn into_inner(self) -> OwnedFd { self.0 } } -impl FromInner<WasiFd> for Socket { - fn from_inner(inner: WasiFd) -> Socket { - Socket(inner) +impl FromInner<OwnedFd> for WasiSocket { + fn from_inner(owned_fd: OwnedFd) -> Self { + Self(owned_fd) } } -impl AsFd for Socket { +impl AsFd for WasiSocket { fn as_fd(&self) -> BorrowedFd<'_> { self.0.as_fd() } } -impl AsRawFd for Socket { +impl AsRawFd for WasiSocket { #[inline] fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } } -impl IntoRawFd for Socket { +impl IntoRawFd for WasiSocket { fn into_raw_fd(self) -> RawFd { self.0.into_raw_fd() } } -impl FromRawFd for Socket { +impl FromRawFd for WasiSocket { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } } } -impl AsInner<Socket> for TcpListener { +impl AsInner<WasiSocket> for Socket { + #[inline] + fn as_inner(&self) -> &WasiSocket { + &self.0 + } +} + +impl IntoInner<WasiSocket> for Socket { + fn into_inner(self) -> WasiSocket { + self.0 + } +} + +impl FromInner<WasiSocket> for Socket { + fn from_inner(sock: WasiSocket) -> Socket { + Socket(sock) + } +} + +impl AsFd for Socket { + fn as_fd(&self) -> BorrowedFd<'_> { + self.0.as_fd() + } +} + +impl AsRawFd for Socket { #[inline] - fn as_inner(&self) -> &Socket { - &self.socket() + fn as_raw_fd(&self) -> RawFd { + self.0.as_raw_fd() + } +} + +impl IntoRawFd for Socket { + fn into_raw_fd(self) -> RawFd { + self.0.into_raw_fd() + } +} + +impl FromRawFd for Socket { + unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } } } diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs index 848632ec2a7..e9fc19bcb99 100644 --- a/library/std/src/sys/pal/windows/args.rs +++ b/library/std/src/sys/pal/windows/args.rs @@ -18,17 +18,6 @@ use crate::sys_common::AsInner; use crate::sys_common::wstr::WStrUnits; use crate::{fmt, io, iter, vec}; -/// This is the const equivalent to `NonZero::new(n).unwrap()` -/// -/// FIXME(const-hack): This can be removed once `Option::unwrap` is stably const. -/// See the `const_option` feature (#67441). -const fn non_zero_u16(n: u16) -> NonZero<u16> { - match NonZero::new(n) { - Some(n) => n, - None => panic!("called `unwrap` on a `None` value"), - } -} - pub fn args() -> Args { // SAFETY: `GetCommandLineW` returns a pointer to a null terminated UTF-16 // string so it's safe for `WStrUnits` to use. @@ -66,10 +55,10 @@ fn parse_lp_cmd_line<'a, F: Fn() -> OsString>( lp_cmd_line: Option<WStrUnits<'a>>, exe_name: F, ) -> Vec<OsString> { - const BACKSLASH: NonZero<u16> = non_zero_u16(b'\\' as u16); - const QUOTE: NonZero<u16> = non_zero_u16(b'"' as u16); - const TAB: NonZero<u16> = non_zero_u16(b'\t' as u16); - const SPACE: NonZero<u16> = non_zero_u16(b' ' as u16); + const BACKSLASH: NonZero<u16> = NonZero::new(b'\\' as u16).unwrap(); + const QUOTE: NonZero<u16> = NonZero::new(b'"' as u16).unwrap(); + const TAB: NonZero<u16> = NonZero::new(b'\t' as u16).unwrap(); + const SPACE: NonZero<u16> = NonZero::new(b' ' as u16).unwrap(); let mut ret_val = Vec::new(); // If the cmd line pointer is null or it points to an empty string then diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index b65ad7dbe8c..9ce3e912caf 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -175,9 +175,9 @@ extern "system" { pub fn WakeByAddressAll(address: *const c_void); } +// These are loaded by `load_synch_functions`. #[cfg(target_vendor = "win7")] compat_fn_optional! { - crate::sys::compat::load_synch_functions(); pub fn WaitOnAddress( address: *const c_void, compareaddress: *const c_void, diff --git a/library/std/src/sys/pal/windows/compat.rs b/library/std/src/sys/pal/windows/compat.rs index c8e25dd0c94..42999da1664 100644 --- a/library/std/src/sys/pal/windows/compat.rs +++ b/library/std/src/sys/pal/windows/compat.rs @@ -198,11 +198,10 @@ macro_rules! compat_fn_with_fallback { /// Optionally loaded functions. /// -/// Actual loading of the function defers to $load_functions. +/// Relies on the functions being pre-loaded elsewhere. #[cfg(target_vendor = "win7")] macro_rules! compat_fn_optional { - ($load_functions:expr; - $( + ($( $(#[$meta:meta])* $vis:vis fn $symbol:ident($($argname:ident: $argtype:ty),*) $(-> $rettype:ty)?; )+) => ( @@ -221,9 +220,6 @@ macro_rules! compat_fn_optional { #[inline(always)] pub fn option() -> Option<F> { - // Miri does not understand the way we do preloading - // therefore load the function here instead. - #[cfg(miri)] $load_functions; NonNull::new(PTR.load(Ordering::Relaxed)).map(|f| unsafe { mem::transmute(f) }) } } diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 1ea253e5e52..a9886012e8e 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -346,7 +346,6 @@ pub fn abort_internal() -> ! { } } -// miri is sensitive to changes here so check that miri is happy if touching this #[cfg(miri)] pub fn abort_internal() -> ! { crate::intrinsics::abort(); diff --git a/library/std/src/sys/sync/once_box.rs b/library/std/src/sys/sync/once_box.rs index 1422b5a1721..9d24db2245a 100644 --- a/library/std/src/sys/sync/once_box.rs +++ b/library/std/src/sys/sync/once_box.rs @@ -8,7 +8,7 @@ use crate::mem::replace; use crate::ptr::null_mut; use crate::sync::atomic::AtomicPtr; -use crate::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed}; +use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; pub(crate) struct OnceBox<T> { ptr: AtomicPtr<T>, @@ -60,7 +60,7 @@ impl<T> OnceBox<T> { #[cold] fn initialize(&self, f: impl FnOnce() -> Box<T>) -> &T { let new_ptr = Box::into_raw(f()); - match self.ptr.compare_exchange(null_mut(), new_ptr, AcqRel, Acquire) { + match self.ptr.compare_exchange(null_mut(), new_ptr, Release, Acquire) { Ok(_) => unsafe { &*new_ptr }, Err(ptr) => { // Lost the race to another thread. diff --git a/library/std/src/sys/sync/thread_parking/mod.rs b/library/std/src/sys/sync/thread_parking/mod.rs index 0ebc5e093ee..f4d8fa0a58c 100644 --- a/library/std/src/sys/sync/thread_parking/mod.rs +++ b/library/std/src/sys/sync/thread_parking/mod.rs @@ -23,6 +23,7 @@ cfg_if::cfg_if! { mod windows7; pub use windows7::Parker; } else if #[cfg(all(target_vendor = "apple", not(miri)))] { + // Doesn't work in Miri, see <https://github.com/rust-lang/miri/issues/2589>. mod darwin; pub use darwin::Parker; } else if #[cfg(target_os = "xous")] { |
