pub fn spawn_socketed_process(
    exec_path: &str,
    argv: &[String],
) -> std::io::Result<SocketedProcess> {
    let (sock_controller, sock_sandbox) = std::os::unix::net::UnixStream::pair()?;

    let exec_path = std::ffi::CString::new(exec_path.as_bytes())?;

    let mut env = collect_env();
    let envp = make_null_terminated_string_array(&mut env);

    let mut argv = collect_argv(argv);
    let argvp = make_null_terminated_string_array(&mut argv);

    let pid = unsafe {
        // Unsafe section required due to raw call to libc posix_spawn function
        // as well as raw handling of raw file descriptor.
        // Safety is assured, cf. posix_spawn API.
        let mut pid = std::mem::MaybeUninit::<libc::pid_t>::uninit();
        let file_actions = std::ptr::null_mut::<libc::posix_spawn_file_actions_t>();
        let attr = std::ptr::null_mut::<libc::posix_spawnattr_t>();

        libc::posix_spawn_file_actions_init(file_actions);
        libc::posix_spawn_file_actions_adddup2(file_actions, sock_sandbox.as_raw_fd(), 3);
        libc::posix_spawnattr_init(attr);

        let spawn_result = libc::posix_spawn(
            pid.as_mut_ptr(),
            exec_path.as_ptr(),
            file_actions,
            attr,
            argvp.as_ptr(),
            envp.as_ptr(),
        );

        libc::posix_spawn_file_actions_destroy(file_actions);
        libc::posix_spawnattr_destroy(attr);

        if spawn_result != 0 {
            return Err(std::io::Error::last_os_error());
        }

        pid.assume_init()
    };

    Ok(SocketedProcess {
        pid,
        control_stream: sock_controller,
    })
}
/// Spawns a subprocess and passes an (anonymous) unix domain socket to
/// it for control. The socket will arrive as file descriptor 3 in the
/// target process, and the other end of the socket will be returned
/// in this call to control the process.
Spawns a subprocess and passes an (anonymous) unix domain socket to
it for control. The socket will arrive as file descriptor 3 in the
target process, and the other end of the socket will be returned
in this call to control the process.
Spawns a subprocess and passes an ( anonymous ) unix domain socket to it for control . The socket will arrive as file descriptor 3 in the target process and the other end of the socket will be returned in this call to control the process .
pub fn spawn_socketed_process(
    exec_path: &str,
    argv: &[String],
) -> std::io::Result<SocketedProcess> {
    let (sock_controller, sock_sandbox) = std::os::unix::net::UnixStream::pair()?;
    let exec_path = std::ffi::CString::new(exec_path.as_bytes())?;
    let mut env = collect_env();
    let envp = make_null_terminated_string_array(&mut env);
    let mut argv = collect_argv(argv);
    let argvp = make_null_terminated_string_array(&mut argv);
    let pid = unsafe {
        // Unsafe section required due to raw call to libc posix_spawn function
        // as well as raw handling of raw file descriptor.
        // Safety is assured, cf. posix_spawn API.
        let mut pid = std::mem::MaybeUninit::<libc::pid_t>::uninit();
        let file_actions = std::ptr::null_mut::<libc::posix_spawn_file_actions_t>();
        let attr = std::ptr::null_mut::<libc::posix_spawnattr_t>();
        libc::posix_spawn_file_actions_init(file_actions);
        libc::posix_spawn_file_actions_adddup2(file_actions, sock_sandbox.as_raw_fd(), 3);
        libc::posix_spawnattr_init(attr);
        let spawn_result = libc::posix_spawn(
            pid.as_mut_ptr(),
            exec_path.as_ptr(),
            file_actions,
            attr,
            argvp.as_ptr(),
            envp.as_ptr(),
        );
        libc::posix_spawn_file_actions_destroy(file_actions);
        libc::posix_spawnattr_destroy(attr);
        if spawn_result != 0 {
            return Err(std::io::Error::last_os_error());
        }
        pid.assume_init()
    };
    Ok(SocketedProcess {
        pid,
        control_stream: sock_controller,
    })
}
pub fn spawn_socketed_process ( exec_path : & str , argv : & [ String ] , ) -> std :: io :: Result < SocketedProcess > { let ( sock_controller , sock_sandbox ) = std :: os :: unix :: net :: UnixStream :: pair ( ) ? ; let exec_path = std :: ffi :: CString :: new ( exec_path . as_bytes ( ) ) ? ; let mut env = collect_env ( ) ; let envp = make_null_terminated_string_array ( & mut env ) ; let mut argv = collect_argv ( argv ) ; let argvp = make_null_terminated_string_array ( & mut argv ) ; let pid = unsafe { // Unsafe section required due to raw call to libc posix_spawn function // as well as raw handling of raw file descriptor. // Safety is assured, cf. posix_spawn API. let mut pid = std :: mem :: MaybeUninit :: < libc :: pid_t > :: uninit ( ) ; let file_actions = std :: ptr :: null_mut :: < libc :: posix_spawn_file_actions_t > ( ) ; let attr = std :: ptr :: null_mut :: < libc :: posix_spawnattr_t > ( ) ; libc :: posix_spawn_file_actions_init ( file_actions ) ; libc :: posix_spawn_file_actions_adddup2 ( file_actions , sock_sandbox . as_raw_fd ( ) , 3 ) ; libc :: posix_spawnattr_init ( attr ) ; let spawn_result = libc :: posix_spawn ( pid . as_mut_ptr ( ) , exec_path . as_ptr ( ) , file_actions , attr , argvp . as_ptr ( ) , envp . as_ptr ( ) , ) ; libc :: posix_spawn_file_actions_destroy ( file_actions ) ; libc :: posix_spawnattr_destroy ( attr ) ; if spawn_result != 0 { return Err ( std :: io :: Error :: last_os_error ( ) ) ; } pid . assume_init ( ) } ; Ok ( SocketedProcess { pid , control_stream : sock_controller , } ) }
Spawns a subprocess and passes an (anonymous) unix domain socket to
it for control.
Spawns a subprocess and passes an ( anonymous ) unix domain socket to it for control .
exec_path
&str
argv
&[String]
exec_path
&str
argv
&[String]