#[cfg(target_os = "vxworks")]
use libc::RTP_ID as pid_t;
#[cfg(not(target_os = "vxworks"))]
use libc::{c_int, pid_t};
#[cfg(not(any(
    target_os = "vxworks",
    target_os = "l4re",
    target_os = "tvos",
    target_os = "watchos",
)))]
use libc::{gid_t, uid_t};

use super::common::*;
use crate::io::{self, Error, ErrorKind};
use crate::num::NonZero;
use crate::sys::cvt;
#[cfg(target_os = "linux")]
use crate::sys::pal::linux::pidfd::PidFd;
use crate::{fmt, mem, sys};

cfg_select! {
    target_os = "nto" => {
        use crate::thread;
        use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t};
        use crate::time::Duration;
        use crate::sync::LazyLock;
        // Get smallest amount of time we can sleep.
        // Return a common value if it cannot be determined.
        fn get_clock_resolution() -> Duration {
            static MIN_DELAY: LazyLock<Duration, fn() -> Duration> = LazyLock::new(|| {
                let mut mindelay = libc::timespec { tv_sec: 0, tv_nsec: 0 };
                if unsafe { libc::clock_getres(libc::CLOCK_MONOTONIC, &mut mindelay) } == 0
                {
                    Duration::from_nanos(mindelay.tv_nsec as u64)
                } else {
                    Duration::from_millis(1)
                }
            });
            *MIN_DELAY
        }
        // Arbitrary minimum sleep duration for retrying fork/spawn
        const MIN_FORKSPAWN_SLEEP: Duration = Duration::from_nanos(1);
        // Maximum duration of sleeping before giving up and returning an error
        const MAX_FORKSPAWN_SLEEP: Duration = Duration::from_millis(1000);
    }
    _ => {}
}

////////////////////////////////////////////////////////////////////////////////
// Command
////////////////////////////////////////////////////////////////////////////////

impl Command {
    pub fn spawn(
        &mut self,
        default: Stdio,
        needs_stdin: bool,
    ) -> io::Result<(Process, StdioPipes)> {
        const CLOEXEC_MSG_FOOTER: [u8; 4] = *b"NOEX";

        let envp = self.capture_env();

        if self.saw_nul() {
            return Err(io::const_error!(
                ErrorKind::InvalidInput,
                "nul byte found in provided data",
            ));
        }

        let (ours, theirs) = self.setup_io(default, needs_stdin)?;

        if let Some(ret) = self.posix_spawn(&theirs, envp.as_ref())? {
            return Ok((ret, ours));
        }

        #[cfg(target_os = "linux")]
        let (input, output) = sys::net::Socket::new_pair(libc::AF_UNIX, libc::SOCK_SEQPACKET)?;

        #[cfg(not(target_os = "linux"))]
        let (input, output) = sys::pipe::anon_pipe()?;

        // Whatever happens after the fork is almost for sure going to touch or
        // look at the environment in one way or another (PATH in `execvp` or
        // accessing the `environ` pointer ourselves). Make sure no other thread
        // is accessing the environment when we do the fork itself.
        //
        // Note that as soon as we're done with the fork there's no need to hold
        // a lock any more because the parent won't do anything and the child is
        // in its own process. Thus the parent drops the lock guard immediately.
        // The child calls `mem::forget` to leak the lock, which is crucial because
        // releasing a lock is not async-signal-safe.
        let env_lock = sys::env::env_read_lock();
        let pid = unsafe { self.do_fork()? };

        if pid == 0 {
            crate::panic::always_abort();
            mem::forget(env_lock); // avoid non-async-signal-safe unlocking
            drop(input);
            #[cfg(target_os = "linux")]
            if self.get_create_pidfd() {
                self.send_pidfd(&output);
            }
            let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) };
            let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
            let errno = errno.to_be_bytes();
            let bytes = [
                errno[0],
                errno[1],
                errno[2],
                errno[3],
                CLOEXEC_MSG_FOOTER[0],
                CLOEXEC_MSG_FOOTER[1],
                CLOEXEC_MSG_FOOTER[2],
                CLOEXEC_MSG_FOOTER[3],
            ];
            // pipe I/O up to PIPE_BUF bytes should be atomic, and then
            // we want to be sure we *don't* run at_exit destructors as
            // we're being torn down regardless
            rtassert!(output.write(&bytes).is_ok());
            unsafe { libc::_exit(1) }
        }

        drop(env_lock);
        drop(output);

        #[cfg(target_os = "linux")]
        let pidfd = if self.get_create_pidfd() { self.recv_pidfd(&input) } else { -1 };

        #[cfg(not(target_os = "linux"))]
        let pidfd = -1;

        // Safety: We obtained the pidfd (on Linux) using SOCK_SEQPACKET, so it's valid.
        let mut p = unsafe { Process::new(pid, pidfd) };
        let mut bytes = [0; 8];

        // loop to handle EINTR
        loop {
            match input.read(&mut bytes) {
                Ok(0) => return Ok((p, ours)),
                Ok(8) => {
                    let (errno, footer) = bytes.split_at(4);
                    assert_eq!(
                        CLOEXEC_MSG_FOOTER, footer,
                        "Validation on the CLOEXEC pipe failed: {:?}",
                        bytes
                    );
                    let errno = i32::from_be_bytes(errno.try_into().unwrap());
                    assert!(p.wait().is_ok(), "wait() should either return Ok or panic");
                    return Err(Error::from_raw_os_error(errno));
                }
                Err(ref e) if e.is_interrupted() => {}
                Err(e) => {
                    assert!(p.wait().is_ok(), "wait() should either return Ok or panic");
                    panic!("the CLOEXEC pipe failed: {e:?}")
                }
                Ok(..) => {
                    // pipe I/O up to PIPE_BUF bytes should be atomic
                    // similarly SOCK_SEQPACKET messages should arrive whole
                    assert!(p.wait().is_ok(), "wait() should either return Ok or panic");
                    panic!("short read on the CLOEXEC pipe")
                }
            }
        }
    }

    // WatchOS and TVOS headers mark the `fork`/`exec*` functions with
    // `__WATCHOS_PROHIBITED __TVOS_PROHIBITED`, and indicate that the
    // `posix_spawn*` functions should be used instead. It isn't entirely clear
    // what `PROHIBITED` means here (e.g. if calls to these functions are
    // allowed to exist in dead code), but it sounds bad, so we go out of our
    // way to avoid that all-together.
    #[cfg(any(target_os = "tvos", target_os = "watchos"))]
    const ERR_APPLE_TV_WATCH_NO_FORK_EXEC: Error = io::const_error!(
        ErrorKind::Unsupported,
        "`fork`+`exec`-based process spawning is not supported on this target",
    );

    #[cfg(any(target_os = "tvos", target_os = "watchos"))]
    unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
        return Err(Self::ERR_APPLE_TV_WATCH_NO_FORK_EXEC);
    }

    // Attempts to fork the process. If successful, returns Ok((0, -1))
    // in the child, and Ok((child_pid, -1)) in the parent.
    #[cfg(not(any(target_os = "watchos", target_os = "tvos", target_os = "nto")))]
    unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
        cvt(libc::fork())
    }

    // On QNX Neutrino, fork can fail with EBADF in case "another thread might have opened
    // or closed a file descriptor while the fork() was occurring".
    // Documentation says "... or try calling fork() again". This is what we do here.
    // See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html
    #[cfg(target_os = "nto")]
    unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
        use crate::sys::os::errno;

        let mut delay = MIN_FORKSPAWN_SLEEP;

        loop {
            let r = libc::fork();
            if r == -1 as libc::pid_t && errno() as libc::c_int == libc::EBADF {
                if delay < get_clock_resolution() {
                    // We cannot sleep this short (it would be longer).
                    // Yield instead.
                    thread::yield_now();
                } else if delay < MAX_FORKSPAWN_SLEEP {
                    thread::sleep(delay);
                } else {
                    return Err(io::const_error!(
                        ErrorKind::WouldBlock,
                        "forking returned EBADF too often",
                    ));
                }
                delay *= 2;
                continue;
            } else {
                return cvt(r);
            }
        }
    }

    pub fn exec(&mut self, default: Stdio) -> io::Error {
        let envp = self.capture_env();

        if self.saw_nul() {
            return io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data");
        }

        match self.setup_io(default, true) {
            Ok((_, theirs)) => {
                unsafe {
                    // Similar to when forking, we want to ensure that access to
                    // the environment is synchronized, so make sure to grab the
                    // environment lock before we try to exec.
                    let _lock = sys::env::env_read_lock();

                    let Err(e) = self.do_exec(theirs, envp.as_ref());
                    e
                }
            }
            Err(e) => e,
        }
    }

    // And at this point we've reached a special time in the life of the
    // child. The child must now be considered hamstrung and unable to
    // do anything other than syscalls really. Consider the following
    // scenario:
    //
    //      1. Thread A of process 1 grabs the malloc() mutex
    //      2. Thread B of process 1 forks(), creating thread C
    //      3. Thread C of process 2 then attempts to malloc()
    //      4. The memory of process 2 is the same as the memory of
    //         process 1, so the mutex is locked.
    //
    // This situation looks a lot like deadlock, right? It turns out
    // that this is what pthread_atfork() takes care of, which is
    // presumably implemented across platforms. The first thing that
    // threads to *before* forking is to do things like grab the malloc
    // mutex, and then after the fork they unlock it.
    //
    // Despite this information, libnative's spawn has been witnessed to
    // deadlock on both macOS and FreeBSD. I'm not entirely sure why, but
    // all collected backtraces point at malloc/free traffic in the
    // child spawned process.
    //
    // For this reason, the block of code below should contain 0
    // invocations of either malloc of free (or their related friends).
    //
    // As an example of not having malloc/free traffic, we don't close
    // this file descriptor by dropping the FileDesc (which contains an
    // allocation). Instead we just close it manually. This will never
    // have the drop glue anyway because this code never returns (the
    // child will either exec() or invoke libc::exit)
    #[cfg(not(any(target_os = "tvos", target_os = "watchos")))]
    unsafe fn do_exec(
        &mut self,
        stdio: ChildPipes,
        maybe_envp: Option<&CStringArray>,
    ) -> Result<!, io::Error> {
        use crate::sys::{self, cvt_r};

        if let Some(fd) = stdio.stdin.fd() {
            cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))?;
        }
        if let Some(fd) = stdio.stdout.fd() {
            cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))?;
        }
        if let Some(fd) = stdio.stderr.fd() {
            cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?;
        }

        #[cfg(not(target_os = "l4re"))]
        {
            if let Some(_g) = self.get_groups() {
                //FIXME: Redox kernel does not support setgroups yet
                #[cfg(not(target_os = "redox"))]
                cvt(libc::setgroups(_g.len().try_into().unwrap(), _g.as_ptr()))?;
            }
            if let Some(u) = self.get_gid() {
                cvt(libc::setgid(u as gid_t))?;
            }
            if let Some(u) = self.get_uid() {
                // When dropping privileges from root, the `setgroups` call
                // will remove any extraneous groups. We only drop groups
                // if we have CAP_SETGID and we weren't given an explicit
                // set of groups. If we don't call this, then even though our
                // uid has dropped, we may still have groups that enable us to
                // do super-user things.
                //FIXME: Redox kernel does not support setgroups yet
                #[cfg(not(target_os = "redox"))]
                if self.get_groups().is_none() {
                    let res = cvt(libc::setgroups(0, crate::ptr::null()));
                    if let Err(e) = res {
                        // Here we ignore the case of not having CAP_SETGID.
                        // An alternative would be to require CAP_SETGID (in
                        // addition to CAP_SETUID) for setting the UID.
                        if e.raw_os_error() != Some(libc::EPERM) {
                            return Err(e.into());
                        }
                    }
                }
                cvt(libc::setuid(u as uid_t))?;
            }
        }
        if let Some(chroot) = self.get_chroot() {
            #[cfg(not(target_os = "fuchsia"))]
            cvt(libc::chroot(chroot.as_ptr()))?;
            #[cfg(target_os = "fuchsia")]
            return Err(io::const_error!(
                io::ErrorKind::Unsupported,
                "chroot not supported by fuchsia"
            ));
        }
        if let Some(cwd) = self.get_cwd() {
            cvt(libc::chdir(cwd.as_ptr()))?;
        }

        if let Some(pgroup) = self.get_pgroup() {
            cvt(libc::setpgid(0, pgroup))?;
        }

        if self.get_setsid() {
            cvt(libc::setsid())?;
        }

        // emscripten has no signal support.
        #[cfg(not(target_os = "emscripten"))]
        {
            // Inherit the signal mask from the parent rather than resetting it (i.e. do not call
            // pthread_sigmask).

            // If -Zon-broken-pipe is used, don't reset SIGPIPE to SIG_DFL.
            // If -Zon-broken-pipe is not used, reset SIGPIPE to SIG_DFL for backward compatibility.
            //
            // -Zon-broken-pipe is an opportunity to change the default here.
            if !crate::sys::pal::on_broken_pipe_flag_used() {
                #[cfg(target_os = "android")] // see issue #88585
                {
                    let mut action: libc::sigaction = mem::zeroed();
                    action.sa_sigaction = libc::SIG_DFL;
                    cvt(libc::sigaction(libc::SIGPIPE, &action, crate::ptr::null_mut()))?;
                }
                #[cfg(not(target_os = "android"))]
                {
                    let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
                    if ret == libc::SIG_ERR {
                        return Err(io::Error::last_os_error());
                    }
                }
                #[cfg(target_os = "hurd")]
                {
                    let ret = sys::signal(libc::SIGLOST, libc::SIG_DFL);
                    if ret == libc::SIG_ERR {
                        return Err(io::Error::last_os_error());
                    }
                }
            }
        }

        for callback in self.get_closures().iter_mut() {
            callback()?;
        }

        // Although we're performing an exec here we may also return with an
        // error from this function (without actually exec'ing) in which case we
        // want to be sure to restore the global environment back to what it
        // once was, ensuring that our temporary override, when free'd, doesn't
        // corrupt our process's environment.
        let mut _reset = None;
        if let Some(envp) = maybe_envp {
            struct Reset(*const *const libc::c_char);

            impl Drop for Reset {
                fn drop(&mut self) {
                    unsafe {
                        *sys::env::environ() = self.0;
                    }
                }
            }

            _reset = Some(Reset(*sys::env::environ()));
            *sys::env::environ() = envp.as_ptr();
        }

        libc::execvp(self.get_program_cstr().as_ptr(), self.get_argv().as_ptr());
        Err(io::Error::last_os_error())
    }

    #[cfg(any(target_os = "tvos", target_os = "watchos"))]
    unsafe fn do_exec(
        &mut self,
        _stdio: ChildPipes,
        _maybe_envp: Option<&CStringArray>,
    ) -> Result<!, io::Error> {
        return Err(Self::ERR_APPLE_TV_WATCH_NO_FORK_EXEC);
    }

    #[cfg(not(any(
        target_os = "freebsd",
        target_os = "illumos",
        all(target_os = "linux", target_env = "gnu"),
        all(target_os = "linux", target_env = "musl"),
        target_os = "nto",
        target_vendor = "apple",
        target_os = "cygwin",
    )))]
    fn posix_spawn(
        &mut self,
        _: &ChildPipes,
        _: Option<&CStringArray>,
    ) -> io::Result<Option<Process>> {
        Ok(None)
    }

    // Only support platforms for which posix_spawn() can return ENOENT
    // directly.
    #[cfg(any(
        target_os = "freebsd",
        target_os = "illumos",
        all(target_os = "linux", target_env = "gnu"),
        all(target_os = "linux", target_env = "musl"),
        target_os = "nto",
        target_vendor = "apple",
        target_os = "cygwin",
    ))]
    fn posix_spawn(
        &mut self,
        stdio: &ChildPipes,
        envp: Option<&CStringArray>,
    ) -> io::Result<Option<Process>> {
        #[cfg(target_os = "linux")]
        use core::sync::atomic::{Atomic, AtomicU8, Ordering};

        use crate::mem::MaybeUninit;
        use crate::sys::{self, cvt_nz, on_broken_pipe_flag_used};

        if self.get_gid().is_some()
            || self.get_uid().is_some()
            || (self.env_saw_path() && !self.program_is_path())
            || !self.get_closures().is_empty()
            || self.get_groups().is_some()
            || self.get_chroot().is_some()
        {
            return Ok(None);
        }

        cfg_select! {
            target_os = "linux" => {
                use crate::sys::weak::weak;

                weak!(
                    fn pidfd_spawnp(
                        pidfd: *mut libc::c_int,
                        path: *const libc::c_char,
                        file_actions: *const libc::posix_spawn_file_actions_t,
                        attrp: *const libc::posix_spawnattr_t,
                        argv: *const *mut libc::c_char,
                        envp: *const *mut libc::c_char,
                    ) -> libc::c_int;
                );

                weak!(
                    fn pidfd_getpid(pidfd: libc::c_int) -> libc::c_int;
                );

                static PIDFD_SUPPORTED: Atomic<u8> = AtomicU8::new(0);
                const UNKNOWN: u8 = 0;
                const SPAWN: u8 = 1;
                // Obtaining a pidfd via the fork+exec path might work
                const FORK_EXEC: u8 = 2;
                // Neither pidfd_spawn nor fork/exec will get us a pidfd.
                // Instead we'll just posix_spawn if the other preconditions are met.
                const NO: u8 = 3;

                if self.get_create_pidfd() {
                    let mut support = PIDFD_SUPPORTED.load(Ordering::Relaxed);
                    if support == FORK_EXEC {
                        return Ok(None);
                    }
                    if support == UNKNOWN {
                        support = NO;
                        let our_pid = crate::process::id();
                        let pidfd = cvt(unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) } as c_int);
                        match pidfd {
                            Ok(pidfd) => {
                                support = FORK_EXEC;
                                if let Some(Ok(pid)) = pidfd_getpid.get().map(|f| cvt(unsafe { f(pidfd) } as i32)) {
                                    if pidfd_spawnp.get().is_some() && pid as u32 == our_pid {
                                        support = SPAWN
                                    }
                                }
                                unsafe { libc::close(pidfd) };
                            }
                            Err(e) if e.raw_os_error() == Some(libc::EMFILE) => {
                                // We're temporarily(?) out of file descriptors.  In this case obtaining a pidfd would also fail
                                // Don't update the support flag so we can probe again later.
                                return Err(e)
                            }
                            _ => {}
                        }
                        PIDFD_SUPPORTED.store(support, Ordering::Relaxed);
                        if support == FORK_EXEC {
                            return Ok(None);
                        }
                    }
                    core::assert_matches::debug_assert_matches!(support, SPAWN | NO);
                }
            }
            _ => {
                if self.get_create_pidfd() {
                    unreachable!("only implemented on linux")
                }
            }
        }

        // Only glibc 2.24+ posix_spawn() supports returning ENOENT directly.
        #[cfg(all(target_os = "linux", target_env = "gnu"))]
        {
            if let Some(version) = sys::os::glibc_version() {
                if version < (2, 24) {
                    return Ok(None);
                }
            } else {
                return Ok(None);
            }
        }

        // On QNX Neutrino, posix_spawnp can fail with EBADF in case "another thread might have opened
        // or closed a file descriptor while the posix_spawn() was occurring".
        // Documentation says "... or try calling posix_spawn() again". This is what we do here.
        // See also http://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/p/posix_spawn.html
        #[cfg(target_os = "nto")]
        unsafe fn retrying_libc_posix_spawnp(
            pid: *mut pid_t,
            file: *const c_char,
            file_actions: *const posix_spawn_file_actions_t,
            attrp: *const posix_spawnattr_t,
            argv: *const *mut c_char,
            envp: *const *mut c_char,
        ) -> io::Result<i32> {
            let mut delay = MIN_FORKSPAWN_SLEEP;
            loop {
                match libc::posix_spawnp(pid, file, file_actions, attrp, argv, envp) {
                    libc::EBADF => {
                        if delay < get_clock_resolution() {
                            // We cannot sleep this short (it would be longer).
                            // Yield instead.
                            thread::yield_now();
                        } else if delay < MAX_FORKSPAWN_SLEEP {
                            thread::sleep(delay);
                        } else {
                            return Err(io::const_error!(
                                ErrorKind::WouldBlock,
                                "posix_spawnp returned EBADF too often",
                            ));
                        }
                        delay *= 2;
                        continue;
                    }
                    r => {
                        return Ok(r);
                    }
                }
            }
        }

        type PosixSpawnAddChdirFn = unsafe extern "C" fn(
            *mut libc::posix_spawn_file_actions_t,
            *const libc::c_char,
        ) -> libc::c_int;

        /// Get the function pointer for adding a chdir action to a
        /// `posix_spawn_file_actions_t`, if available, assuming a dynamic libc.
        ///
        /// Some platforms can set a new working directory for a spawned process in the
        /// `posix_spawn` path. This function looks up the function pointer for adding
        /// such an action to a `posix_spawn_file_actions_t` struct.
        #[cfg(not(any(all(target_os = "linux", target_env = "musl"), target_os = "cygwin")))]
        fn get_posix_spawn_addchdir() -> Option<PosixSpawnAddChdirFn> {
            use crate::sys::weak::weak;

            // POSIX.1-2024 standardizes this function:
            // https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addchdir.html.
            // The _np version is more widely available, though, so try that first.

            weak!(
                fn posix_spawn_file_actions_addchdir_np(
                    file_actions: *mut libc::posix_spawn_file_actions_t,
                    path: *const libc::c_char,
                ) -> libc::c_int;
            );

            weak!(
                fn posix_spawn_file_actions_addchdir(
                    file_actions: *mut libc::posix_spawn_file_actions_t,
                    path: *const libc::c_char,
                ) -> libc::c_int;
            );

            posix_spawn_file_actions_addchdir_np
                .get()
                .or_else(|| posix_spawn_file_actions_addchdir.get())
        }

        /// Get the function pointer for adding a chdir action to a
        /// `posix_spawn_file_actions_t`, if available, on platforms where the function
        /// is known to exist.
        ///
        /// Weak symbol lookup doesn't work with statically linked libcs, so in cases
        /// where static linking is possible we need to either check for the presence
        /// of the symbol at compile time or know about it upfront.
        ///
        /// Cygwin doesn't support weak symbol, so just link it.
        #[cfg(any(all(target_os = "linux", target_env = "musl"), target_os = "cygwin"))]
        fn get_posix_spawn_addchdir() -> Option<PosixSpawnAddChdirFn> {
            // Our minimum required musl supports this function, so we can just use it.
            Some(libc::posix_spawn_file_actions_addchdir_np)
        }

        let addchdir = match self.get_cwd() {
            Some(cwd) => {
                if cfg!(target_vendor = "apple") {
                    // There is a bug in macOS where a relative executable
                    // path like "../myprogram" will cause `posix_spawn` to
                    // successfully launch the program, but erroneously return
                    // ENOENT when used with posix_spawn_file_actions_addchdir_np
                    // which was introduced in macOS 10.15.
                    if self.get_program_kind() == ProgramKind::Relative {
                        return Ok(None);
                    }
                }
                // Check for the availability of the posix_spawn addchdir
                // function now. If it isn't available, bail and use the
                // fork/exec path.
                match get_posix_spawn_addchdir() {
                    Some(f) => Some((f, cwd)),
                    None => return Ok(None),
                }
            }
            None => None,
        };

        let pgroup = self.get_pgroup();

        struct PosixSpawnFileActions<'a>(&'a mut MaybeUninit<libc::posix_spawn_file_actions_t>);

        impl Drop for PosixSpawnFileActions<'_> {
            fn drop(&mut self) {
                unsafe {
                    libc::posix_spawn_file_actions_destroy(self.0.as_mut_ptr());
                }
            }
        }

        struct PosixSpawnattr<'a>(&'a mut MaybeUninit<libc::posix_spawnattr_t>);

        impl Drop for PosixSpawnattr<'_> {
            fn drop(&mut self) {
                unsafe {
                    libc::posix_spawnattr_destroy(self.0.as_mut_ptr());
                }
            }
        }

        unsafe {
            let mut attrs = MaybeUninit::uninit();
            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);

            if let Some(fd) = stdio.stdin.fd() {
                cvt_nz(libc::posix_spawn_file_actions_adddup2(
                    file_actions.0.as_mut_ptr(),
                    fd,
                    libc::STDIN_FILENO,
                ))?;
            }
            if let Some(fd) = stdio.stdout.fd() {
                cvt_nz(libc::posix_spawn_file_actions_adddup2(
                    file_actions.0.as_mut_ptr(),
                    fd,
                    libc::STDOUT_FILENO,
                ))?;
            }
            if let Some(fd) = stdio.stderr.fd() {
                cvt_nz(libc::posix_spawn_file_actions_adddup2(
                    file_actions.0.as_mut_ptr(),
                    fd,
                    libc::STDERR_FILENO,
                ))?;
            }
            if let Some((f, cwd)) = addchdir {
                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))?;
            }

            // Inherit the signal mask from this process rather than resetting it (i.e. do not call
            // posix_spawnattr_setsigmask).

            // If -Zon-broken-pipe is used, don't reset SIGPIPE to SIG_DFL.
            // If -Zon-broken-pipe is not used, reset SIGPIPE to SIG_DFL for backward compatibility.
            //
            // -Zon-broken-pipe is an opportunity to change the default here.
            if !on_broken_pipe_flag_used() {
                let mut default_set = MaybeUninit::<libc::sigset_t>::uninit();
                cvt(sigemptyset(default_set.as_mut_ptr()))?;
                cvt(sigaddset(default_set.as_mut_ptr(), libc::SIGPIPE))?;
                #[cfg(target_os = "hurd")]
                {
                    cvt(sigaddset(default_set.as_mut_ptr(), libc::SIGLOST))?;
                }
                cvt_nz(libc::posix_spawnattr_setsigdefault(
                    attrs.0.as_mut_ptr(),
                    default_set.as_ptr(),
                ))?;
                flags |= libc::POSIX_SPAWN_SETSIGDEF;
            }

            if self.get_setsid() {
                cfg_select! {
                    all(target_os = "linux", target_env = "gnu") => {
                        flags |= libc::POSIX_SPAWN_SETSID;
                    }
                    _ => {
                        return Ok(None);
                    }
                }
            }

            cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?;

            // Make sure we synchronize access to the global `environ` resource
            let _env_lock = sys::env::env_read_lock();
            let envp = envp.map(|c| c.as_ptr()).unwrap_or_else(|| *sys::env::environ() as *const _);

            #[cfg(not(target_os = "nto"))]
            let spawn_fn = libc::posix_spawnp;
            #[cfg(target_os = "nto")]
            let spawn_fn = retrying_libc_posix_spawnp;

            #[cfg(target_os = "linux")]
            if self.get_create_pidfd() && PIDFD_SUPPORTED.load(Ordering::Relaxed) == SPAWN {
                let mut pidfd: libc::c_int = -1;
                let spawn_res = pidfd_spawnp.get().unwrap()(
                    &mut pidfd,
                    self.get_program_cstr().as_ptr(),
                    file_actions.0.as_ptr(),
                    attrs.0.as_ptr(),
                    self.get_argv().as_ptr() as *const _,
                    envp as *const _,
                );

                let spawn_res = cvt_nz(spawn_res);
                if let Err(ref e) = spawn_res
                    && e.raw_os_error() == Some(libc::ENOSYS)
                {
                    PIDFD_SUPPORTED.store(FORK_EXEC, Ordering::Relaxed);
                    return Ok(None);
                }
                spawn_res?;

                let pid = match cvt(pidfd_getpid.get().unwrap()(pidfd)) {
                    Ok(pid) => pid,
                    Err(e) => {
                        // The child has been spawned and we are holding its pidfd.
                        // But we cannot obtain its pid even though pidfd_getpid support was verified earlier.
                        // This might happen if libc can't open procfs because the file descriptor limit has been reached.
                        libc::close(pidfd);
                        return Err(Error::new(
                            e.kind(),
                            "pidfd_spawnp succeeded but the child's PID could not be obtained",
                        ));
                    }
                };

                return Ok(Some(Process::new(pid, pidfd)));
            }

            // Safety: -1 indicates we don't have a pidfd.
            let mut p = Process::new(0, -1);

            let spawn_res = spawn_fn(
                &mut p.pid,
                self.get_program_cstr().as_ptr(),
                file_actions.0.as_ptr(),
                attrs.0.as_ptr(),
                self.get_argv().as_ptr() as *const _,
                envp as *const _,
            );

            #[cfg(target_os = "nto")]
            let spawn_res = spawn_res?;

            cvt_nz(spawn_res)?;
            Ok(Some(p))
        }
    }

    #[cfg(target_os = "linux")]
    fn send_pidfd(&self, sock: &crate::sys::net::Socket) {
        use libc::{CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_SPACE, SCM_RIGHTS, SOL_SOCKET};

        use crate::io::IoSlice;
        use crate::os::fd::RawFd;
        use crate::sys::cvt_r;

        unsafe {
            let child_pid = libc::getpid();
            // pidfd_open sets CLOEXEC by default
            let pidfd = libc::syscall(libc::SYS_pidfd_open, child_pid, 0);

            let fds: [c_int; 1] = [pidfd as RawFd];

            const SCM_MSG_LEN: usize = size_of::<[c_int; 1]>();

            #[repr(C)]
            union Cmsg {
                buf: [u8; unsafe { CMSG_SPACE(SCM_MSG_LEN as u32) as usize }],
                _align: libc::cmsghdr,
            }

            let mut cmsg: Cmsg = mem::zeroed();

            // 0-length message to send through the socket so we can pass along the fd
            let mut iov = [IoSlice::new(b"")];
            let mut msg: libc::msghdr = mem::zeroed();

            msg.msg_iov = (&raw mut iov) as *mut _;
            msg.msg_iovlen = 1;

            // only attach cmsg if we successfully acquired the pidfd
            if pidfd >= 0 {
                msg.msg_controllen = size_of_val(&cmsg.buf) as _;
                msg.msg_control = (&raw mut cmsg.buf) as *mut _;

                let hdr = CMSG_FIRSTHDR((&raw mut msg) as *mut _);
                (*hdr).cmsg_level = SOL_SOCKET;
                (*hdr).cmsg_type = SCM_RIGHTS;
                (*hdr).cmsg_len = CMSG_LEN(SCM_MSG_LEN as _) as _;
                let data = CMSG_DATA(hdr);
                crate::ptr::copy_nonoverlapping(
                    fds.as_ptr().cast::<u8>(),
                    data as *mut _,
                    SCM_MSG_LEN,
                );
            }

            // we send the 0-length message even if we failed to acquire the pidfd
            // so we get a consistent SEQPACKET order
            match cvt_r(|| libc::sendmsg(sock.as_raw(), &msg, 0)) {
                Ok(0) => {}
                other => rtabort!("failed to communicate with parent process. {:?}", other),
            }
        }
    }

    #[cfg(target_os = "linux")]
    fn recv_pidfd(&self, sock: &crate::sys::net::Socket) -> pid_t {
        use libc::{CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_SPACE, SCM_RIGHTS, SOL_SOCKET};

        use crate::io::IoSliceMut;
        use crate::sys::cvt_r;

        unsafe {
            const SCM_MSG_LEN: usize = size_of::<[c_int; 1]>();

            #[repr(C)]
            union Cmsg {
                _buf: [u8; unsafe { CMSG_SPACE(SCM_MSG_LEN as u32) as usize }],
                _align: libc::cmsghdr,
            }
            let mut cmsg: Cmsg = mem::zeroed();
            // 0-length read to get the fd
            let mut iov = [IoSliceMut::new(&mut [])];

            let mut msg: libc::msghdr = mem::zeroed();

            msg.msg_iov = (&raw mut iov) as *mut _;
            msg.msg_iovlen = 1;
            msg.msg_controllen = size_of::<Cmsg>() as _;
            msg.msg_control = (&raw mut cmsg) as *mut _;

            match cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, libc::MSG_CMSG_CLOEXEC)) {
                Err(_) => return -1,
                Ok(_) => {}
            }

            let hdr = CMSG_FIRSTHDR((&raw mut msg) as *mut _);
            if hdr.is_null()
                || (*hdr).cmsg_level != SOL_SOCKET
                || (*hdr).cmsg_type != SCM_RIGHTS
                || (*hdr).cmsg_len != CMSG_LEN(SCM_MSG_LEN as _) as _
            {
                return -1;
            }
            let data = CMSG_DATA(hdr);

            let mut fds = [-1 as c_int];

            crate::ptr::copy_nonoverlapping(
                data as *const _,
                fds.as_mut_ptr().cast::<u8>(),
                SCM_MSG_LEN,
            );

            fds[0]
        }
    }
}

////////////////////////////////////////////////////////////////////////////////
// Processes
////////////////////////////////////////////////////////////////////////////////

/// The unique ID of the process (this should never be negative).
pub struct Process {
    pid: pid_t,
    status: Option<ExitStatus>,
    // On Linux, stores the pidfd created for this child.
    // This is None if the user did not request pidfd creation,
    // or if the pidfd could not be created for some reason
    // (e.g. the `pidfd_open` syscall was not available).
    #[cfg(target_os = "linux")]
    pidfd: Option<PidFd>,
}

impl Process {
    #[cfg(target_os = "linux")]
    /// # Safety
    ///
    /// `pidfd` must either be -1 (representing no file descriptor) or a valid, exclusively owned file
    /// descriptor (See [I/O Safety]).
    ///
    /// [I/O Safety]: crate::io#io-safety
    unsafe fn new(pid: pid_t, pidfd: pid_t) -> Self {
        use crate::os::unix::io::FromRawFd;
        use crate::sys_common::FromInner;
        // Safety: If `pidfd` is nonnegative, we assume it's valid and otherwise unowned.
        let pidfd = (pidfd >= 0).then(|| PidFd::from_inner(sys::fd::FileDesc::from_raw_fd(pidfd)));
        Process { pid, status: None, pidfd }
    }

    #[cfg(not(target_os = "linux"))]
    unsafe fn new(pid: pid_t, _pidfd: pid_t) -> Self {
        Process { pid, status: None }
    }

    pub fn id(&self) -> u32 {
        self.pid as u32
    }

    pub fn kill(&self) -> io::Result<()> {
        self.send_signal(libc::SIGKILL)
    }

    pub(crate) fn send_signal(&self, signal: i32) -> io::Result<()> {
        // If we've already waited on this process then the pid can be recycled and
        // used for another process, and we probably shouldn't be sending signals to
        // random processes, so return Ok because the process has exited already.
        if self.status.is_some() {
            return Ok(());
        }
        #[cfg(target_os = "linux")]
        if let Some(pid_fd) = self.pidfd.as_ref() {
            // pidfd_send_signal predates pidfd_open. so if we were able to get an fd then sending signals will work too
            return pid_fd.send_signal(signal);
        }
        cvt(unsafe { libc::kill(self.pid, signal) }).map(drop)
    }

    pub fn wait(&mut self) -> io::Result<ExitStatus> {
        use crate::sys::cvt_r;
        if let Some(status) = self.status {
            return Ok(status);
        }
        #[cfg(target_os = "linux")]
        if let Some(pid_fd) = self.pidfd.as_ref() {
            let status = pid_fd.wait()?;
            self.status = Some(status);
            return Ok(status);
        }
        let mut status = 0 as c_int;
        cvt_r(|| unsafe { libc::waitpid(self.pid, &mut status, 0) })?;
        self.status = Some(ExitStatus::new(status));
        Ok(ExitStatus::new(status))
    }

    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
        if let Some(status) = self.status {
            return Ok(Some(status));
        }
        #[cfg(target_os = "linux")]
        if let Some(pid_fd) = self.pidfd.as_ref() {
            let status = pid_fd.try_wait()?;
            if let Some(status) = status {
                self.status = Some(status)
            }
            return Ok(status);
        }
        let mut status = 0 as c_int;
        let pid = cvt(unsafe { libc::waitpid(self.pid, &mut status, libc::WNOHANG) })?;
        if pid == 0 {
            Ok(None)
        } else {
            self.status = Some(ExitStatus::new(status));
            Ok(Some(ExitStatus::new(status)))
        }
    }
}

/// Unix exit statuses
//
// This is not actually an "exit status" in Unix terminology.  Rather, it is a "wait status".
// See the discussion in comments and doc comments for `std::process::ExitStatus`.
#[derive(PartialEq, Eq, Clone, Copy, Default)]
pub struct ExitStatus(c_int);

impl fmt::Debug for ExitStatus {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_tuple("unix_wait_status").field(&self.0).finish()
    }
}

impl ExitStatus {
    pub fn new(status: c_int) -> ExitStatus {
        ExitStatus(status)
    }

    #[cfg(target_os = "linux")]
    pub fn from_waitid_siginfo(siginfo: libc::siginfo_t) -> ExitStatus {
        let status = unsafe { siginfo.si_status() };

        match siginfo.si_code {
            libc::CLD_EXITED => ExitStatus((status & 0xff) << 8),
            libc::CLD_KILLED => ExitStatus(status),
            libc::CLD_DUMPED => ExitStatus(status | 0x80),
            libc::CLD_CONTINUED => ExitStatus(0xffff),
            libc::CLD_STOPPED | libc::CLD_TRAPPED => ExitStatus(((status & 0xff) << 8) | 0x7f),
            _ => unreachable!("waitid() should only return the above codes"),
        }
    }

    fn exited(&self) -> bool {
        libc::WIFEXITED(self.0)
    }

    pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
        // This assumes that WIFEXITED(status) && WEXITSTATUS==0 corresponds to status==0. This is
        // true on all actual versions of Unix, is widely assumed, and is specified in SuS
        // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
        // true for a platform pretending to be Unix, the tests (our doctests, and also
        // unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
        match NonZero::try_from(self.0) {
            /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)),
            /* was zero, couldn't convert */ Err(_) => Ok(()),
        }
    }

    pub fn code(&self) -> Option<i32> {
        self.exited().then(|| libc::WEXITSTATUS(self.0))
    }

    pub fn signal(&self) -> Option<i32> {
        libc::WIFSIGNALED(self.0).then(|| libc::WTERMSIG(self.0))
    }

    pub fn core_dumped(&self) -> bool {
        libc::WIFSIGNALED(self.0) && libc::WCOREDUMP(self.0)
    }

    pub fn stopped_signal(&self) -> Option<i32> {
        libc::WIFSTOPPED(self.0).then(|| libc::WSTOPSIG(self.0))
    }

    pub fn continued(&self) -> bool {
        libc::WIFCONTINUED(self.0)
    }

    pub fn into_raw(&self) -> c_int {
        self.0
    }
}

/// Converts a raw `c_int` to a type-safe `ExitStatus` by wrapping it without copying.
impl From<c_int> for ExitStatus {
    fn from(a: c_int) -> ExitStatus {
        ExitStatus(a)
    }
}

/// Converts a signal number to a readable, searchable name.
///
/// This string should be displayed right after the signal number.
/// If a signal is unrecognized, it returns the empty string, so that
/// you just get the number like "0". If it is recognized, you'll get
/// something like "9 (SIGKILL)".
fn signal_string(signal: i32) -> &'static str {
    match signal {
        libc::SIGHUP => " (SIGHUP)",
        libc::SIGINT => " (SIGINT)",
        libc::SIGQUIT => " (SIGQUIT)",
        libc::SIGILL => " (SIGILL)",
        libc::SIGTRAP => " (SIGTRAP)",
        libc::SIGABRT => " (SIGABRT)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGBUS => " (SIGBUS)",
        libc::SIGFPE => " (SIGFPE)",
        libc::SIGKILL => " (SIGKILL)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGUSR1 => " (SIGUSR1)",
        libc::SIGSEGV => " (SIGSEGV)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGUSR2 => " (SIGUSR2)",
        libc::SIGPIPE => " (SIGPIPE)",
        libc::SIGALRM => " (SIGALRM)",
        libc::SIGTERM => " (SIGTERM)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGCHLD => " (SIGCHLD)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGCONT => " (SIGCONT)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGSTOP => " (SIGSTOP)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGTSTP => " (SIGTSTP)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGTTIN => " (SIGTTIN)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGTTOU => " (SIGTTOU)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGURG => " (SIGURG)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGXCPU => " (SIGXCPU)",
        #[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
        libc::SIGXFSZ => " (SIGXFSZ)",
        #[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
        libc::SIGVTALRM => " (SIGVTALRM)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGPROF => " (SIGPROF)",
        #[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
        libc::SIGWINCH => " (SIGWINCH)",
        #[cfg(not(any(target_os = "haiku", target_os = "l4re")))]
        libc::SIGIO => " (SIGIO)",
        #[cfg(target_os = "haiku")]
        libc::SIGPOLL => " (SIGPOLL)",
        #[cfg(not(target_os = "l4re"))]
        libc::SIGSYS => " (SIGSYS)",
        // For information on Linux signals, run `man 7 signal`
        #[cfg(all(
            target_os = "linux",
            any(
                target_arch = "x86_64",
                target_arch = "x86",
                target_arch = "arm",
                target_arch = "aarch64"
            )
        ))]
        libc::SIGSTKFLT => " (SIGSTKFLT)",
        #[cfg(any(target_os = "linux", target_os = "nto", target_os = "cygwin"))]
        libc::SIGPWR => " (SIGPWR)",
        #[cfg(any(
            target_os = "freebsd",
            target_os = "netbsd",
            target_os = "openbsd",
            target_os = "dragonfly",
            target_os = "nto",
            target_vendor = "apple",
            target_os = "cygwin",
        ))]
        libc::SIGEMT => " (SIGEMT)",
        #[cfg(any(
            target_os = "freebsd",
            target_os = "netbsd",
            target_os = "openbsd",
            target_os = "dragonfly",
            target_vendor = "apple",
        ))]
        libc::SIGINFO => " (SIGINFO)",
        #[cfg(target_os = "hurd")]
        libc::SIGLOST => " (SIGLOST)",
        #[cfg(target_os = "freebsd")]
        libc::SIGTHR => " (SIGTHR)",
        #[cfg(target_os = "freebsd")]
        libc::SIGLIBRT => " (SIGLIBRT)",
        _ => "",
    }
}

impl fmt::Display for ExitStatus {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if let Some(code) = self.code() {
            write!(f, "exit status: {code}")
        } else if let Some(signal) = self.signal() {
            let signal_string = signal_string(signal);
            if self.core_dumped() {
                write!(f, "signal: {signal}{signal_string} (core dumped)")
            } else {
                write!(f, "signal: {signal}{signal_string}")
            }
        } else if let Some(signal) = self.stopped_signal() {
            let signal_string = signal_string(signal);
            write!(f, "stopped (not terminated) by signal: {signal}{signal_string}")
        } else if self.continued() {
            write!(f, "continued (WIFCONTINUED)")
        } else {
            write!(f, "unrecognised wait status: {} {:#x}", self.0, self.0)
        }
    }
}

#[derive(PartialEq, Eq, Clone, Copy)]
pub struct ExitStatusError(NonZero<c_int>);

impl Into<ExitStatus> for ExitStatusError {
    fn into(self) -> ExitStatus {
        ExitStatus(self.0.into())
    }
}

impl fmt::Debug for ExitStatusError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_tuple("unix_wait_status").field(&self.0).finish()
    }
}

impl ExitStatusError {
    pub fn code(self) -> Option<NonZero<i32>> {
        ExitStatus(self.0.into()).code().map(|st| st.try_into().unwrap())
    }
}

#[cfg(target_os = "linux")]
mod linux_child_ext {
    use crate::io::ErrorKind;
    use crate::os::linux::process as os;
    use crate::sys::pal::linux::pidfd as imp;
    use crate::sys_common::FromInner;
    use crate::{io, mem};

    #[unstable(feature = "linux_pidfd", issue = "82971")]
    impl crate::os::linux::process::ChildExt for crate::process::Child {
        fn pidfd(&self) -> io::Result<&os::PidFd> {
            self.handle
                .pidfd
                .as_ref()
                // SAFETY: The os type is a transparent wrapper, therefore we can transmute references
                .map(|fd| unsafe { mem::transmute::<&imp::PidFd, &os::PidFd>(fd) })
                .ok_or_else(|| io::const_error!(ErrorKind::Uncategorized, "no pidfd was created."))
        }

        fn into_pidfd(mut self) -> Result<os::PidFd, Self> {
            self.handle
                .pidfd
                .take()
                .map(|fd| <os::PidFd as FromInner<imp::PidFd>>::from_inner(fd))
                .ok_or_else(|| self)
        }
    }
}

#[cfg(test)]
mod tests;

// See [`unsupported_wait_status::compare_with_linux`];
#[cfg(all(test, target_os = "linux"))]
#[path = "unsupported/wait_status.rs"]
mod unsupported_wait_status;
