Skip to content

Commit 05fd96c

Browse files
committed
Fold the signal-hook-sys inside the main signal-hook
To avoid problems with extra dependency, compatibility, etc.
1 parent 1150bb3 commit 05fd96c

File tree

16 files changed

+106
-159
lines changed

16 files changed

+106
-159
lines changed

.github/workflows/test.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ jobs:
151151
- name: Check compilation
152152
run: |
153153
rm Cargo.lock
154+
cargo update
154155
cargo check --no-default-features
155156
156157

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
* Allow extracting Origin from the raw `siginfo_t` structure by hand, without
44
needing an iterator.
5+
* Folding the signal-hook-sys inline (but still compiling C code only
6+
conditionally).
57

68
# 0.3.1
79

Cargo.lock

+1-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+6-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ maintenance = { status = "actively-developed" }
2020
channel = []
2121
default = ["channel", "iterator"]
2222
iterator = []
23-
extended-siginfo = ["channel", "iterator", "signal-hook-sys"]
23+
extended-siginfo = ["channel", "iterator", "extended-siginfo-raw"]
24+
extended-siginfo-raw = ["cc"]
2425

2526
[workspace]
2627
members = [
@@ -29,16 +30,18 @@ members = [
2930
"signal-hook-tokio",
3031
"signal-hook-mio",
3132
"signal-hook-async-std",
32-
"signal-hook-sys",
3333
]
3434

3535
[dependencies]
3636
libc = "^0.2"
3737
signal-hook-registry = { version = "^1.3", path = "signal-hook-registry" }
38-
signal-hook-sys = { version = "^0.1.1", path = "signal-hook-sys", optional = true }
3938

4039
[dev-dependencies]
4140
serial_test = "^0.5"
4241

4342
[package.metadata.docs.rs]
4443
all-features = true
44+
rustdoc-args = ["--cfg", "docsrs"]
45+
46+
[build-dependencies]
47+
cc = { version = "^1", optional = true }

build.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[cfg(feature = "extended-siginfo-raw")]
2+
fn main() {
3+
cc::Build::new()
4+
.file("src/low_level/extract.c")
5+
.compile("extract");
6+
}
7+
8+
#[cfg(not(feature = "extended-siginfo-raw"))]
9+
fn main() {}

signal-hook-async-std/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ serial_test = "~0.5"
3030

3131
[package.metadata.docs.rs]
3232
all-features = true
33+
rustdoc-args = ["--cfg", "docsrs"]

signal-hook-mio/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ serial_test = "~0.5"
3636

3737
[package.metadata.docs.rs]
3838
all-features = true
39+
rustdoc-args = ["--cfg", "docsrs"]

signal-hook-sys/Cargo.toml

-16
This file was deleted.

signal-hook-sys/LICENSE-APACHE

-1
This file was deleted.

signal-hook-sys/LICENSE-MIT

-1
This file was deleted.

signal-hook-sys/build.rs

-5
This file was deleted.

signal-hook-sys/src/lib.rs

-116
This file was deleted.

signal-hook-tokio/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ serial_test = "~0.5"
3737

3838
[package.metadata.docs.rs]
3939
all-features = true
40+
rustdoc-args = ["--cfg", "docsrs"]

signal-hook-sys/src/extract.c src/low_level/extract.c

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*
2+
* Low-level extraction code to overcome rust's libc not having the best access
3+
* to siginfo_t details.
4+
*/
15
#include <stdbool.h>
26
#include <signal.h>
37
#include <stdint.h>

src/low_level/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use libc::c_int;
1010
pub mod channel;
1111
#[cfg(not(windows))]
1212
pub mod pipe;
13-
#[cfg(feature = "signal-hook-sys")]
13+
#[cfg(feature = "extended-siginfo-raw")]
1414
pub mod siginfo;
1515

1616
pub use signal_hook_registry::{register, unregister};

src/low_level/siginfo.rs

+79-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,54 @@
33
//! See [`Origin`].
44
55
use libc::{c_int, pid_t, siginfo_t, uid_t};
6-
use signal_hook_sys::internal::{Cause as ICause, SigInfo};
6+
// Careful: make sure the signature and the constants match the C source
7+
extern "C" {
8+
fn sighook_signal_cause(info: &siginfo_t) -> ICause;
9+
fn sighook_signal_pid(info: &siginfo_t) -> pid_t;
10+
fn sighook_signal_uid(info: &siginfo_t) -> uid_t;
11+
}
12+
13+
// Warning: must be in sync with the C code
14+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
15+
#[non_exhaustive]
16+
#[repr(u8)]
17+
// For some reason, the fact it comes from the C makes rustc emit warning that *some* of these are
18+
// not constructed. No idea why only some of them.
19+
#[allow(dead_code)]
20+
enum ICause {
21+
Unknown = 0,
22+
Kernel = 1,
23+
User = 2,
24+
TKill = 3,
25+
Queue = 4,
26+
MesgQ = 5,
27+
Exited = 6,
28+
Killed = 7,
29+
Dumped = 8,
30+
Trapped = 9,
31+
Stopped = 10,
32+
Continued = 11,
33+
}
34+
35+
impl ICause {
36+
// The MacOs doesn't use the SI_* constants and leaves si_code at 0. But it doesn't use an
37+
// union, it has a good-behaved struct with fields and therefore we *can* read the values,
38+
// even though they'd contain nonsense (zeroes). We wipe that out later.
39+
#[cfg(target_os = "macos")]
40+
fn has_process(self) -> bool {
41+
true
42+
}
43+
44+
#[cfg(not(target_os = "macos"))]
45+
fn has_process(self) -> bool {
46+
use ICause::*;
47+
match self {
48+
Unknown | Kernel => false,
49+
User | TKill | Queue | MesgQ | Exited | Killed | Dumped | Trapped | Stopped
50+
| Continued => true,
51+
}
52+
}
53+
}
754

855
/// Information about process, as presented in the signal metadata.
956
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -16,6 +63,23 @@ pub struct Process {
1663
pub uid: uid_t,
1764
}
1865

66+
impl Process {
67+
/**
68+
* Extract the process information.
69+
*
70+
* # Safety
71+
*
72+
* The `info` must have a `si_code` corresponding to some situation that has the `si_pid`
73+
* and `si_uid` filled in.
74+
*/
75+
unsafe fn extract(info: &siginfo_t) -> Self {
76+
Self {
77+
pid: sighook_signal_pid(info),
78+
uid: sighook_signal_uid(info),
79+
}
80+
}
81+
}
82+
1983
/// The means by which a signal was sent by other process.
2084
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2185
#[non_exhaustive]
@@ -154,14 +218,22 @@ impl Origin {
154218
/// The value passed by kernel satisfies this, care must be taken only when constructed
155219
/// manually.
156220
pub unsafe fn extract(info: &siginfo_t) -> Self {
221+
let cause = sighook_signal_cause(info);
222+
let process = if cause.has_process() {
223+
let process = Process::extract(info);
224+
// On macos we don't have the si_code to go by, but we can go by the values being
225+
// empty there.
226+
if cfg!(target_os = "macos") && process.pid == 0 && process.uid == 0 {
227+
None
228+
} else {
229+
Some(process)
230+
}
231+
} else {
232+
None
233+
};
157234
let signal = info.si_signo;
158-
let extracted = SigInfo::extract(info);
159-
let process = extracted.process.map(|p| Process {
160-
pid: p.pid,
161-
uid: p.uid,
162-
});
163235
Origin {
164-
cause: extracted.cause.into(),
236+
cause: cause.into(),
165237
signal,
166238
process,
167239
}

0 commit comments

Comments
 (0)