diff options
Diffstat (limited to 'library/std/src/sys/unix/process/process_common.rs')
-rw-r--r-- | library/std/src/sys/unix/process/process_common.rs | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index bca1b65a7..2834ee0ac 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -45,11 +45,31 @@ cfg_if::cfg_if! { } #[allow(dead_code)] pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int { - use crate::{slice, mem}; + use crate::{ + mem::{align_of, size_of}, + slice, + }; + use libc::{c_ulong, sigset_t}; + + // The implementations from bionic (android libc) type pun `sigset_t` as an + // array of `c_ulong`. This works, but lets add a smoke check to make sure + // that doesn't change. + const _: () = assert!( + align_of::<c_ulong>() == align_of::<sigset_t>() + && (size_of::<sigset_t>() % size_of::<c_ulong>()) == 0 + ); - let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>()); let bit = (signum - 1) as usize; - raw[bit / 8] |= 1 << (bit % 8); + if set.is_null() || bit >= (8 * size_of::<sigset_t>()) { + crate::sys::unix::os::set_errno(libc::EINVAL); + return -1; + } + let raw = slice::from_raw_parts_mut( + set as *mut c_ulong, + size_of::<sigset_t>() / size_of::<c_ulong>(), + ); + const LONG_BIT: usize = size_of::<c_ulong>() * 8; + raw[bit / LONG_BIT] |= 1 << (bit % LONG_BIT); return 0; } } else { @@ -72,6 +92,7 @@ pub struct Command { argv: Argv, env: CommandEnv, + program_kind: ProgramKind, cwd: Option<CString>, uid: Option<uid_t>, gid: Option<gid_t>, @@ -128,15 +149,40 @@ pub enum Stdio { Fd(FileDesc), } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum ProgramKind { + /// A program that would be looked up on the PATH (e.g. `ls`) + PathLookup, + /// A relative path (e.g. `my-dir/foo`, `../foo`, `./foo`) + Relative, + /// An absolute path. + Absolute, +} + +impl ProgramKind { + fn new(program: &OsStr) -> Self { + if program.bytes().starts_with(b"/") { + Self::Absolute + } else if program.bytes().contains(&b'/') { + // If the program has more than one component in it, it is a relative path. + Self::Relative + } else { + Self::PathLookup + } + } +} + impl Command { #[cfg(not(target_os = "linux"))] pub fn new(program: &OsStr) -> Command { let mut saw_nul = false; + let program_kind = ProgramKind::new(program.as_ref()); let program = os2c(program, &mut saw_nul); Command { argv: Argv(vec![program.as_ptr(), ptr::null()]), args: vec![program.clone()], program, + program_kind, env: Default::default(), cwd: None, uid: None, @@ -154,11 +200,13 @@ impl Command { #[cfg(target_os = "linux")] pub fn new(program: &OsStr) -> Command { let mut saw_nul = false; + let program_kind = ProgramKind::new(program.as_ref()); let program = os2c(program, &mut saw_nul); Command { argv: Argv(vec![program.as_ptr(), ptr::null()]), args: vec![program.clone()], program, + program_kind, env: Default::default(), cwd: None, uid: None, @@ -234,6 +282,11 @@ impl Command { OsStr::from_bytes(self.program.as_bytes()) } + #[allow(dead_code)] + pub fn get_program_kind(&self) -> ProgramKind { + self.program_kind + } + pub fn get_args(&self) -> CommandArgs<'_> { let mut iter = self.args.iter(); iter.next(); |