diff options
author | Jesse Luehrs <doy@tozt.net> | 2021-12-30 15:43:53 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2021-12-30 15:44:29 -0500 |
commit | b82bcb3aeb96fd3a867e6e717be3b9431faa70bd (patch) | |
tree | d3260785f9c4c6ada2cbfc79728d0d6a1aec7441 | |
parent | d1a9c4d1d878e7bcb4caac766fabcfb48fe418f2 (diff) | |
download | pty-process-b82bcb3aeb96fd3a867e6e717be3b9431faa70bd.tar.gz pty-process-b82bcb3aeb96fd3a867e6e717be3b9431faa70bd.zip |
simplify
-rw-r--r-- | src/blocking/command.rs | 9 | ||||
-rw-r--r-- | src/command.rs | 9 | ||||
-rw-r--r-- | src/sys.rs | 20 |
3 files changed, 21 insertions, 17 deletions
diff --git a/src/blocking/command.rs b/src/blocking/command.rs index b2ca3e4..ed36443 100644 --- a/src/blocking/command.rs +++ b/src/blocking/command.rs @@ -103,25 +103,26 @@ impl Command { &mut self, pty: &crate::blocking::Pty, ) -> crate::Result<std::process::Child> { - let (stdin, stdout, stderr, mut pre_exec) = - crate::sys::setup_subprocess(pty.pts())?; + let pts = pty.pts(); + let (stdin, stdout, stderr) = crate::sys::setup_subprocess(pts)?; self.inner.stdin(self.stdin.take().unwrap_or(stdin)); self.inner.stdout(self.stdout.take().unwrap_or(stdout)); self.inner.stderr(self.stderr.take().unwrap_or(stderr)); + let mut session_leader = crate::sys::session_leader(pts); // safe because setsid() is an async-signal-safe function and ioctl() // is a raw syscall (which is inherently async-signal-safe). if let Some(mut custom) = self.pre_exec.take() { unsafe { self.inner.pre_exec(move || { - pre_exec()?; + session_leader()?; custom()?; Ok(()) }) }; } else { - unsafe { self.inner.pre_exec(pre_exec) }; + unsafe { self.inner.pre_exec(session_leader) }; } Ok(self.inner.spawn()?) diff --git a/src/command.rs b/src/command.rs index c50af30..cd1c8a3 100644 --- a/src/command.rs +++ b/src/command.rs @@ -103,25 +103,26 @@ impl Command { &mut self, pty: &crate::Pty, ) -> crate::Result<async_process::Child> { - let (stdin, stdout, stderr, mut pre_exec) = - crate::sys::setup_subprocess(pty.pts())?; + let pts = pty.pts(); + let (stdin, stdout, stderr) = crate::sys::setup_subprocess(pts)?; self.inner.stdin(self.stdin.take().unwrap_or(stdin)); self.inner.stdout(self.stdout.take().unwrap_or(stdout)); self.inner.stderr(self.stderr.take().unwrap_or(stderr)); + let mut session_leader = crate::sys::session_leader(pts); // Safety: setsid() is an async-signal-safe function and ioctl() is a // raw syscall (which is inherently async-signal-safe). if let Some(mut custom) = self.pre_exec.take() { unsafe { self.inner.pre_exec(move || { - pre_exec()?; + session_leader()?; custom()?; Ok(()) }) }; } else { - unsafe { self.inner.pre_exec(pre_exec) }; + unsafe { self.inner.pre_exec(session_leader) }; } Ok(self.inner.spawn()?) @@ -46,7 +46,6 @@ pub fn setup_subprocess( std::process::Stdio, std::process::Stdio, std::process::Stdio, - impl FnMut() -> std::io::Result<()>, )> { let pts_fd = pts.as_raw_fd(); @@ -63,17 +62,20 @@ pub fn setup_subprocess( unsafe { std::process::Stdio::from_raw_fd(stdin) }, unsafe { std::process::Stdio::from_raw_fd(stdout) }, unsafe { std::process::Stdio::from_raw_fd(stderr) }, - move || { - nix::unistd::setsid()?; - set_controlling_terminal(pts_fd)?; - - // no need to close anything, since we set cloexec everywhere - - Ok(()) - }, )) } +pub fn session_leader( + pts: &impl std::os::unix::io::AsRawFd, +) -> impl FnMut() -> std::io::Result<()> { + let pts_fd = pts.as_raw_fd(); + move || { + nix::unistd::setsid()?; + set_controlling_terminal(pts_fd)?; + Ok(()) + } +} + fn set_controlling_terminal(fd: std::os::unix::io::RawFd) -> nix::Result<()> { // Safety: std::fs::File is required to contain a valid file descriptor unsafe { set_controlling_terminal_unsafe(fd, std::ptr::null()) } |