Skip to main content

endpoint_sec/event/
event_signal.rs

1//! [`EventSignal`]
2
3use endpoint_sec_sys::es_event_signal_t;
4
5use crate::Process;
6
7/// Send a signal to a process event.
8///
9/// Signals may be sent on behalf of another process or directly. Notably
10/// launchd often sends signals on behalf of another process for service start/
11/// stop operations. If this is the case an instigator will be provided. The
12/// relationship between each process is illustrated below:
13///
14/// Delegated Signal:
15///
16/// ```
17/// Instigator Process -> IPC to Sender Process (launchd) -> Target Process
18/// ```
19///
20/// Direct Signal:
21///
22/// ```
23/// Sender Process -> Target Process
24/// ```
25///
26/// Clients may wish to block delegated signals from launchd for non-authorized
27/// instigators, while still allowing direct signals initiated by launchd for
28/// shutdown/reboot/restart.
29#[doc(alias = "es_event_signal_t")]
30pub struct EventSignal<'a> {
31    /// The raw reference.
32    pub(crate) raw: &'a es_event_signal_t,
33
34    /// The version of the message.
35    pub(crate) version: u32,
36}
37
38impl<'a> EventSignal<'a> {
39    /// The signal number to be delivered.
40    #[inline(always)]
41    pub fn sig(&self) -> i32 {
42        self.raw.sig
43    }
44
45    /// The process that will receive the signal.
46    #[inline(always)]
47    pub fn target(&self) -> Process<'a> {
48        // Safety: 'a tied to self, object obtained through ES
49        Process::new(unsafe { self.raw.target() }, self.version)
50    }
51
52    /// Process information for the instigator.
53    ///
54    /// Only available for delegated signals.
55    ///
56    /// Note: Only available only if message version >= 9.
57    #[cfg(feature = "macos_15_4_0")]
58    #[inline(always)]
59    pub fn instigator(&self) -> Option<Process<'a>> {
60        if self.version >= 9 {
61            // Safety: 'a tied to self, object obtained through ES
62            let process = unsafe { self.raw.instigator()? };
63            Some(Process::new(process, self.version))
64        } else {
65            None
66        }
67    }
68
69}
70
71// Safety: safe to send across threads: does not contain any interior mutability nor depend on current thread state
72unsafe impl Send for EventSignal<'_> {}
73// Safety: safe to share across threads: does not contain any interior mutability nor depend on current thread state
74unsafe impl Sync for EventSignal<'_> {}
75
76impl_debug_eq_hash_with_functions!(EventSignal<'a> with version; sig, target, #[cfg(feature = "macos_15_4_0")] instigator);