diff options
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/backtrace.rs | 6 | ||||
| -rw-r--r-- | library/std/src/process/tests.rs | 29 | ||||
| -rw-r--r-- | library/std/src/sync/once.rs | 7 | ||||
| -rw-r--r-- | library/std/src/sys/solid/fs.rs | 28 | ||||
| -rw-r--r-- | library/std/src/sys/windows/process.rs | 16 | ||||
| -rw-r--r-- | library/std/src/sys/windows/process/tests.rs | 4 |
6 files changed, 83 insertions, 7 deletions
diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs index 0b86b4f30b9..94e6070c0f7 100644 --- a/library/std/src/backtrace.rs +++ b/library/std/src/backtrace.rs @@ -99,7 +99,7 @@ use crate::cell::UnsafeCell; use crate::env; use crate::ffi::c_void; use crate::fmt; -use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; +use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed}; use crate::sync::Once; use crate::sys_common::backtrace::{lock, output_filename}; use crate::vec::Vec; @@ -256,7 +256,7 @@ impl Backtrace { // backtrace captures speedy, because otherwise reading environment // variables every time can be somewhat slow. static ENABLED: AtomicUsize = AtomicUsize::new(0); - match ENABLED.load(SeqCst) { + match ENABLED.load(Relaxed) { 0 => {} 1 => return false, _ => return true, @@ -268,7 +268,7 @@ impl Backtrace { Err(_) => false, }, }; - ENABLED.store(enabled as usize + 1, SeqCst); + ENABLED.store(enabled as usize + 1, Relaxed); enabled } diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs index 67b747e4107..e5cdc473706 100644 --- a/library/std/src/process/tests.rs +++ b/library/std/src/process/tests.rs @@ -4,6 +4,10 @@ use super::{Command, Output, Stdio}; use crate::io::ErrorKind; use crate::str; +fn known_command() -> Command { + if cfg!(windows) { Command::new("help") } else { Command::new("echo") } +} + #[cfg(target_os = "android")] fn shell_cmd() -> Command { Command::new("/system/bin/sh") @@ -305,7 +309,7 @@ fn test_interior_nul_in_progname_is_error() { #[test] fn test_interior_nul_in_arg_is_error() { - match Command::new("rustc").arg("has-some-\0\0s-inside").spawn() { + match known_command().arg("has-some-\0\0s-inside").spawn() { Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), Ok(_) => panic!(), } @@ -313,7 +317,7 @@ fn test_interior_nul_in_arg_is_error() { #[test] fn test_interior_nul_in_args_is_error() { - match Command::new("rustc").args(&["has-some-\0\0s-inside"]).spawn() { + match known_command().args(&["has-some-\0\0s-inside"]).spawn() { Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), Ok(_) => panic!(), } @@ -321,7 +325,7 @@ fn test_interior_nul_in_args_is_error() { #[test] fn test_interior_nul_in_current_dir_is_error() { - match Command::new("rustc").current_dir("has-some-\0\0s-inside").spawn() { + match known_command().current_dir("has-some-\0\0s-inside").spawn() { Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), Ok(_) => panic!(), } @@ -416,3 +420,22 @@ fn env_empty() { let p = Command::new("cmd").args(&["/C", "exit 0"]).env_clear().spawn(); assert!(p.is_ok()); } + +// See issue #91991 +#[test] +#[cfg(windows)] +fn run_bat_script() { + let tempdir = crate::sys_common::io::test::tmpdir(); + let script_path = tempdir.join("hello.cmd"); + + crate::fs::write(&script_path, "@echo Hello, %~1!").unwrap(); + let output = Command::new(&script_path) + .arg("fellow Rustaceans") + .stdout(crate::process::Stdio::piped()) + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "Hello, fellow Rustaceans!"); +} diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 1710c005393..f76d0759561 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -90,6 +90,7 @@ mod tests; use crate::cell::Cell; use crate::fmt; use crate::marker; +use crate::panic::{RefUnwindSafe, UnwindSafe}; use crate::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use crate::thread::{self, Thread}; @@ -123,6 +124,12 @@ unsafe impl Sync for Once {} #[stable(feature = "rust1", since = "1.0.0")] unsafe impl Send for Once {} +#[stable(feature = "sync_once_unwind_safe", since = "1.59.0")] +impl UnwindSafe for Once {} + +#[stable(feature = "sync_once_unwind_safe", since = "1.59.0")] +impl RefUnwindSafe for Once {} + /// State yielded to [`Once::call_once_force()`]’s closure parameter. The state /// can be used to query the poison status of the [`Once`]. #[stable(feature = "once_poison", since = "1.51.0")] diff --git a/library/std/src/sys/solid/fs.rs b/library/std/src/sys/solid/fs.rs index abc60b56fbb..8a0eeff0c4d 100644 --- a/library/std/src/sys/solid/fs.rs +++ b/library/std/src/sys/solid/fs.rs @@ -2,7 +2,7 @@ use super::{abi, error}; use crate::{ ffi::{CStr, CString, OsStr, OsString}, fmt, - io::{self, IoSlice, IoSliceMut, SeekFrom}, + io::{self, IoSlice, IoSliceMut, ReadBuf, SeekFrom}, mem::MaybeUninit, os::raw::{c_int, c_short}, os::solid::ffi::OsStrExt, @@ -339,6 +339,32 @@ impl File { } } + pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> { + unsafe { + let len = buf.remaining(); + let mut out_num_bytes = MaybeUninit::uninit(); + error::SolidError::err_if_negative(abi::SOLID_FS_Read( + self.fd.raw(), + buf.unfilled_mut().as_mut_ptr() as *mut u8, + len, + out_num_bytes.as_mut_ptr(), + )) + .map_err(|e| e.as_io_error())?; + + // Safety: `out_num_bytes` is filled by the successful call to + // `SOLID_FS_Read` + let num_bytes_read = out_num_bytes.assume_init(); + + // Safety: `num_bytes_read` bytes were written to the unfilled + // portion of the buffer + buf.assume_init(num_bytes_read); + + buf.add_filled(num_bytes_read); + + Ok(()) + } + } + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { crate::io::default_read_vectored(|buf| self.read(buf), bufs) } diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index 66b210ce1bf..e84dfbce4a7 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -704,6 +704,19 @@ fn make_command_line(prog: &OsStr, args: &[Arg], force_quotes: bool) -> io::Resu // Encode the command and arguments in a command line string such // that the spawned process may recover them using CommandLineToArgvW. let mut cmd: Vec<u16> = Vec::new(); + + // CreateFileW has special handling for .bat and .cmd files, which means we + // need to add an extra pair of quotes surrounding the whole command line + // so they are properly passed on to the script. + // See issue #91991. + let is_batch_file = Path::new(prog) + .extension() + .map(|ext| ext.eq_ignore_ascii_case("cmd") || ext.eq_ignore_ascii_case("bat")) + .unwrap_or(false); + if is_batch_file { + cmd.push(b'"' as u16); + } + // Always quote the program name so CreateProcess doesn't interpret args as // part of the name if the binary wasn't found first time. append_arg(&mut cmd, prog, Quote::Always)?; @@ -715,6 +728,9 @@ fn make_command_line(prog: &OsStr, args: &[Arg], force_quotes: bool) -> io::Resu }; append_arg(&mut cmd, arg, quote)?; } + if is_batch_file { + cmd.push(b'"' as u16); + } return Ok(cmd); fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr, quote: Quote) -> io::Result<()> { diff --git a/library/std/src/sys/windows/process/tests.rs b/library/std/src/sys/windows/process/tests.rs index 6c862edc237..6159a679c0e 100644 --- a/library/std/src/sys/windows/process/tests.rs +++ b/library/std/src/sys/windows/process/tests.rs @@ -160,6 +160,8 @@ fn windows_exe_resolver() { io::ErrorKind::InvalidInput ); + /* FIXME: fix and re-enable these tests before making changes to the resolver. + /* Some of the following tests may need to be changed if you are deliberately changing the behaviour of `resolve_exe`. @@ -179,4 +181,6 @@ fn windows_exe_resolver() { // The application's directory is also searched. let current_exe = env::current_exe().unwrap(); assert!(resolve_exe(current_exe.file_name().unwrap().as_ref(), None).is_ok()); + + */ } |
