diff options
author | German Maglione <gmaglione@redhat.com> | 2022-06-08 15:55:13 +0200 |
---|---|---|
committer | German Maglione <gmaglione@redhat.com> | 2022-07-12 17:25:51 +0200 |
commit | 3d44d276e768f47cefe301e3affbefd315dc1327 (patch) | |
tree | 4a2c5236c5325ad7e4d353bd8c0d285424761768 /src | |
parent | 5f859d10dfd21b99405054d80392649adc392fd0 (diff) | |
download | nix-3d44d276e768f47cefe301e3affbefd315dc1327.zip |
SigSet: A new unsafe helper method to create a SigSet from a sigset_t
Currently, the only way to create a `SigSet` from a `sigset_t` object
is by using pointer casts, like:
```
unsafe {
let sigset = *(&sigset as *const libc::sigset_t as *const SigSet)
};
```
This is un-ergonomic for library creators with interfaces to C.
So, let's add a new unsafe method that creates a `SigSet` from a
`libc::sigset_t` object.
We can't implement `From` since converting from `libc::sigset_t` to
`SigSet` is unsafe, because objects of type `libc::sigset_t` must be
initialized by calling either `sigemptyset(3)` or `sigfillset(3)`
before being used. In other case, the results are undefined.
We can't implement `TryFrom` either, because there is no way to check
if an object of type `libc::sigset_t` is initialized.
Signed-off-by: German Maglione <gmaglione@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/sys/signal.rs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/sys/signal.rs b/src/sys/signal.rs index 529b39a8..4ce09308 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -567,6 +567,19 @@ impl SigSet { Signal::try_from(signum.assume_init()).unwrap() }) } + + /// Converts a `libc::sigset_t` object to a [`SigSet`] without checking whether the + /// `libc::sigset_t` is already initialized. + /// + /// # Safety + /// + /// The `sigset` passed in must be a valid an initialized `libc::sigset_t` by calling either + /// [`sigemptyset(3)`](https://man7.org/linux/man-pages/man3/sigemptyset.3p.html) or + /// [`sigfillset(3)`](https://man7.org/linux/man-pages/man3/sigfillset.3p.html). + /// Otherwise, the results are undefined. + pub unsafe fn from_sigset_t_unchecked(sigset: libc::sigset_t) -> SigSet { + SigSet { sigset } + } } impl AsRef<libc::sigset_t> for SigSet { @@ -1311,4 +1324,21 @@ mod tests { .join() .unwrap(); } + + #[test] + fn test_from_sigset_t_unchecked() { + let src_set = SigSet::empty(); + let set = unsafe { SigSet::from_sigset_t_unchecked(src_set.sigset) }; + + for signal in Signal::iterator() { + assert!(!set.contains(signal)); + } + + let src_set = SigSet::all(); + let set = unsafe { SigSet::from_sigset_t_unchecked(src_set.sigset) }; + + for signal in Signal::iterator() { + assert!(set.contains(signal)); + } + } } |