Skip to content

Commit 41f9d83

Browse files
committed
rust: fix windows build
1 parent 7840e51 commit 41f9d83

File tree

3 files changed

+26
-107
lines changed

3 files changed

+26
-107
lines changed

rust/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ nom = { version = "7.1", default-features = false, features = ["std"] }
2323
regex = "1.9"
2424
shell-words = "1.1"
2525
tempfile = "3.13"
26+
signal-hook = { version = "0.3", features = ["iterator"] }
2627

2728
[workspace.package]
2829
version = "4.0.0"

rust/bear/Cargo.toml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,7 @@ nom.workspace = true
4040
regex.workspace = true
4141
rand.workspace = true
4242
tempfile.workspace = true
43-
nix = { version = "0.29", optional = true, features = ["signal", "process"] }
44-
winapi = { version = "0.3", optional = true, features = ["processthreadsapi", "winnt", "handleapi"] }
45-
signal-hook = "0.3.17"
46-
47-
[target.'cfg(unix)'.dependencies]
48-
nix = { version = "0.29", features = ["signal", "process"] }
49-
50-
[target.'cfg(windows)'.dependencies]
51-
winapi = { version = "0.3", features = ["processthreadsapi", "winnt", "handleapi"] }
43+
signal-hook.workspace = true
5244

5345
[profile.release]
5446
strip = true
Lines changed: 24 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,44 @@
11
// SPDX-License-Identifier: GPL-3.0-or-later
22

33
use anyhow::Result;
4-
use nix::libc::c_int;
5-
#[cfg(unix)]
6-
use nix::sys::signal::{kill, Signal};
7-
#[cfg(unix)]
8-
use nix::unistd::Pid;
94
use std::process::{Command, ExitStatus};
10-
use std::sync::atomic::{AtomicBool, Ordering};
5+
use std::sync::atomic::{AtomicUsize, Ordering};
116
use std::sync::Arc;
127
use std::thread;
13-
use std::time::Duration;
14-
#[cfg(windows)]
15-
use winapi::shared::minwindef::FALSE;
16-
#[cfg(windows)]
17-
use winapi::um::processthreadsapi::{OpenProcess, TerminateProcess};
18-
#[cfg(windows)]
19-
use winapi::um::winnt::{PROCESS_TERMINATE, SYNCHRONIZE};
8+
use std::time;
209

2110
/// This method supervises the execution of a command.
2211
///
2312
/// It starts the command and waits for its completion. It also forwards
2413
/// signals to the child process. The method returns the exit status of the
2514
/// child process.
2615
pub fn supervise(command: &mut Command) -> Result<ExitStatus> {
27-
let mut child = command.spawn()?;
28-
29-
let child_pid = child.id();
30-
let running = Arc::new(AtomicBool::new(true));
31-
let running_in_thread = running.clone();
32-
33-
let mut signals = signal_hook::iterator::Signals::new([
34-
signal_hook::consts::SIGINT,
35-
signal_hook::consts::SIGTERM,
36-
])?;
37-
38-
#[cfg(unix)]
39-
{
40-
signals.add_signal(signal_hook::consts::SIGHUP)?;
41-
signals.add_signal(signal_hook::consts::SIGQUIT)?;
42-
signals.add_signal(signal_hook::consts::SIGALRM)?;
43-
signals.add_signal(signal_hook::consts::SIGUSR1)?;
44-
signals.add_signal(signal_hook::consts::SIGUSR2)?;
45-
signals.add_signal(signal_hook::consts::SIGCONT)?;
46-
signals.add_signal(signal_hook::consts::SIGSTOP)?;
16+
let signaled = Arc::new(AtomicUsize::new(0));
17+
for signal in signal_hook::consts::TERM_SIGNALS {
18+
signal_hook::flag::register_usize(*signal, Arc::clone(&signaled), *signal as usize)?;
4719
}
4820

49-
let handler = thread::spawn(move || {
50-
for signal in signals.forever() {
51-
log::debug!("Received signal: {:?}", signal);
52-
if forward_signal(signal, child_pid) {
53-
// If the signal caused termination, we should stop the process.
54-
running_in_thread.store(false, Ordering::SeqCst);
55-
break;
56-
}
21+
let mut child = command.spawn()?;
22+
loop {
23+
// Forward signals to the child process, but don't exit the loop while it is running
24+
if signaled.swap(0usize, Ordering::SeqCst) != 0 {
25+
log::debug!("Received signal, forwarding to child process");
26+
child.kill()?;
5727
}
58-
});
59-
60-
while running.load(Ordering::SeqCst) {
61-
thread::sleep(Duration::from_millis(100));
62-
}
63-
handler.join().unwrap();
64-
65-
let exit_status = child.wait()?;
66-
67-
Ok(exit_status)
68-
}
69-
70-
#[cfg(windows)]
71-
fn forward_signal(_: c_int, child_pid: u32) -> bool {
72-
let process_handle = unsafe { OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, child_pid) };
73-
if process_handle.is_null() {
74-
let err = unsafe { winapi::um::errhandling::GetLastError() };
75-
log::error!("Failed to open process: {}", err);
76-
// If the process handle is not valid, presume the process is not running anymore.
77-
return true;
78-
}
7928

80-
let terminated = unsafe { TerminateProcess(process_handle, 1) };
81-
if terminated == FALSE {
82-
let err = unsafe { winapi::um::errhandling::GetLastError() };
83-
log::error!("Failed to terminate process: {}", err);
84-
}
85-
86-
// Ensure proper handle closure
87-
unsafe { winapi::um::handleapi::CloseHandle(process_handle) };
88-
89-
// Return true if the process was terminated.
90-
terminated == TRUE
91-
}
92-
93-
#[cfg(unix)]
94-
fn forward_signal(signal: c_int, child_pid: u32) -> bool {
95-
// Forward the signal to the child process
96-
if let Err(e) = kill(
97-
Pid::from_raw(child_pid as i32),
98-
Signal::try_from(signal).ok(),
99-
) {
100-
log::error!("Error forwarding signal: {}", e);
101-
}
102-
103-
// Return true if the process was terminated.
104-
match kill(Pid::from_raw(child_pid as i32), None) {
105-
Ok(_) => {
106-
log::debug!("Checking if the process is still running... yes");
107-
false
108-
}
109-
Err(nix::Error::ESRCH) => {
110-
log::debug!("Checking if the process is still running... no");
111-
true
112-
}
113-
Err(_) => {
114-
log::debug!("Checking if the process is still running... presume dead");
115-
true
29+
// Check if the child process has exited
30+
match child.try_wait() {
31+
Ok(Some(exit_status)) => {
32+
log::debug!("Child process exited");
33+
return Ok(exit_status);
34+
}
35+
Ok(None) => {
36+
thread::sleep(time::Duration::from_millis(100));
37+
}
38+
Err(e) => {
39+
log::error!("Error waiting for child process: {}", e);
40+
return Err(e.into());
41+
}
11642
}
11743
}
11844
}

0 commit comments

Comments
 (0)