Skip to content

Commit 269ee72

Browse files
committed
add ChildExt(::send_signal)
1 parent a124fb3 commit 269ee72

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

library/std/src/os/unix/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ pub mod prelude {
116116
#[stable(feature = "rust1", since = "1.0.0")]
117117
pub use super::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
118118
#[doc(no_inline)]
119+
#[unstable(feature = "unix_send_signal", issue = "141975")]
120+
pub use super::process::ChildExt;
121+
#[doc(no_inline)]
119122
#[stable(feature = "rust1", since = "1.0.0")]
120123
pub use super::process::{CommandExt, ExitStatusExt};
121124
#[doc(no_inline)]

library/std/src/os/unix/process.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,41 @@ impl ExitStatusExt for process::ExitStatusError {
378378
}
379379
}
380380

381+
#[unstable(feature = "unix_send_signal", issue = "141975")]
382+
pub trait ChildExt: Sealed {
383+
/// Sends a signal to a child process.
384+
///
385+
/// # Errors
386+
///
387+
/// This function will return an error if the signal is invalid. The integer values associated
388+
/// with signals are implemenation-specific, so it's encouraged to use a crate that provides
389+
/// posix bindings.
390+
///
391+
/// # Examples
392+
///
393+
/// ```rust
394+
/// #![feature(unix_send_signal)]
395+
///
396+
/// use std::{io, os::unix::process::ChildExt, process::{Command, Stdio}};
397+
///
398+
/// use libc::SIGTERM;
399+
///
400+
/// fn main() -> io::Result<()> {
401+
/// let child = Command::new("cat").stdin(Stdio::piped()).spawn()?;
402+
/// child.send_signal(SIGTERM)?;
403+
/// Ok(())
404+
/// }
405+
/// ```
406+
fn send_signal(&self, signal: i32) -> io::Result<()>;
407+
}
408+
409+
#[unstable(feature = "unix_send_signal", issue = "141975")]
410+
impl ChildExt for process::Child {
411+
fn send_signal(&self, signal: i32) -> io::Result<()> {
412+
self.handle.send_signal(signal)
413+
}
414+
}
415+
381416
#[stable(feature = "process_extensions", since = "1.2.0")]
382417
impl FromRawFd for process::Stdio {
383418
#[inline]

library/std/src/sys/pal/unix/linux/pidfd.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@ pub(crate) struct PidFd(FileDesc);
1313

1414
impl PidFd {
1515
pub fn kill(&self) -> io::Result<()> {
16+
self.send_signal(libc::SIGKILL)
17+
}
18+
19+
pub(crate) fn send_signal(&self, signal: i32) -> io::Result<()> {
1620
cvt(unsafe {
1721
libc::syscall(
1822
libc::SYS_pidfd_send_signal,
1923
self.0.as_raw_fd(),
20-
libc::SIGKILL,
24+
signal,
2125
crate::ptr::null::<()>(),
2226
0,
2327
)

library/std/src/sys/process/unix/unix.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -964,18 +964,22 @@ impl Process {
964964
}
965965

966966
pub fn kill(&mut self) -> io::Result<()> {
967+
self.send_signal(libc::SIGKILL)
968+
}
969+
970+
pub(crate) fn send_signal(&self, signal: i32) -> io::Result<()> {
967971
// If we've already waited on this process then the pid can be recycled
968-
// and used for another process, and we probably shouldn't be killing
972+
// and used for another process, and we probably shouldn't be signaling
969973
// random processes, so return Ok because the process has exited already.
970974
if self.status.is_some() {
971975
return Ok(());
972976
}
973977
#[cfg(target_os = "linux")]
974978
if let Some(pid_fd) = self.pidfd.as_ref() {
975979
// pidfd_send_signal predates pidfd_open. so if we were able to get an fd then sending signals will work too
976-
return pid_fd.kill();
980+
return pid_fd.send_signal(signal);
977981
}
978-
cvt(unsafe { libc::kill(self.pid, libc::SIGKILL) }).map(drop)
982+
cvt(unsafe { libc::kill(self.pid, signal) }).map(drop)
979983
}
980984

981985
pub fn wait(&mut self) -> io::Result<ExitStatus> {

0 commit comments

Comments
 (0)