aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-12-30 15:43:53 -0500
committerJesse Luehrs <doy@tozt.net>2021-12-30 15:44:29 -0500
commitb82bcb3aeb96fd3a867e6e717be3b9431faa70bd (patch)
treed3260785f9c4c6ada2cbfc79728d0d6a1aec7441
parentd1a9c4d1d878e7bcb4caac766fabcfb48fe418f2 (diff)
downloadpty-process-b82bcb3aeb96fd3a867e6e717be3b9431faa70bd.tar.gz
pty-process-b82bcb3aeb96fd3a867e6e717be3b9431faa70bd.zip
simplify
-rw-r--r--src/blocking/command.rs9
-rw-r--r--src/command.rs9
-rw-r--r--src/sys.rs20
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()?)
diff --git a/src/sys.rs b/src/sys.rs
index b837949..0d897bc 100644
--- a/src/sys.rs
+++ b/src/sys.rs
@@ -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()) }