1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
use std::io::Result; use std::os::unix::io::RawFd; use std::path::PathBuf; pub fn before_exec() -> Result<()> { use libc; unsafe { libc::setsid(); libc::ioctl(0, libc::TIOCSCTTY, 1); } Ok(()) } pub fn fork() -> usize { use libc; unsafe { libc::fork() as usize } } pub fn set_winsize(fd: RawFd, row: u16, col: u16, xpixel: u16, ypixel: u16) { use libc; unsafe { let size = libc::winsize { ws_row: row, ws_col: col, ws_xpixel: xpixel, ws_ypixel: ypixel, }; libc::ioctl(fd, libc::TIOCSWINSZ, &size as *const libc::winsize); } } pub fn getpty() -> (RawFd, PathBuf) { use libc; use std::ffi::CStr; use std::fs::OpenOptions; use std::io::Error; use std::os::unix::io::IntoRawFd; const TIOCPKT: libc::c_ulong = 0x5420; extern "C" { fn ptsname(fd: libc::c_int) -> *const libc::c_char; fn grantpt(fd: libc::c_int) -> libc::c_int; fn unlockpt(fd: libc::c_int) -> libc::c_int; fn ioctl(fd: libc::c_int, request: libc::c_ulong, ...) -> libc::c_int; } let master_fd = OpenOptions::new() .read(true) .write(true) .open("/dev/ptmx") .unwrap() .into_raw_fd(); unsafe { let mut flag: libc::c_int = 1; if ioctl(master_fd, TIOCPKT, &mut flag as *mut libc::c_int) < 0 { panic!("ioctl: {:?}", Error::last_os_error()); } if grantpt(master_fd) < 0 { panic!("grantpt: {:?}", Error::last_os_error()); } if unlockpt(master_fd) < 0 { panic!("unlockpt: {:?}", Error::last_os_error()); } } let tty_path = unsafe { PathBuf::from( CStr::from_ptr(ptsname(master_fd)) .to_string_lossy() .into_owned(), ) }; (master_fd, tty_path) }