Function nc::pidfd_send_signal
source · pub unsafe fn pidfd_send_signal(
pidfd: i32,
sig: i32,
info: &mut siginfo_t,
flags: u32
) -> Result<(), Errno>
Expand description
Signal a process through a pidfd.
@pidfd: file descriptor of the process @sig: signal to send @info: signal info @flags: future flags
The syscall currently only signals via PIDTYPE_PID
which covers
kill(<positive-pid>, <signal>)
. It does not signal threads or process
groups.
In order to extend the syscall to threads and process groups the @flags
argument should be used. In essence, the @flags argument will determine
what is signaled and not the file descriptor itself. Put in other words,
grouping is a property of the flags argument not a property of the file
descriptor.
Return: 0 on success, negative errno on failure
Examples found in repository?
examples/pidfd.rs (line 86)
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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
fn run_main() {
const STDOUT_FD: i32 = 1;
let pid = unsafe { nc::fork() };
assert!(pid.is_ok());
if pid == Ok(0) {
let curr_pid = unsafe { nc::getpid() };
println!("In child process, pid: {}", curr_pid);
let path = "/tmp/nc-pidfdopen";
let fd = unsafe {
nc::openat(
nc::AT_FDCWD,
path,
nc::O_CREAT | nc::O_WRONLY | nc::O_TRUNC,
0o644,
)
};
assert!(fd.is_ok());
let fd = fd.unwrap();
let ret = unsafe { nc::dup3(fd, STDOUT_FD, 0) };
assert!(ret.is_ok());
println!("[child] stdout redirected to file!");
let t = nc::timespec_t {
tv_sec: 2,
tv_nsec: 0,
};
unsafe {
let ret = nc::nanosleep(&t, None);
assert!(ret.is_ok());
let ret = nc::close(fd);
assert!(ret.is_ok());
let ret = nc::unlinkat(nc::AT_FDCWD, path, 0);
assert!(ret.is_ok());
nc::exit(0);
}
}
let pid = pid.unwrap();
println!("[parent] child pid: {}", pid);
let t = nc::timespec_t {
tv_sec: 2,
tv_nsec: 0,
};
let ret = unsafe { nc::nanosleep(&t, None) };
assert!(ret.is_ok());
let pidfd = unsafe { nc::pidfd_open(pid, 0) };
assert!(pidfd.is_ok());
let pidfd = pidfd.unwrap();
let ret = unsafe { nc::pidfd_getfd(pidfd, STDOUT_FD, 0) };
println!("ret: {:?}", ret);
if let Err(errno) = ret {
eprintln!("pidfd_getfd() failed, err: {}", nc::strerror(errno));
}
let child_stdout_fd = ret.unwrap();
let msg = "Hello, msg from parent process\n";
let ret = unsafe { nc::write(child_stdout_fd, msg.as_ptr() as usize, msg.len()) };
assert!(ret.is_ok());
let nwrite = ret.unwrap();
assert_eq!(nwrite as usize, msg.len());
let mut info = nc::siginfo_t::default();
let ret = unsafe { nc::pidfd_send_signal(pidfd, nc::SIGKILL, &mut info, 0) };
println!("ret: {:?}", ret);
if let Err(errno) = ret {
eprintln!("pidfd_send_signal() failed, err: {}", nc::strerror(errno));
}
unsafe {
let ret = nc::close(pidfd);
assert!(ret.is_ok());
let ret = nc::close(child_stdout_fd);
assert!(ret.is_ok());
}
}