From 27f6d2c7f6a608497f8737a6e3605df8c993ee22 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 5 Mar 2022 18:14:34 +0000 Subject: [PATCH 1/6] Relax tests for Windows dos device names Windows 11 no longer turn paths ending with dos device names into device paths. E.g. `C:\path\to\COM1.txt` used to get turned into `\\.\COM1`. Whereas now the path is left as is. --- library/std/src/path/tests.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index 8e51433094a69..09a900b5bc055 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1752,10 +1752,7 @@ fn test_windows_absolute() { unchanged!(r"\\?\path.\to/file.."); assert_eq!(absolute(r"C:\path..\to.\file.").unwrap(), Path::new(r"C:\path..\to\file")); - assert_eq!(absolute(r"C:\path\to\COM1").unwrap(), Path::new(r"\\.\COM1")); - assert_eq!(absolute(r"C:\path\to\COM1.txt").unwrap(), Path::new(r"\\.\COM1")); - assert_eq!(absolute(r"C:\path\to\COM1 .txt").unwrap(), Path::new(r"\\.\COM1")); - assert_eq!(absolute(r"C:\path\to\cOnOuT$").unwrap(), Path::new(r"\\.\cOnOuT$")); + assert_eq!(absolute(r"COM1").unwrap().as_os_str(), Path::new(r"\\.\COM1").as_os_str()); } #[bench] From 3009eec10da01b7dc052891369a16346604ed50b Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 5 Mar 2022 18:15:58 +0000 Subject: [PATCH 2/6] Use as_os_str to compare exact paths --- library/std/src/path/tests.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index 09a900b5bc055..3a393ea8380b3 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1731,11 +1731,11 @@ fn test_windows_absolute() { let relative = r"a\b"; let mut expected = crate::env::current_dir().unwrap(); expected.push(relative); - assert_eq!(absolute(relative).unwrap(), expected); + assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str()); macro_rules! unchanged( ($path:expr) => { - assert_eq!(absolute($path).unwrap(), Path::new($path)); + assert_eq!(absolute($path).unwrap().as_os_str(), Path::new($path).as_os_str()); } ); @@ -1751,7 +1751,10 @@ fn test_windows_absolute() { // Verbatim paths are always unchanged, no matter what. unchanged!(r"\\?\path.\to/file.."); - assert_eq!(absolute(r"C:\path..\to.\file.").unwrap(), Path::new(r"C:\path..\to\file")); + assert_eq!( + absolute(r"C:\path..\to.\file.").unwrap().as_os_str(), + Path::new(r"C:\path..\to\file").as_os_str() + ); assert_eq!(absolute(r"COM1").unwrap().as_os_str(), Path::new(r"\\.\COM1").as_os_str()); } From b628497b7cf8235a7f74fa037e86051fa78b5188 Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Thu, 3 Feb 2022 09:40:45 +0000 Subject: [PATCH 3/6] Add a `process_group` method to UNIX `CommandExt` --- library/std/src/os/unix/process.rs | 10 ++++ .../src/sys/unix/process/process_common.rs | 12 +++- .../sys/unix/process/process_common/tests.rs | 55 +++++++++++++++++++ .../std/src/sys/unix/process/process_unix.rs | 15 ++++- 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 855f900430c4a..d95bc9b15c9c4 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -149,6 +149,11 @@ pub trait CommandExt: Sealed { fn arg0(&mut self, arg: S) -> &mut process::Command where S: AsRef; + + /// Sets the process group ID of the child process. Translates to a `setpgid` call in the child + /// process. + #[unstable(feature = "process_set_process_group", issue = "93857")] + fn process_group(&mut self, pgroup: i32) -> &mut process::Command; } #[stable(feature = "rust1", since = "1.0.0")] @@ -201,6 +206,11 @@ impl CommandExt for process::Command { self.as_inner_mut().set_arg_0(arg.as_ref()); self } + + fn process_group(&mut self, pgroup: i32) -> &mut process::Command { + self.as_inner_mut().pgroup(pgroup); + self + } } /// Unix-specific extensions to [`process::ExitStatus`] and diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index 7ac2f9d8af75a..1adf7f82c8c29 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -18,7 +18,7 @@ use crate::sys_common::IntoInner; #[cfg(not(target_os = "fuchsia"))] use crate::sys::fs::OpenOptions; -use libc::{c_char, c_int, gid_t, uid_t, EXIT_FAILURE, EXIT_SUCCESS}; +use libc::{c_char, c_int, gid_t, pid_t, uid_t, EXIT_FAILURE, EXIT_SUCCESS}; cfg_if::cfg_if! { if #[cfg(target_os = "fuchsia")] { @@ -82,6 +82,7 @@ pub struct Command { stderr: Option, #[cfg(target_os = "linux")] create_pidfd: bool, + pgroup: Option, } // Create a new type for argv, so that we can make it `Send` and `Sync` @@ -145,6 +146,7 @@ impl Command { stdin: None, stdout: None, stderr: None, + pgroup: None, } } @@ -167,6 +169,7 @@ impl Command { stdout: None, stderr: None, create_pidfd: false, + pgroup: None, } } @@ -202,6 +205,9 @@ impl Command { pub fn groups(&mut self, groups: &[gid_t]) { self.groups = Some(Box::from(groups)); } + pub fn pgroup(&mut self, pgroup: pid_t) { + self.pgroup = Some(pgroup); + } #[cfg(target_os = "linux")] pub fn create_pidfd(&mut self, val: bool) { @@ -265,6 +271,10 @@ impl Command { pub fn get_groups(&self) -> Option<&[gid_t]> { self.groups.as_deref() } + #[allow(dead_code)] + pub fn get_pgroup(&self) -> Option { + self.pgroup + } pub fn get_closures(&mut self) -> &mut Vec io::Result<()> + Send + Sync>> { &mut self.closures diff --git a/library/std/src/sys/unix/process/process_common/tests.rs b/library/std/src/sys/unix/process/process_common/tests.rs index 10aa34e9443b7..9f1a645372f42 100644 --- a/library/std/src/sys/unix/process/process_common/tests.rs +++ b/library/std/src/sys/unix/process/process_common/tests.rs @@ -67,3 +67,58 @@ fn test_process_mask() { t!(cat.wait()); } } + +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_process_group_posix_spawn() { + unsafe { + // Spawn a cat subprocess that's just going to hang since there is no I/O. + let mut cmd = Command::new(OsStr::new("cat")); + cmd.pgroup(0); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + // Check that we can kill its process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_process_group_no_posix_spawn() { + unsafe { + // Same as above, create hang-y cat. This time, force using the non-posix_spawnp path. + let mut cmd = Command::new(OsStr::new("cat")); + cmd.pgroup(0); + cmd.pre_exec(Box::new(|| Ok(()))); // pre_exec forces fork + exec + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + // Check that we can kill its process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index bce35b380e677..86bb5b5d07b74 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -320,6 +320,10 @@ impl Command { cvt(libc::chdir(cwd.as_ptr()))?; } + if let Some(pgroup) = self.get_pgroup() { + cvt(libc::setpgid(0, pgroup))?; + } + // emscripten has no signal support. #[cfg(not(target_os = "emscripten"))] { @@ -459,6 +463,8 @@ impl Command { None => None, }; + let pgroup = self.get_pgroup(); + // Safety: -1 indicates we don't have a pidfd. let mut p = unsafe { Process::new(0, -1) }; @@ -487,6 +493,8 @@ impl Command { cvt_nz(libc::posix_spawnattr_init(attrs.as_mut_ptr()))?; let attrs = PosixSpawnattr(&mut attrs); + let mut flags = 0; + let mut file_actions = MaybeUninit::uninit(); cvt_nz(libc::posix_spawn_file_actions_init(file_actions.as_mut_ptr()))?; let file_actions = PosixSpawnFileActions(&mut file_actions); @@ -516,13 +524,18 @@ impl Command { cvt_nz(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?; } + if let Some(pgroup) = pgroup { + flags |= libc::POSIX_SPAWN_SETPGROUP; + cvt_nz(libc::posix_spawnattr_setpgroup(attrs.0.as_mut_ptr(), pgroup))?; + } + let mut set = MaybeUninit::::uninit(); cvt(sigemptyset(set.as_mut_ptr()))?; cvt_nz(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(), set.as_ptr()))?; cvt(sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?; cvt_nz(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(), set.as_ptr()))?; - let flags = libc::POSIX_SPAWN_SETSIGDEF | libc::POSIX_SPAWN_SETSIGMASK; + flags |= libc::POSIX_SPAWN_SETSIGDEF | libc::POSIX_SPAWN_SETSIGMASK; cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; // Make sure we synchronize access to the global `environ` resource From 05e9fcb704e91b38e31f6b209748fec975e1a0be Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 17 Mar 2022 21:22:35 -0600 Subject: [PATCH 4/6] Re-enable parallel debuginfo tests Debuginfo tests are serialized due to some older version of LLDB. However, that comment was last touched in 2014, so presumably these older versions are long since obsolete. Partially fixes bug #72719. --- src/tools/compiletest/src/main.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 3f2cd3ae232ba..503b624114a2a 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -487,11 +487,6 @@ fn configure_lldb(config: &Config) -> Option { return None; } - // Some older versions of LLDB seem to have problems with multiple - // instances running in parallel, so only run one test thread at a - // time. - env::set_var("RUST_TEST_THREADS", "1"); - Some(Config { debugger: Some(Debugger::Lldb), ..config.clone() }) } From a358ad2aff788bf21cf9c17662da7e962d75fc83 Mon Sep 17 00:00:00 2001 From: CAD97 Date: Tue, 15 Mar 2022 23:58:18 -0500 Subject: [PATCH 5/6] Make Weak::new const --- library/alloc/src/rc.rs | 5 +++-- library/alloc/src/sync.rs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 3065169e5e2cb..ea651c075d968 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2112,9 +2112,10 @@ impl Weak { /// assert!(empty.upgrade().is_none()); /// ``` #[stable(feature = "downgraded_weak", since = "1.10.0")] + #[rustc_const_unstable(feature = "const_weak_new", issue = "95091", reason = "recently added")] #[must_use] - pub fn new() -> Weak { - Weak { ptr: NonNull::new(usize::MAX as *mut RcBox).expect("MAX is not 0") } + pub const fn new() -> Weak { + Weak { ptr: unsafe { NonNull::new_unchecked(usize::MAX as *mut RcBox) } } } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 2140c3f168d1c..ba3187294e654 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1742,9 +1742,10 @@ impl Weak { /// assert!(empty.upgrade().is_none()); /// ``` #[stable(feature = "downgraded_weak", since = "1.10.0")] + #[rustc_const_unstable(feature = "const_weak_new", issue = "95091", reason = "recently added")] #[must_use] - pub fn new() -> Weak { - Weak { ptr: NonNull::new(usize::MAX as *mut ArcInner).expect("MAX is not 0") } + pub const fn new() -> Weak { + Weak { ptr: unsafe { NonNull::new_unchecked(usize::MAX as *mut ArcInner) } } } } From a12674a0523c4b5ca20c981be179f4216f325dbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20BRANSTETT?= Date: Sat, 19 Mar 2022 10:23:09 +0100 Subject: [PATCH 6/6] Extend --check-cfg tests to all predicate inside all/any --- src/test/ui/check-cfg/mix.rs | 22 ++++++++ src/test/ui/check-cfg/mix.stderr | 96 +++++++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 1 deletion(-) diff --git a/src/test/ui/check-cfg/mix.rs b/src/test/ui/check-cfg/mix.rs index 26c735c4a10bd..b51d356f61fdf 100644 --- a/src/test/ui/check-cfg/mix.rs +++ b/src/test/ui/check-cfg/mix.rs @@ -45,6 +45,28 @@ fn test_cfg_macro() { //~^ WARNING unexpected `cfg` condition name cfg!(any(feature = "bad", windows)); //~^ WARNING unexpected `cfg` condition value + cfg!(any(windows, xxx)); + //~^ WARNING unexpected `cfg` condition name + cfg!(all(unix, xxx)); + //~^ WARNING unexpected `cfg` condition name + cfg!(all(aa, bb)); + //~^ WARNING unexpected `cfg` condition name + //~| WARNING unexpected `cfg` condition name + cfg!(any(aa, bb)); + //~^ WARNING unexpected `cfg` condition name + //~| WARNING unexpected `cfg` condition name + cfg!(any(unix, feature = "zebra")); + //~^ WARNING unexpected `cfg` condition value + cfg!(any(xxx, feature = "zebra")); + //~^ WARNING unexpected `cfg` condition name + //~| WARNING unexpected `cfg` condition value + cfg!(any(xxx, unix, xxx)); + //~^ WARNING unexpected `cfg` condition name + //~| WARNING unexpected `cfg` condition name + cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); + //~^ WARNING unexpected `cfg` condition value + //~| WARNING unexpected `cfg` condition value + //~| WARNING unexpected `cfg` condition value } fn main() {} diff --git a/src/test/ui/check-cfg/mix.stderr b/src/test/ui/check-cfg/mix.stderr index b273be774224d..08a338da104d0 100644 --- a/src/test/ui/check-cfg/mix.stderr +++ b/src/test/ui/check-cfg/mix.stderr @@ -62,5 +62,99 @@ LL | cfg!(any(feature = "bad", windows)); | = note: expected values for `feature` are: bar, foo -warning: 9 warnings emitted +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:48:23 + | +LL | cfg!(any(windows, xxx)); + | ^^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:50:20 + | +LL | cfg!(all(unix, xxx)); + | ^^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:52:14 + | +LL | cfg!(all(aa, bb)); + | ^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:52:18 + | +LL | cfg!(all(aa, bb)); + | ^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:55:14 + | +LL | cfg!(any(aa, bb)); + | ^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:55:18 + | +LL | cfg!(any(aa, bb)); + | ^^ + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:58:20 + | +LL | cfg!(any(unix, feature = "zebra")); + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: bar, foo + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:60:14 + | +LL | cfg!(any(xxx, feature = "zebra")); + | ^^^ + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:60:19 + | +LL | cfg!(any(xxx, feature = "zebra")); + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: bar, foo + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:63:14 + | +LL | cfg!(any(xxx, unix, xxx)); + | ^^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:63:25 + | +LL | cfg!(any(xxx, unix, xxx)); + | ^^^ + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:66:14 + | +LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: bar, foo + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:66:33 + | +LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: bar, foo + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:66:52 + | +LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: bar, foo + +warning: 23 warnings emitted