diff options
author | Jesse Luehrs <doy@tozt.net> | 2020-07-17 01:21:20 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2020-07-17 01:21:20 -0400 |
commit | 6985d5dd288ebc665fa5b342d013fba656276a61 (patch) | |
tree | e422c2fca52c1ca26c4e8f3ea0b8af25f0785e85 | |
parent | 1996a03987a5a8c7e50a16a7a63b6dbdcd0424ad (diff) | |
download | pty-process-6985d5dd288ebc665fa5b342d013fba656276a61.tar.gz pty-process-6985d5dd288ebc665fa5b342d013fba656276a61.zip |
make the pty the controlling terminal for the child spawned into it
this is necessary to propagate SIGWINCH signals, among other things
-rw-r--r-- | src/command.rs | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/command.rs b/src/command.rs index cf1925d..7377881 100644 --- a/src/command.rs +++ b/src/command.rs @@ -35,10 +35,17 @@ impl Command for std::process::Command { .stdout(unsafe { std::process::Stdio::from_raw_fd(stdout) }) .stderr(unsafe { std::process::Stdio::from_raw_fd(stderr) }); - // safe because the only thing this function does is call close(), - // which is an async-signal-safe function + // XXX not entirely safe - setsid() and close() are async-signal-safe + // functions, but ioctl() is not, and only async-signal-safe functions + // are allowed to be called between fork() and exec(). other things + // seem to be able to get away with this though, so i'm not sure what + // the right answer here is? unsafe { self.pre_exec(move || { + nix::unistd::setsid().map_err(|e| e.as_errno().unwrap())?; + set_controlling_terminal(pts_fd, std::ptr::null()) + .map_err(|e| e.as_errno().unwrap())?; + // in the parent, destructors will handle closing these file // descriptors (other than pt, used by the parent to // communicate with the child) when the function ends, but in @@ -59,6 +66,7 @@ impl Command for std::process::Command { .map_err(|e| e.as_errno().unwrap())?; nix::unistd::close(stderr) .map_err(|e| e.as_errno().unwrap())?; + Ok(()) }); } @@ -97,3 +105,9 @@ impl std::ops::DerefMut for Child { &mut self.child } } + +nix::ioctl_write_ptr_bad!( + set_controlling_terminal, + libc::TIOCSCTTY, + libc::c_int +); |