/// Spawn a process in a new pty.
Spawn a process in a new pty.
Spawn a process in a new pty .
pub fn new(config: Config<crate::config::ui_config::UiConfig>, size: SizeInfo) -> Result<Pty, ()>
    {
        let new_winsize = winsize {
            ws_row: size.screen_lines() as u16,
            ws_col: size.columns() as u16,
            ws_xpixel: size.width() as libc::c_ushort,
            ws_ypixel: size.height() as libc::c_ushort,
        };
        let pty = openpty(&new_winsize, None).unwrap();
        if let Ok(mut termios) = termios::tcgetattr(pty.master) {
            // Set character encoding to UTF-8.
            termios.input_flags.set(InputFlags::IUTF8, true);
            let _ = termios::tcsetattr(pty.master, SetArg::TCSANOW, &termios);
        }
        let mut buf = [0; 1024];
        let pw = get_pw_entry(&mut buf);
        let slave = pty.slave;
        let master = pty.master;
        let (command, args) = match config.shell {
            Some(program) => {
                match program {
                    Program::Just(str) => {
                        (str, Vec::<String>::new())
                    }, 
                    Program::WithArgs { program, args } => {
                        (program, args)
                    }
                }
            }, 
            None => {
                (crate::tab_manager::DEFAULT_SHELL.to_string(), Vec::<String>::new())
            }
        };
        unsafe {
            Command::new(&command)
                .args(args.to_vec())
                .stdin(Stdio::from_raw_fd(pty.slave))
                .stdout(Stdio::from_raw_fd(pty.slave))
                .stderr(Stdio::from_raw_fd(pty.slave))
                .env("LOGNAME", pw.name)
                .env("USER", pw.name)
                .env("HOME", pw.dir)
                .env("SHELL", crate::tab_manager::DEFAULT_SHELL)
                .pre_exec(move || {
                    let pid = setsid().map_err(|e| format!("Error occured with setsid: {}", e)).unwrap();
                    if pid.as_raw() == -1 {
                        die!("Failed to set session id: {}", io::Error::last_os_error());
                    }
                    ioctl::set_controlling(slave).unwrap();
                    libc::close(slave);
                    libc::close(master);
                    libc::signal(libc::SIGCHLD, libc::SIG_DFL);
                    libc::signal(libc::SIGHUP, libc::SIG_DFL);
                    libc::signal(libc::SIGINT, libc::SIG_DFL);
                    libc::signal(libc::SIGQUIT, libc::SIG_DFL);
                    libc::signal(libc::SIGTERM, libc::SIG_DFL);
                    libc::signal(libc::SIGALRM, libc::SIG_DFL);
                    Ok(())
                })
                .spawn()
                .map_err(|err| {
                    error!("Error creating Pty: {}", err);
                })
                .and_then(|_ch| {
                    let child = Pty {
                        fd: pty.master,
                        file: File::from_raw_fd(pty.master),
                        fin: File::from_raw_fd(pty.master),
                        slave,
                        master
                    };
                    child.resize(new_winsize)?;
                    Ok(child)
                })
        }
    }
pub fn new ( config : Config < crate :: config :: ui_config :: UiConfig > , size : SizeInfo ) -> Result < Pty , ( ) > { let new_winsize = winsize { ws_row : size . screen_lines ( ) as u16 , ws_col : size . columns ( ) as u16 , ws_xpixel : size . width ( ) as libc :: c_ushort , ws_ypixel : size . height ( ) as libc :: c_ushort , } ; let pty = openpty ( & new_winsize , None ) . unwrap ( ) ; if let Ok ( mut termios ) = termios :: tcgetattr ( pty . master ) { // Set character encoding to UTF-8. termios . input_flags . set ( InputFlags :: IUTF8 , true ) ; let _ = termios :: tcsetattr ( pty . master , SetArg :: TCSANOW , & termios ) ; } let mut buf = [ 0 ; 1024 ] ; let pw = get_pw_entry ( & mut buf ) ; let slave = pty . slave ; let master = pty . master ; let ( command , args ) = match config . shell { Some ( program ) => { match program { Program :: Just ( str ) => { ( str , Vec :: < String > :: new ( ) ) } , Program :: WithArgs { program , args } => { ( program , args ) } } } , None => { ( crate :: tab_manager :: DEFAULT_SHELL . to_string ( ) , Vec :: < String > :: new ( ) ) } } ; unsafe { Command :: new ( & command ) . args ( args . to_vec ( ) ) . stdin ( Stdio :: from_raw_fd ( pty . slave ) ) . stdout ( Stdio :: from_raw_fd ( pty . slave ) ) . stderr ( Stdio :: from_raw_fd ( pty . slave ) ) . env ( " " , pw . name ) . env ( " " , pw . name ) . env ( " " , pw . dir ) . env ( " " , crate :: tab_manager :: DEFAULT_SHELL ) . pre_exec ( move | | { let pid = setsid ( ) . map_err ( | e | format ! ( " " e ) ) . unwrap ( ) ; if pid . as_raw ( ) == - 1 { die ! ( " " io Error last_os_error ( ) ) ; } ioctl :: set_controlling ( slave ) . unwrap ( ) ; libc :: close ( slave ) ; libc :: close ( master ) ; libc :: signal ( libc :: SIGCHLD , libc :: SIG_DFL ) ; libc :: signal ( libc :: SIGHUP , libc :: SIG_DFL ) ; libc :: signal ( libc :: SIGINT , libc :: SIG_DFL ) ; libc :: signal ( libc :: SIGQUIT , libc :: SIG_DFL ) ; libc :: signal ( libc :: SIGTERM , libc :: SIG_DFL ) ; libc :: signal ( libc :: SIGALRM , libc :: SIG_DFL ) ; Ok ( ( ) ) } ) . spawn ( ) . map_err ( | err | { error ! ( " " err ) ; } ) . and_then ( | _ch | { let child = Pty { fd : pty . master , file : File :: from_raw_fd ( pty . master ) , fin : File :: from_raw_fd ( pty . master ) , slave , master } ; child . resize ( new_winsize ) ? ; Ok ( child ) } ) } }
Spawn a process in a new pty.
Spawn a process in a new pty .
config
Config<crate::config::ui_config::UiConfig>
size
SizeInfo