scx_pandemonium/cli/
death_pipe.rs1use std::sync::atomic::{AtomicBool, Ordering};
2
3pub fn create_death_pipe() -> Result<(i32, i32), std::io::Error> {
7 let mut fds = [0i32; 2];
8 let ret = unsafe { libc::pipe2(fds.as_mut_ptr(), 0) };
9 if ret < 0 {
10 return Err(std::io::Error::last_os_error());
11 }
12 Ok((fds[0], fds[1]))
13}
14
15pub fn close_fd(fd: i32) {
16 if fd >= 0 {
17 unsafe {
18 libc::close(fd);
19 }
20 }
21}
22
23pub fn spawn_death_watcher(death_fd: i32, running: &'static AtomicBool) {
27 std::thread::Builder::new()
28 .name("death-watcher".into())
29 .spawn(move || {
30 let mut pfd = libc::pollfd {
31 fd: death_fd,
32 events: libc::POLLIN,
33 revents: 0,
34 };
35 while running.load(Ordering::Relaxed) {
36 let ret = unsafe { libc::poll(&mut pfd, 1, 100) };
37 if ret > 0 && (pfd.revents & (libc::POLLHUP | libc::POLLERR)) != 0 {
38 running.store(false, Ordering::Relaxed);
39 break;
40 }
41 if ret < 0 {
42 let err = std::io::Error::last_os_error();
43 if err.kind() != std::io::ErrorKind::Interrupted {
44 running.store(false, Ordering::Relaxed);
45 break;
46 }
47 }
48 }
49 unsafe {
50 libc::close(death_fd);
51 }
52 })
53 .ok();
54}