diff options
| author | Ralf Jung <post@ralfj.de> | 2025-01-15 08:39:35 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-15 08:39:35 +0000 |
| commit | 5460fbe610cacae6de98a3dfc3ffe9573f0c9906 (patch) | |
| tree | 96bea23fabeb42d05f67dbb77d59f152a7e9f18d /library/std/src | |
| parent | d40f2f77bf372b0ce5fc16000c6ec1b95bd654c0 (diff) | |
| parent | 0930bfe6d29a2c9b5b71219ff4c946b732d3f3c7 (diff) | |
Merge pull request #4139 from rust-lang/rustup-2025-01-15
Automatic Rustup
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/path.rs | 15 | ||||
| -rw-r--r-- | library/std/src/rt.rs | 47 | ||||
| -rw-r--r-- | library/std/src/sys/pal/uefi/helpers.rs | 21 | ||||
| -rw-r--r-- | library/std/src/sys/pal/uefi/process.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/path/sgx.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/path/unix.rs | 11 | ||||
| -rw-r--r-- | library/std/src/sys/path/unsupported_backslash.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/path/windows.rs | 4 |
8 files changed, 73 insertions, 35 deletions
diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 35e920ab344..7fd08a97f1f 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -298,7 +298,7 @@ where } // Detect scheme on Redox -fn has_redox_scheme(s: &[u8]) -> bool { +pub(crate) fn has_redox_scheme(s: &[u8]) -> bool { cfg!(target_os = "redox") && s.contains(&b':') } @@ -2155,7 +2155,7 @@ impl Path { unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(s)) } } // The following (private!) function reveals the byte encoding used for OsStr. - fn as_u8_slice(&self) -> &[u8] { + pub(crate) fn as_u8_slice(&self) -> &[u8] { self.inner.as_encoded_bytes() } @@ -2323,14 +2323,7 @@ impl Path { #[must_use] #[allow(deprecated)] pub fn is_absolute(&self) -> bool { - if cfg!(target_os = "redox") { - // FIXME: Allow Redox prefixes - self.has_root() || has_redox_scheme(self.as_u8_slice()) - } else { - self.has_root() - && (cfg!(any(unix, target_os = "hermit", target_os = "wasi")) - || self.prefix().is_some()) - } + sys::path::is_absolute(self) } /// Returns `true` if the `Path` is relative, i.e., not absolute. @@ -2353,7 +2346,7 @@ impl Path { !self.is_absolute() } - fn prefix(&self) -> Option<Prefix<'_>> { + pub(crate) fn prefix(&self) -> Option<Prefix<'_>> { self.components().prefix } diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs index b2492238bd3..24a362072ab 100644 --- a/library/std/src/rt.rs +++ b/library/std/src/rt.rs @@ -67,7 +67,7 @@ macro_rules! rtunwrap { }; } -fn handle_rt_panic(e: Box<dyn Any + Send>) { +fn handle_rt_panic<T>(e: Box<dyn Any + Send>) -> T { mem::forget(e); rtabort!("initialization or cleanup bug"); } @@ -157,7 +157,7 @@ fn lang_start_internal( argc: isize, argv: *const *const u8, sigpipe: u8, -) -> Result<isize, !> { +) -> isize { // Guard against the code called by this function from unwinding outside of the Rust-controlled // code, which is UB. This is a requirement imposed by a combination of how the // `#[lang="start"]` attribute is implemented as well as by the implementation of the panicking @@ -168,19 +168,33 @@ fn lang_start_internal( // panic is a std implementation bug. A quite likely one too, as there isn't any way to // prevent std from accidentally introducing a panic to these functions. Another is from // user code from `main` or, more nefariously, as described in e.g. issue #86030. - // SAFETY: Only called once during runtime initialization. - panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) }) - .unwrap_or_else(handle_rt_panic); - let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize) - .map_err(move |e| { - mem::forget(e); - rtabort!("drop of the panic payload panicked"); + // + // We use `catch_unwind` with `handle_rt_panic` instead of `abort_unwind` to make the error in + // case of a panic a bit nicer. + panic::catch_unwind(move || { + // SAFETY: Only called once during runtime initialization. + unsafe { init(argc, argv, sigpipe) }; + + let ret_code = panic::catch_unwind(main).unwrap_or_else(move |payload| { + // Carefully dispose of the panic payload. + let payload = panic::AssertUnwindSafe(payload); + panic::catch_unwind(move || drop({ payload }.0)).unwrap_or_else(move |e| { + mem::forget(e); // do *not* drop the 2nd payload + rtabort!("drop of the panic payload panicked"); + }); + // Return error code for panicking programs. + 101 }); - panic::catch_unwind(cleanup).unwrap_or_else(handle_rt_panic); - // Guard against multiple threads calling `libc::exit` concurrently. - // See the documentation for `unique_thread_exit` for more information. - panic::catch_unwind(crate::sys::exit_guard::unique_thread_exit).unwrap_or_else(handle_rt_panic); - ret_code + let ret_code = ret_code as isize; + + cleanup(); + // Guard against multiple threads calling `libc::exit` concurrently. + // See the documentation for `unique_thread_exit` for more information. + crate::sys::exit_guard::unique_thread_exit(); + + ret_code + }) + .unwrap_or_else(handle_rt_panic) } #[cfg(not(any(test, doctest)))] @@ -191,11 +205,10 @@ fn lang_start<T: crate::process::Termination + 'static>( argv: *const *const u8, sigpipe: u8, ) -> isize { - let Ok(v) = lang_start_internal( + lang_start_internal( &move || crate::sys::backtrace::__rust_begin_short_backtrace(main).report().to_i32(), argc, argv, sigpipe, - ); - v + ) } diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index 47d9add72b5..7504a0f7ad7 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -222,14 +222,14 @@ pub(crate) fn runtime_services() -> Option<NonNull<r_efi::efi::RuntimeServices>> NonNull::new(runtime_services) } -pub(crate) struct DevicePath(NonNull<r_efi::protocols::device_path::Protocol>); +pub(crate) struct OwnedDevicePath(NonNull<r_efi::protocols::device_path::Protocol>); -impl DevicePath { +impl OwnedDevicePath { pub(crate) fn from_text(p: &OsStr) -> io::Result<Self> { fn inner( p: &OsStr, protocol: NonNull<r_efi::protocols::device_path_from_text::Protocol>, - ) -> io::Result<DevicePath> { + ) -> io::Result<OwnedDevicePath> { let path_vec = p.encode_wide().chain(Some(0)).collect::<Vec<u16>>(); if path_vec[..path_vec.len() - 1].contains(&0) { return Err(const_error!( @@ -242,7 +242,7 @@ impl DevicePath { unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) }; NonNull::new(path) - .map(DevicePath) + .map(OwnedDevicePath) .ok_or_else(|| const_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path")) } @@ -275,12 +275,12 @@ impl DevicePath { )) } - pub(crate) fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol { + pub(crate) const fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol { self.0.as_ptr() } } -impl Drop for DevicePath { +impl Drop for OwnedDevicePath { fn drop(&mut self) { if let Some(bt) = boot_services() { let bt: NonNull<r_efi::efi::BootServices> = bt.cast(); @@ -291,6 +291,15 @@ impl Drop for DevicePath { } } +impl crate::fmt::Debug for OwnedDevicePath { + fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result { + match device_path_to_text(self.0) { + Ok(p) => p.fmt(f), + Err(_) => f.debug_struct("OwnedDevicePath").finish_non_exhaustive(), + } + } +} + pub(crate) struct OwnedProtocol<T> { guid: r_efi::efi::Guid, handle: NonNull<crate::ffi::c_void>, diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs index 95707ebb7f0..1a0754134df 100644 --- a/library/std/src/sys/pal/uefi/process.rs +++ b/library/std/src/sys/pal/uefi/process.rs @@ -326,7 +326,7 @@ mod uefi_command_internal { impl Image { pub fn load_image(p: &OsStr) -> io::Result<Self> { - let path = helpers::DevicePath::from_text(p)?; + let path = helpers::OwnedDevicePath::from_text(p)?; let boot_services: NonNull<r_efi::efi::BootServices> = boot_services() .ok_or_else(|| const_error!(io::ErrorKind::NotFound, "Boot Services not found"))? .cast(); diff --git a/library/std/src/sys/path/sgx.rs b/library/std/src/sys/path/sgx.rs index c805c15e702..32c7752f605 100644 --- a/library/std/src/sys/path/sgx.rs +++ b/library/std/src/sys/path/sgx.rs @@ -23,3 +23,7 @@ pub const MAIN_SEP: char = '/'; pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> { unsupported() } + +pub(crate) fn is_absolute(path: &Path) -> bool { + path.has_root() && path.prefix().is_some() +} diff --git a/library/std/src/sys/path/unix.rs b/library/std/src/sys/path/unix.rs index 2a7c025c3c4..361e99964f1 100644 --- a/library/std/src/sys/path/unix.rs +++ b/library/std/src/sys/path/unix.rs @@ -60,3 +60,14 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> { Ok(normalized) } + +pub(crate) fn is_absolute(path: &Path) -> bool { + if cfg!(target_os = "redox") { + // FIXME: Allow Redox prefixes + path.has_root() || crate::path::has_redox_scheme(path.as_u8_slice()) + } else if cfg!(any(unix, target_os = "hermit", target_os = "wasi")) { + path.has_root() + } else { + path.has_root() && path.prefix().is_some() + } +} diff --git a/library/std/src/sys/path/unsupported_backslash.rs b/library/std/src/sys/path/unsupported_backslash.rs index 855f443678c..30b06c132c9 100644 --- a/library/std/src/sys/path/unsupported_backslash.rs +++ b/library/std/src/sys/path/unsupported_backslash.rs @@ -24,3 +24,7 @@ pub const MAIN_SEP: char = '\\'; pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> { unsupported() } + +pub(crate) fn is_absolute(path: &Path) -> bool { + path.has_root() && path.prefix().is_some() +} diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs index de042fa3f82..1c534721916 100644 --- a/library/std/src/sys/path/windows.rs +++ b/library/std/src/sys/path/windows.rs @@ -346,3 +346,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> { os2path, ) } + +pub(crate) fn is_absolute(path: &Path) -> bool { + path.has_root() && path.prefix().is_some() +} |
