Skip to main content

syd/
lib.rs

1//
2// libsyd: Rust-based C library for syd interaction via /dev/syd
3// lib/src/lib.rs: syd API C Library
4//
5// Copyright (c) 2023, 2024, 2025, 2026 Ali Polatel <alip@chesswob.org>
6//
7// SPDX-License-Identifier: LGPL-3.0
8
9//! # libsyd - syd API Rust Library
10//!
11//! `libsyd` is a C library written in Rust that implements the syd
12//! stat API, providing an interface to the `/dev/syd` of syd. It
13//! allows for runtime configuration and interaction with the syd
14//! sandboxing environment.
15//!
16//! ## Overview
17//! The library is designed to interact with the syd sandboxing
18//! environment, offering functionalities to check and modify the state
19//! of the sandbox lock, and perform system calls to `/dev/syd`.
20//!
21//! For more detailed information and usage instructions, refer to the syd
22//! manual, available at [syd Manual](http://man.exherbo.org/syd.2.html).
23//!
24//! ## Author
25//! Ali Polatel <alip@chesswob.org>
26
27// We like safe, clean and simple code with documentation.
28#![deny(missing_docs)]
29#![deny(clippy::allow_attributes_without_reason)]
30#![deny(clippy::arithmetic_side_effects)]
31#![deny(clippy::as_ptr_cast_mut)]
32#![deny(clippy::as_underscore)]
33#![deny(clippy::assertions_on_result_states)]
34#![deny(clippy::borrow_as_ptr)]
35#![deny(clippy::branches_sharing_code)]
36#![deny(clippy::case_sensitive_file_extension_comparisons)]
37#![deny(clippy::cast_lossless)]
38#![deny(clippy::cast_possible_truncation)]
39#![deny(clippy::cast_possible_wrap)]
40#![deny(clippy::cast_precision_loss)]
41#![deny(clippy::cast_ptr_alignment)]
42#![deny(clippy::cast_sign_loss)]
43#![deny(clippy::checked_conversions)]
44#![deny(clippy::clear_with_drain)]
45#![deny(clippy::clone_on_ref_ptr)]
46#![deny(clippy::cloned_instead_of_copied)]
47#![deny(clippy::cognitive_complexity)]
48#![deny(clippy::collection_is_never_read)]
49#![deny(clippy::copy_iterator)]
50#![deny(clippy::create_dir)]
51#![deny(clippy::dbg_macro)]
52#![deny(clippy::debug_assert_with_mut_call)]
53#![deny(clippy::decimal_literal_representation)]
54#![deny(clippy::default_trait_access)]
55#![deny(clippy::default_union_representation)]
56#![deny(clippy::derive_partial_eq_without_eq)]
57#![deny(clippy::doc_link_with_quotes)]
58#![deny(clippy::doc_markdown)]
59#![deny(clippy::explicit_into_iter_loop)]
60#![deny(clippy::explicit_iter_loop)]
61#![deny(clippy::fallible_impl_from)]
62#![deny(clippy::missing_safety_doc)]
63#![deny(clippy::undocumented_unsafe_blocks)]
64
65use std::{
66    ffi::{CStr, OsStr, OsString},
67    fmt,
68    fs::{symlink_metadata, Metadata},
69    os::{
70        fd::RawFd,
71        linux::fs::MetadataExt as LinuxMetadataExt,
72        raw::{c_char, c_int},
73        unix::{
74            ffi::OsStrExt,
75            fs::{FileTypeExt, MetadataExt as UnixMetadataExt},
76        },
77    },
78    path::{Path, PathBuf},
79};
80
81/// `lock_state_t_t` type represents possible states for the sandbox lock.
82#[expect(non_camel_case_types)]
83pub type lock_state_t = u8;
84
85/// The sandbox lock is off, allowing all sandbox commands.
86pub const LOCK_OFF: lock_state_t = 0;
87/// The sandbox lock is set to on for all processes except the initial
88/// process (syd exec child).
89pub const LOCK_EXEC: lock_state_t = 1;
90/// The sandbox lock is in drop-only mode, allowing only privilege-dropping
91/// sandbox commands.
92pub const LOCK_DROP: lock_state_t = 2;
93/// The sandbox lock is in read-only mode, allowing only read-only access
94/// to sandbox state.
95pub const LOCK_READ: lock_state_t = 3;
96/// The sandbox lock is on, disallowing all sandbox commands.
97pub const LOCK_ON: lock_state_t = 4;
98
99// An enumeration of the possible states for the sandbox lock.
100#[repr(u8)]
101#[derive(Copy, Clone, Debug)]
102enum LockState {
103    // The sandbox lock is off, allowing all sandbox commands.
104    Off = LOCK_OFF,
105    // The sandbox lock is set to on for all processes except the initial
106    // process (syd exec child).
107    Exec = LOCK_EXEC,
108    // The sandbox lock is in drop-only mode, allowing only privilege-dropping
109    // sandbox commands.
110    Drop = LOCK_DROP,
111    // The sandbox lock is in read-only mode, allowing only read-only access
112    // to sandbox state.
113    Read = LOCK_READ,
114    // The sandbox lock is on, disallowing all sandbox commands.
115    On = LOCK_ON,
116}
117
118impl TryFrom<lock_state_t> for LockState {
119    type Error = ();
120
121    fn try_from(value: lock_state_t) -> Result<Self, Self::Error> {
122        match value {
123            LOCK_OFF => Ok(LockState::Off),
124            LOCK_EXEC => Ok(LockState::Exec),
125            LOCK_DROP => Ok(LockState::Drop),
126            LOCK_READ => Ok(LockState::Read),
127            LOCK_ON => Ok(LockState::On),
128            _ => Err(()),
129        }
130    }
131}
132
133impl fmt::Display for LockState {
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        let state_str = match self {
136            LockState::Off => "off",
137            LockState::Exec => "exec",
138            LockState::Drop => "drop",
139            LockState::Read => "read",
140            LockState::On => "on",
141        };
142        write!(f, "{state_str}")
143    }
144}
145
146/// `action_t` type represents possible sandboxing action values.
147#[expect(non_camel_case_types)]
148pub type action_t = u8;
149
150/// Allow system call.
151pub const ACTION_ALLOW: action_t = 0;
152/// Allow system call and warn.
153pub const ACTION_WARN: action_t = 1;
154/// Deny system call silently.
155pub const ACTION_FILTER: action_t = 2;
156/// Deny system call and warn.
157pub const ACTION_DENY: action_t = 3;
158/// Deny system call, warn and panic the current Syd thread.
159pub const ACTION_PANIC: action_t = 4;
160/// Deny system call, warn and stop the offending process.
161pub const ACTION_STOP: action_t = 5;
162/// Deny system call, warn and abort the offending process.
163pub const ACTION_ABORT: action_t = 6;
164/// Deny system call, warn and kill the offending process.
165pub const ACTION_KILL: action_t = 7;
166/// Warn, and exit Syd immediately with deny errno as exit value.
167pub const ACTION_EXIT: action_t = 8;
168
169// An enumeration of the possible actions for sandboxing.
170#[repr(u8)]
171#[derive(Copy, Clone, Debug)]
172enum Action {
173    // Allow system call.
174    Allow = ACTION_ALLOW,
175    // Allow system call and warn.
176    Warn = ACTION_WARN,
177    // Deny system call silently.
178    Filter = ACTION_FILTER,
179    // Deny system call and warn.
180    Deny = ACTION_DENY,
181    // Deny system call, warn and panic the current Syd thread.
182    Panic = ACTION_PANIC,
183    // Deny system call, warn and stop the offending process.
184    Stop = ACTION_STOP,
185    // Deny system call, warn and abort offending process.
186    Abort = ACTION_ABORT,
187    // Deny system call, warn and kill the offending process.
188    Kill = ACTION_KILL,
189    // Warn, and exit Syd immediately with deny errno as exit value.
190    Exit = ACTION_EXIT,
191}
192
193impl TryFrom<action_t> for Action {
194    type Error = ();
195
196    fn try_from(value: action_t) -> Result<Self, Self::Error> {
197        match value {
198            ACTION_ALLOW => Ok(Action::Allow),
199            ACTION_WARN => Ok(Action::Warn),
200            ACTION_FILTER => Ok(Action::Filter),
201            ACTION_DENY => Ok(Action::Deny),
202            ACTION_PANIC => Ok(Action::Panic),
203            ACTION_STOP => Ok(Action::Stop),
204            ACTION_ABORT => Ok(Action::Abort),
205            ACTION_KILL => Ok(Action::Kill),
206            ACTION_EXIT => Ok(Action::Exit),
207            _ => Err(()),
208        }
209    }
210}
211
212impl fmt::Display for Action {
213    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214        let action_str = match self {
215            Action::Allow => "allow",
216            Action::Warn => "warn",
217            Action::Filter => "filter",
218            Action::Deny => "deny",
219            Action::Panic => "panic",
220            Action::Stop => "stop",
221            Action::Abort => "abort",
222            Action::Kill => "kill",
223            Action::Exit => "exit",
224        };
225        write!(f, "{action_str}")
226    }
227}
228
229const EFAULT: i32 = 14;
230const EINVAL: i32 = 22;
231const LIB_MAJOR: &'static str = env!("CARGO_PKG_VERSION_MAJOR");
232const SYD_ATIME: i64 = 505958400;
233const SYD_CTIME: i64 = -2036448000;
234const SYD_MTIME: i64 = -842745600;
235
236fn check_stat(stat: &Metadata) -> bool {
237    let lib_major = if let Ok(lib_major) = LIB_MAJOR.parse() {
238        lib_major
239    } else {
240        return false;
241    };
242
243    // Check file type.
244    if !stat.file_type().is_char_device() {
245        return false;
246    }
247
248    // Check timestamps.
249    if stat.st_atime() != SYD_ATIME {
250        return false;
251    }
252    if stat.st_ctime() != SYD_CTIME {
253        return false;
254    }
255    if stat.st_mtime() != SYD_MTIME {
256        return false;
257    }
258
259    let rdev = stat.rdev();
260
261    let api_major = (rdev >> 8) & 0xff;
262    let api_minor = rdev & 0xff;
263
264    // Device type represents syd(2) API version.
265    // See RETURN VALUE section in syd(2) manual page.
266    api_major == lib_major && api_minor >= 1
267}
268
269fn stat<P: AsRef<Path>>(path: P) -> c_int {
270    match symlink_metadata(path) {
271        Ok(stat) if check_stat(&stat) => 0,
272        Ok(_) => -EINVAL,
273        Err(error) => match error.raw_os_error() {
274            Some(e) => e.checked_neg().unwrap_or(-EINVAL),
275            None => -EINVAL,
276        },
277    }
278}
279
280fn esyd<P: AsRef<Path>>(rule: P, elem: *const c_char, op: u8) -> c_int {
281    if !matches!(op, b'+' | b'-' | b'^' | b':') {
282        return -EINVAL;
283    }
284
285    if elem.is_null() {
286        return -EFAULT;
287    }
288
289    // SAFETY: Trust that `elem` is a null-terminated string.
290    let elem = unsafe { CStr::from_ptr(elem) };
291    let elem = OsStr::from_bytes(elem.to_bytes());
292
293    // Manually concatenate the path segments
294    let mut path = OsString::from("/dev/syd/");
295    path.push(rule.as_ref());
296    path.push(OsStr::from_bytes(&[op]));
297    path.push(elem);
298
299    // Convert the OsString to PathBuf
300    let path = PathBuf::from(path);
301
302    stat(path)
303}
304
305/// Performs a syd API check
306///
307/// The caller is advised to perform this check before
308/// calling any other syd API calls.
309///
310/// Returns API number on success, negated errno on failure.
311#[no_mangle]
312pub extern "C" fn syd_api() -> c_int {
313    match stat("/dev/syd/3") {
314        0 => 3,
315        n => n,
316    }
317}
318
319/// Performs an lstat system call on the file "/dev/syd".
320///
321/// Returns 0 on success, negated errno on failure.
322#[no_mangle]
323pub extern "C" fn syd_check() -> c_int {
324    stat("/dev/syd")
325}
326
327/// Causes syd to exit immediately with code 127
328///
329/// Returns 0 on success, negated errno on failure.
330#[no_mangle]
331pub extern "C" fn syd_panic() -> c_int {
332    stat("/dev/syd/panic")
333}
334
335/// Causes syd to reset sandboxing to the default state.
336/// Allowlists, denylists and filters are going to be cleared.
337///
338/// Returns 0 on success, negated errno on failure.
339#[no_mangle]
340pub extern "C" fn syd_reset() -> c_int {
341    stat("/dev/syd/reset")
342}
343
344/// Causes syd to read configuration from the given file descriptor.
345///
346/// Returns 0 on success, negated errno on failure.
347#[no_mangle]
348pub extern "C" fn syd_load(fd: c_int) -> c_int {
349    let fd = match RawFd::try_from(fd) {
350        Ok(fd) if fd < 0 => return -EINVAL,
351        Ok(fd) => fd,
352        Err(_) => return -EINVAL,
353    };
354    stat(&format!("/dev/syd/load/{fd}"))
355}
356
357/// Sets the state of the sandbox lock.
358///
359/// state: The desired state of the sandbox lock.
360///
361/// Returns 0 on success, negated errno on failure.
362#[no_mangle]
363pub extern "C" fn syd_lock(state: lock_state_t) -> c_int {
364    // Convert lock_state_t enum to corresponding lock state string.
365    let state = match LockState::try_from(state) {
366        Ok(state) => state,
367        Err(_) => return -EINVAL,
368    };
369
370    stat(&format!("/dev/syd/lock:{state}"))
371}
372
373/// Checks if Filesystem sandboxing is enabled.
374///
375/// Returns true if Filesystem sandboxing is enabled, false otherwise.
376#[no_mangle]
377pub extern "C" fn syd_enabled_fs() -> bool {
378    stat("/dev/syd/sandbox/fs?") == 0
379}
380
381/// Enable Filesystem sandboxing.
382///
383/// Returns 0 on success, negated errno on failure.
384#[no_mangle]
385pub extern "C" fn syd_enable_fs() -> c_int {
386    stat("/dev/syd/sandbox/fs:on")
387}
388
389/// Disable Filesystem sandboxing.
390///
391/// Returns 0 on success, negated errno on failure.
392#[no_mangle]
393pub extern "C" fn syd_disable_fs() -> c_int {
394    stat("/dev/syd/sandbox/fs:off")
395}
396
397/// Checks if walk sandboxing is enabled.
398///
399/// Returns true if walk sandboxing is enabled, false otherwise.
400#[no_mangle]
401pub extern "C" fn syd_enabled_walk() -> bool {
402    stat("/dev/syd/sandbox/walk?") == 0
403}
404
405/// Enable walk sandboxing.
406///
407/// Returns 0 on success, negated errno on failure.
408#[no_mangle]
409pub extern "C" fn syd_enable_walk() -> c_int {
410    stat("/dev/syd/sandbox/walk:on")
411}
412
413/// Disable walk sandboxing.
414///
415/// Returns 0 on success, negated errno on failure.
416#[no_mangle]
417pub extern "C" fn syd_disable_walk() -> c_int {
418    stat("/dev/syd/sandbox/walk:off")
419}
420
421/// Checks if stat sandboxing is enabled.
422///
423/// Returns true if stat sandboxing is enabled, false otherwise.
424#[no_mangle]
425pub extern "C" fn syd_enabled_stat() -> bool {
426    stat("/dev/syd/sandbox/stat?") == 0
427}
428
429/// Enable stat sandboxing.
430///
431/// Returns 0 on success, negated errno on failure.
432#[no_mangle]
433pub extern "C" fn syd_enable_stat() -> c_int {
434    stat("/dev/syd/sandbox/stat:on")
435}
436
437/// Disable stat sandboxing.
438///
439/// Returns 0 on success, negated errno on failure.
440#[no_mangle]
441pub extern "C" fn syd_disable_stat() -> c_int {
442    stat("/dev/syd/sandbox/stat:off")
443}
444
445/// Checks if read sandboxing is enabled.
446///
447/// Returns true if read sandboxing is enabled, false otherwise.
448#[no_mangle]
449pub extern "C" fn syd_enabled_read() -> bool {
450    stat("/dev/syd/sandbox/read?") == 0
451}
452
453/// Enable read sandboxing.
454///
455/// Returns 0 on success, negated errno on failure.
456#[no_mangle]
457pub extern "C" fn syd_enable_read() -> c_int {
458    stat("/dev/syd/sandbox/read:on")
459}
460
461/// Disable read sandboxing.
462///
463/// Returns 0 on success, negated errno on failure.
464#[no_mangle]
465pub extern "C" fn syd_disable_read() -> c_int {
466    stat("/dev/syd/sandbox/read:off")
467}
468
469/// Checks if write sandboxing is enabled.
470///
471/// Returns true if write sandboxing is enabled, false otherwise.
472#[no_mangle]
473pub extern "C" fn syd_enabled_write() -> bool {
474    stat("/dev/syd/sandbox/write?") == 0
475}
476
477/// Enable write sandboxing.
478///
479/// Returns 0 on success, negated errno on failure.
480#[no_mangle]
481pub extern "C" fn syd_enable_write() -> c_int {
482    stat("/dev/syd/sandbox/write:on")
483}
484
485/// Disable write sandboxing.
486///
487/// Returns 0 on success, negated errno on failure.
488#[no_mangle]
489pub extern "C" fn syd_disable_write() -> c_int {
490    stat("/dev/syd/sandbox/write:off")
491}
492
493/// Checks if exec sandboxing is enabled.
494///
495/// Returns true if exec sandboxing is enabled, false otherwise.
496#[no_mangle]
497pub extern "C" fn syd_enabled_exec() -> bool {
498    stat("/dev/syd/sandbox/exec?") == 0
499}
500
501/// Enable exec sandboxing.
502///
503/// Returns 0 on success, negated errno on failure.
504#[no_mangle]
505pub extern "C" fn syd_enable_exec() -> c_int {
506    stat("/dev/syd/sandbox/exec:on")
507}
508
509/// Disable exec sandboxing.
510///
511/// Returns 0 on success, negated errno on failure.
512#[no_mangle]
513pub extern "C" fn syd_disable_exec() -> c_int {
514    stat("/dev/syd/sandbox/exec:off")
515}
516
517/// Checks if ioctl sandboxing is enabled.
518///
519/// Returns true if ioctl sandboxing is enabled, false otherwise.
520#[no_mangle]
521pub extern "C" fn syd_enabled_ioctl() -> bool {
522    stat("/dev/syd/sandbox/ioctl?") == 0
523}
524
525/// Enable ioctl sandboxing.
526///
527/// Returns 0 on success, negated errno on failure.
528#[no_mangle]
529pub extern "C" fn syd_enable_ioctl() -> c_int {
530    stat("/dev/syd/sandbox/ioctl:on")
531}
532
533/// Disable ioctl sandboxing.
534///
535/// Returns 0 on success, negated errno on failure.
536#[no_mangle]
537pub extern "C" fn syd_disable_ioctl() -> c_int {
538    stat("/dev/syd/sandbox/ioctl:off")
539}
540
541/// Checks if create sandboxing is enabled.
542///
543/// Returns true if create sandboxing is enabled, false otherwise.
544#[no_mangle]
545pub extern "C" fn syd_enabled_create() -> bool {
546    stat("/dev/syd/sandbox/create?") == 0
547}
548
549/// Enable create sandboxing.
550///
551/// Returns 0 on success, negated errno on failure.
552#[no_mangle]
553pub extern "C" fn syd_enable_create() -> c_int {
554    stat("/dev/syd/sandbox/create:on")
555}
556
557/// Disable create sandboxing.
558///
559/// Returns 0 on success, negated errno on failure.
560#[no_mangle]
561pub extern "C" fn syd_disable_create() -> c_int {
562    stat("/dev/syd/sandbox/create:off")
563}
564
565/// Checks if delete sandboxing is enabled.
566///
567/// Returns true if delete sandboxing is enabled, false otherwise.
568#[no_mangle]
569pub extern "C" fn syd_enabled_delete() -> bool {
570    stat("/dev/syd/sandbox/delete?") == 0
571}
572
573/// Enable delete sandboxing.
574///
575/// Returns 0 on success, negated errno on failure.
576#[no_mangle]
577pub extern "C" fn syd_enable_delete() -> c_int {
578    stat("/dev/syd/sandbox/delete:on")
579}
580
581/// Disable delete sandboxing.
582///
583/// Returns 0 on success, negated errno on failure.
584#[no_mangle]
585pub extern "C" fn syd_disable_delete() -> c_int {
586    stat("/dev/syd/sandbox/delete:off")
587}
588
589/// Checks if rename sandboxing is enabled.
590///
591/// Returns true if rename sandboxing is enabled, false otherwise.
592#[no_mangle]
593pub extern "C" fn syd_enabled_rename() -> bool {
594    stat("/dev/syd/sandbox/rename?") == 0
595}
596
597/// Enable rename sandboxing.
598///
599/// Returns 0 on success, negated errno on failure.
600#[no_mangle]
601pub extern "C" fn syd_enable_rename() -> c_int {
602    stat("/dev/syd/sandbox/rename:on")
603}
604
605/// Disable rename sandboxing.
606///
607/// Returns 0 on success, negated errno on failure.
608#[no_mangle]
609pub extern "C" fn syd_disable_rename() -> c_int {
610    stat("/dev/syd/sandbox/rename:off")
611}
612
613/// Checks if symlink sandboxing is enabled.
614///
615/// Returns true if symlink sandboxing is enabled, false otherwise.
616#[no_mangle]
617pub extern "C" fn syd_enabled_symlink() -> bool {
618    stat("/dev/syd/sandbox/symlink?") == 0
619}
620
621/// Enable symlink sandboxing.
622///
623/// Returns 0 on success, negated errno on failure.
624#[no_mangle]
625pub extern "C" fn syd_enable_symlink() -> c_int {
626    stat("/dev/syd/sandbox/symlink:on")
627}
628
629/// Disable symlink sandboxing.
630///
631/// Returns 0 on success, negated errno on failure.
632#[no_mangle]
633pub extern "C" fn syd_disable_symlink() -> c_int {
634    stat("/dev/syd/sandbox/symlink:off")
635}
636
637/// Checks if truncate sandboxing is enabled.
638///
639/// Returns true if truncate sandboxing is enabled, false otherwise.
640#[no_mangle]
641pub extern "C" fn syd_enabled_truncate() -> bool {
642    stat("/dev/syd/sandbox/truncate?") == 0
643}
644
645/// Enable truncate sandboxing.
646///
647/// Returns 0 on success, negated errno on failure.
648#[no_mangle]
649pub extern "C" fn syd_enable_truncate() -> c_int {
650    stat("/dev/syd/sandbox/truncate:on")
651}
652
653/// Disable truncate sandboxing.
654///
655/// Returns 0 on success, negated errno on failure.
656#[no_mangle]
657pub extern "C" fn syd_disable_truncate() -> c_int {
658    stat("/dev/syd/sandbox/truncate:off")
659}
660
661/// Checks if chdir sandboxing is enabled.
662///
663/// Returns true if chdir sandboxing is enabled, false otherwise.
664#[no_mangle]
665pub extern "C" fn syd_enabled_chdir() -> bool {
666    stat("/dev/syd/sandbox/chdir?") == 0
667}
668
669/// Enable chdir sandboxing.
670///
671/// Returns 0 on success, negated errno on failure.
672#[no_mangle]
673pub extern "C" fn syd_enable_chdir() -> c_int {
674    stat("/dev/syd/sandbox/chdir:on")
675}
676
677/// Disable chdir sandboxing.
678///
679/// Returns 0 on success, negated errno on failure.
680#[no_mangle]
681pub extern "C" fn syd_disable_chdir() -> c_int {
682    stat("/dev/syd/sandbox/chdir:off")
683}
684
685/// Checks if readdir sandboxing is enabled.
686///
687/// Returns true if readdir sandboxing is enabled, false otherwise.
688#[no_mangle]
689pub extern "C" fn syd_enabled_readdir() -> bool {
690    stat("/dev/syd/sandbox/readdir?") == 0
691}
692
693/// Enable readdir sandboxing.
694///
695/// Returns 0 on success, negated errno on failure.
696#[no_mangle]
697pub extern "C" fn syd_enable_readdir() -> c_int {
698    stat("/dev/syd/sandbox/readdir:on")
699}
700
701/// Disable readdir sandboxing.
702///
703/// Returns 0 on success, negated errno on failure.
704#[no_mangle]
705pub extern "C" fn syd_disable_readdir() -> c_int {
706    stat("/dev/syd/sandbox/readdir:off")
707}
708
709/// Checks if mkdir sandboxing is enabled.
710///
711/// Returns true if mkdir sandboxing is enabled, false otherwise.
712#[no_mangle]
713pub extern "C" fn syd_enabled_mkdir() -> bool {
714    stat("/dev/syd/sandbox/mkdir?") == 0
715}
716
717/// Enable mkdir sandboxing.
718///
719/// Returns 0 on success, negated errno on failure.
720#[no_mangle]
721pub extern "C" fn syd_enable_mkdir() -> c_int {
722    stat("/dev/syd/sandbox/mkdir:on")
723}
724
725/// Disable mkdir sandboxing.
726///
727/// Returns 0 on success, negated errno on failure.
728#[no_mangle]
729pub extern "C" fn syd_disable_mkdir() -> c_int {
730    stat("/dev/syd/sandbox/mkdir:off")
731}
732
733/// Checks if rmdir sandboxing is enabled.
734///
735/// Returns true if rmdir sandboxing is enabled, false otherwise.
736#[no_mangle]
737pub extern "C" fn syd_enabled_rmdir() -> bool {
738    stat("/dev/syd/sandbox/rmdir?") == 0
739}
740
741/// Enable rmdir sandboxing.
742///
743/// Returns 0 on success, negated errno on failure.
744#[no_mangle]
745pub extern "C" fn syd_enable_rmdir() -> c_int {
746    stat("/dev/syd/sandbox/rmdir:on")
747}
748
749/// Disable rmdir sandboxing.
750///
751/// Returns 0 on success, negated errno on failure.
752#[no_mangle]
753pub extern "C" fn syd_disable_rmdir() -> c_int {
754    stat("/dev/syd/sandbox/rmdir:off")
755}
756
757/// Checks if chown sandboxing is enabled.
758///
759/// Returns true if chown sandboxing is enabled, false otherwise.
760#[no_mangle]
761pub extern "C" fn syd_enabled_chown() -> bool {
762    stat("/dev/syd/sandbox/chown?") == 0
763}
764
765/// Enable chown sandboxing.
766///
767/// Returns 0 on success, negated errno on failure.
768#[no_mangle]
769pub extern "C" fn syd_enable_chown() -> c_int {
770    stat("/dev/syd/sandbox/chown:on")
771}
772
773/// Disable chown sandboxing.
774///
775/// Returns 0 on success, negated errno on failure.
776#[no_mangle]
777pub extern "C" fn syd_disable_chown() -> c_int {
778    stat("/dev/syd/sandbox/chown:off")
779}
780
781/// Checks if chgrp sandboxing is enabled.
782///
783/// Returns true if chgrp sandboxing is enabled, false otherwise.
784#[no_mangle]
785pub extern "C" fn syd_enabled_chgrp() -> bool {
786    stat("/dev/syd/sandbox/chgrp?") == 0
787}
788
789/// Enable chgrp sandboxing.
790///
791/// Returns 0 on success, negated errno on failure.
792#[no_mangle]
793pub extern "C" fn syd_enable_chgrp() -> c_int {
794    stat("/dev/syd/sandbox/chgrp:on")
795}
796
797/// Disable chgrp sandboxing.
798///
799/// Returns 0 on success, negated errno on failure.
800#[no_mangle]
801pub extern "C" fn syd_disable_chgrp() -> c_int {
802    stat("/dev/syd/sandbox/chgrp:off")
803}
804
805/// Checks if chmod sandboxing is enabled.
806///
807/// Returns true if chmod sandboxing is enabled, false otherwise.
808#[no_mangle]
809pub extern "C" fn syd_enabled_chmod() -> bool {
810    stat("/dev/syd/sandbox/chmod?") == 0
811}
812
813/// Enable chmod sandboxing.
814///
815/// Returns 0 on success, negated errno on failure.
816#[no_mangle]
817pub extern "C" fn syd_enable_chmod() -> c_int {
818    stat("/dev/syd/sandbox/chmod:on")
819}
820
821/// Disable chmod sandboxing.
822///
823/// Returns 0 on success, negated errno on failure.
824#[no_mangle]
825pub extern "C" fn syd_disable_chmod() -> c_int {
826    stat("/dev/syd/sandbox/chmod:off")
827}
828
829/// Checks if chattr sandboxing is enabled.
830///
831/// Returns true if chattr sandboxing is enabled, false otherwise.
832#[no_mangle]
833pub extern "C" fn syd_enabled_chattr() -> bool {
834    stat("/dev/syd/sandbox/chattr?") == 0
835}
836
837/// Enable chattr sandboxing.
838///
839/// Returns 0 on success, negated errno on failure.
840#[no_mangle]
841pub extern "C" fn syd_enable_chattr() -> c_int {
842    stat("/dev/syd/sandbox/chattr:on")
843}
844
845/// Disable chattr sandboxing.
846///
847/// Returns 0 on success, negated errno on failure.
848#[no_mangle]
849pub extern "C" fn syd_disable_chattr() -> c_int {
850    stat("/dev/syd/sandbox/chattr:off")
851}
852
853/// Checks if chroot sandboxing is enabled.
854///
855/// Returns true if chroot sandboxing is enabled, false otherwise.
856#[no_mangle]
857pub extern "C" fn syd_enabled_chroot() -> bool {
858    stat("/dev/syd/sandbox/chroot?") == 0
859}
860
861/// Enable chroot sandboxing.
862///
863/// Returns 0 on success, negated errno on failure.
864#[no_mangle]
865pub extern "C" fn syd_enable_chroot() -> c_int {
866    stat("/dev/syd/sandbox/chroot:on")
867}
868
869/// Disable chroot sandboxing.
870///
871/// Returns 0 on success, negated errno on failure.
872#[no_mangle]
873pub extern "C" fn syd_disable_chroot() -> c_int {
874    stat("/dev/syd/sandbox/chroot:off")
875}
876
877/// Checks if notify sandboxing is enabled.
878///
879/// Returns true if notify sandboxing is enabled, false otherwise.
880#[no_mangle]
881pub extern "C" fn syd_enabled_notify() -> bool {
882    stat("/dev/syd/sandbox/notify?") == 0
883}
884
885/// Enable notify sandboxing.
886///
887/// Returns 0 on success, negated errno on failure.
888#[no_mangle]
889pub extern "C" fn syd_enable_notify() -> c_int {
890    stat("/dev/syd/sandbox/notify:on")
891}
892
893/// Disable notify sandboxing.
894///
895/// Returns 0 on success, negated errno on failure.
896#[no_mangle]
897pub extern "C" fn syd_disable_notify() -> c_int {
898    stat("/dev/syd/sandbox/notify:off")
899}
900
901/// Checks if utime sandboxing is enabled.
902///
903/// Returns true if utime sandboxing is enabled, false otherwise.
904#[no_mangle]
905pub extern "C" fn syd_enabled_utime() -> bool {
906    stat("/dev/syd/sandbox/utime?") == 0
907}
908
909/// Enable utime sandboxing.
910///
911/// Returns 0 on success, negated errno on failure.
912#[no_mangle]
913pub extern "C" fn syd_enable_utime() -> c_int {
914    stat("/dev/syd/sandbox/utime:on")
915}
916
917/// Disable utime sandboxing.
918///
919/// Returns 0 on success, negated errno on failure.
920#[no_mangle]
921pub extern "C" fn syd_disable_utime() -> c_int {
922    stat("/dev/syd/sandbox/utime:off")
923}
924
925/// Checks if mkbdev sandboxing is enabled.
926///
927/// Returns true if mkbdev sandboxing is enabled, false otherwise.
928#[no_mangle]
929pub extern "C" fn syd_enabled_mkbdev() -> bool {
930    stat("/dev/syd/sandbox/mkbdev?") == 0
931}
932
933/// Enable mkbdev sandboxing.
934///
935/// Returns 0 on success, negated errno on failure.
936#[no_mangle]
937pub extern "C" fn syd_enable_mkbdev() -> c_int {
938    stat("/dev/syd/sandbox/mkbdev:on")
939}
940
941/// Disable mkbdev sandboxing.
942///
943/// Returns 0 on success, negated errno on failure.
944#[no_mangle]
945pub extern "C" fn syd_disable_mkbdev() -> c_int {
946    stat("/dev/syd/sandbox/mkbdev:off")
947}
948
949/// Checks if mkcdev sandboxing is enabled.
950///
951/// Returns true if mkcdev sandboxing is enabled, false otherwise.
952#[no_mangle]
953pub extern "C" fn syd_enabled_mkcdev() -> bool {
954    stat("/dev/syd/sandbox/mkcdev?") == 0
955}
956
957/// Enable mkcdev sandboxing.
958///
959/// Returns 0 on success, negated errno on failure.
960#[no_mangle]
961pub extern "C" fn syd_enable_mkcdev() -> c_int {
962    stat("/dev/syd/sandbox/mkcdev:on")
963}
964
965/// Disable mkcdev sandboxing.
966///
967/// Returns 0 on success, negated errno on failure.
968#[no_mangle]
969pub extern "C" fn syd_disable_mkcdev() -> c_int {
970    stat("/dev/syd/sandbox/mkcdev:off")
971}
972
973/// Checks if mkfifo sandboxing is enabled.
974///
975/// Returns true if mkfifo sandboxing is enabled, false otherwise.
976#[no_mangle]
977pub extern "C" fn syd_enabled_mkfifo() -> bool {
978    stat("/dev/syd/sandbox/mkfifo?") == 0
979}
980
981/// Enable mkfifo sandboxing.
982///
983/// Returns 0 on success, negated errno on failure.
984#[no_mangle]
985pub extern "C" fn syd_enable_mkfifo() -> c_int {
986    stat("/dev/syd/sandbox/mkfifo:on")
987}
988
989/// Disable mkfifo sandboxing.
990///
991/// Returns 0 on success, negated errno on failure.
992#[no_mangle]
993pub extern "C" fn syd_disable_mkfifo() -> c_int {
994    stat("/dev/syd/sandbox/mkfifo:off")
995}
996
997/// Checks if mktemp sandboxing is enabled.
998///
999/// Returns true if mktemp sandboxing is enabled, false otherwise.
1000#[no_mangle]
1001pub extern "C" fn syd_enabled_mktemp() -> bool {
1002    stat("/dev/syd/sandbox/mktemp?") == 0
1003}
1004
1005/// Enable mktemp sandboxing.
1006///
1007/// Returns 0 on success, negated errno on failure.
1008#[no_mangle]
1009pub extern "C" fn syd_enable_mktemp() -> c_int {
1010    stat("/dev/syd/sandbox/mktemp:on")
1011}
1012
1013/// Disable mktemp sandboxing.
1014///
1015/// Returns 0 on success, negated errno on failure.
1016#[no_mangle]
1017pub extern "C" fn syd_disable_mktemp() -> c_int {
1018    stat("/dev/syd/sandbox/mktemp:off")
1019}
1020
1021/// Checks if net sandboxing is enabled.
1022///
1023/// Returns true if net sandboxing is enabled, false otherwise.
1024#[no_mangle]
1025pub extern "C" fn syd_enabled_net() -> bool {
1026    stat("/dev/syd/sandbox/net?") == 0
1027}
1028
1029/// Enable net sandboxing.
1030///
1031/// Returns 0 on success, negated errno on failure.
1032#[no_mangle]
1033pub extern "C" fn syd_enable_net() -> c_int {
1034    stat("/dev/syd/sandbox/net:on")
1035}
1036
1037/// Disable net sandboxing.
1038///
1039/// Returns 0 on success, negated errno on failure.
1040#[no_mangle]
1041pub extern "C" fn syd_disable_net() -> c_int {
1042    stat("/dev/syd/sandbox/net:off")
1043}
1044
1045/// Checks if memory sandboxing is enabled.
1046///
1047/// Returns true if memory sandboxing is enabled, false otherwise.
1048#[no_mangle]
1049pub extern "C" fn syd_enabled_mem() -> bool {
1050    stat("/dev/syd/sandbox/mem?") == 0
1051}
1052
1053/// Enable memory sandboxing.
1054///
1055/// Returns 0 on success, negated errno on failure.
1056#[no_mangle]
1057pub extern "C" fn syd_enable_mem() -> c_int {
1058    stat("/dev/syd/sandbox/mem:on")
1059}
1060
1061/// Disable memory sandboxing.
1062///
1063/// Returns 0 on success, negated errno on failure.
1064#[no_mangle]
1065pub extern "C" fn syd_disable_mem() -> c_int {
1066    stat("/dev/syd/sandbox/mem:off")
1067}
1068
1069/// Checks if PID sandboxing is enabled.
1070///
1071/// Returns true if PID sandboxing is enabled, false otherwise.
1072#[no_mangle]
1073pub extern "C" fn syd_enabled_pid() -> bool {
1074    stat("/dev/syd/sandbox/pid?") == 0
1075}
1076
1077/// Enable PID sandboxing.
1078///
1079/// Returns 0 on success, negated errno on failure.
1080#[no_mangle]
1081pub extern "C" fn syd_enable_pid() -> c_int {
1082    stat("/dev/syd/sandbox/pid:on")
1083}
1084
1085/// Disable PID sandboxing.
1086///
1087/// Returns 0 on success, negated errno on failure.
1088#[no_mangle]
1089pub extern "C" fn syd_disable_pid() -> c_int {
1090    stat("/dev/syd/sandbox/pid:off")
1091}
1092
1093/// Checks if lock sandboxing is enabled.
1094///
1095/// Returns true if lock sandboxing is enabled, false otherwise.
1096#[no_mangle]
1097pub extern "C" fn syd_enabled_lock() -> bool {
1098    stat("/dev/syd/sandbox/lock?") == 0
1099}
1100
1101/// Checks if crypt sandboxing is enabled.
1102///
1103/// Returns true if crypt sandboxing is enabled, false otherwise.
1104#[no_mangle]
1105pub extern "C" fn syd_enabled_crypt() -> bool {
1106    stat("/dev/syd/sandbox/crypt?") == 0
1107}
1108
1109/// Checks if proxy sandboxing is enabled.
1110///
1111/// Returns true if proxy sandboxing is enabled, false otherwise.
1112#[no_mangle]
1113pub extern "C" fn syd_enabled_proxy() -> bool {
1114    stat("/dev/syd/sandbox/proxy?") == 0
1115}
1116
1117/// Checks if force sandboxing is enabled.
1118///
1119/// Returns true if force sandboxing is enabled, false otherwise.
1120#[no_mangle]
1121pub extern "C" fn syd_enabled_force() -> bool {
1122    stat("/dev/syd/sandbox/force?") == 0
1123}
1124
1125/// Enable force sandboxing.
1126///
1127/// Returns 0 on success, negated errno on failure.
1128#[no_mangle]
1129pub extern "C" fn syd_enable_force() -> c_int {
1130    stat("/dev/syd/sandbox/force:on")
1131}
1132
1133/// Disable force sandboxing.
1134///
1135/// Returns 0 on success, negated errno on failure.
1136#[no_mangle]
1137pub extern "C" fn syd_disable_force() -> c_int {
1138    stat("/dev/syd/sandbox/force:off")
1139}
1140
1141/// Checks if TPE sandboxing is enabled.
1142///
1143/// Returns true if TPE sandboxing is enabled, false otherwise.
1144#[no_mangle]
1145pub extern "C" fn syd_enabled_tpe() -> bool {
1146    stat("/dev/syd/sandbox/tpe?") == 0
1147}
1148
1149/// Enable TPE sandboxing.
1150///
1151/// Returns 0 on success, negated errno on failure.
1152#[no_mangle]
1153pub extern "C" fn syd_enable_tpe() -> c_int {
1154    stat("/dev/syd/sandbox/tpe:on")
1155}
1156
1157/// Disable TPE sandboxing.
1158///
1159/// Returns 0 on success, negated errno on failure.
1160#[no_mangle]
1161pub extern "C" fn syd_disable_tpe() -> c_int {
1162    stat("/dev/syd/sandbox/tpe:off")
1163}
1164
1165/// Set the default action for Filesystem sandboxing.
1166#[no_mangle]
1167pub extern "C" fn syd_default_fs(action: action_t) -> c_int {
1168    // Convert action_t enum to corresponding action string.
1169    let action = match Action::try_from(action) {
1170        Ok(action) => action,
1171        Err(_) => return -EINVAL,
1172    };
1173    stat(&format!("/dev/syd/default/fs:{action}"))
1174}
1175
1176/// Set the default action for Walk Sandboxing.
1177#[no_mangle]
1178pub extern "C" fn syd_default_walk(action: action_t) -> c_int {
1179    // Convert action_t enum to corresponding action string.
1180    let action = match Action::try_from(action) {
1181        Ok(action) => action,
1182        Err(_) => return -EINVAL,
1183    };
1184    stat(&format!("/dev/syd/default/walk:{action}"))
1185}
1186
1187/// Set the default action for Stat Sandboxing.
1188#[no_mangle]
1189pub extern "C" fn syd_default_stat(action: action_t) -> c_int {
1190    // Convert action_t enum to corresponding action string.
1191    let action = match Action::try_from(action) {
1192        Ok(action) => action,
1193        Err(_) => return -EINVAL,
1194    };
1195    stat(&format!("/dev/syd/default/stat:{action}"))
1196}
1197
1198/// Set the default action for Read Sandboxing.
1199#[no_mangle]
1200pub extern "C" fn syd_default_read(action: action_t) -> c_int {
1201    // Convert action_t enum to corresponding action string.
1202    let action = match Action::try_from(action) {
1203        Ok(action) => action,
1204        Err(_) => return -EINVAL,
1205    };
1206    stat(&format!("/dev/syd/default/read:{action}"))
1207}
1208
1209/// Set the default action for Write Sandboxing.
1210#[no_mangle]
1211pub extern "C" fn syd_default_write(action: action_t) -> c_int {
1212    // Convert action_t enum to corresponding action string.
1213    let action = match Action::try_from(action) {
1214        Ok(action) => action,
1215        Err(_) => return -EINVAL,
1216    };
1217    stat(&format!("/dev/syd/default/write:{action}"))
1218}
1219
1220/// Set the default action for Exec Sandboxing.
1221#[no_mangle]
1222pub extern "C" fn syd_default_exec(action: action_t) -> c_int {
1223    // Convert action_t enum to corresponding action string.
1224    let action = match Action::try_from(action) {
1225        Ok(action) => action,
1226        Err(_) => return -EINVAL,
1227    };
1228    stat(&format!("/dev/syd/default/exec:{action}"))
1229}
1230
1231/// Set the default action for Ioctl Sandboxing.
1232#[no_mangle]
1233pub extern "C" fn syd_default_ioctl(action: action_t) -> c_int {
1234    // Convert action_t enum to corresponding action string.
1235    let action = match Action::try_from(action) {
1236        Ok(action) => action,
1237        Err(_) => return -EINVAL,
1238    };
1239    stat(&format!("/dev/syd/default/ioctl:{action}"))
1240}
1241
1242/// Set the default action for Create Sandboxing.
1243#[no_mangle]
1244pub extern "C" fn syd_default_create(action: action_t) -> c_int {
1245    // Convert action_t enum to corresponding action string.
1246    let action = match Action::try_from(action) {
1247        Ok(action) => action,
1248        Err(_) => return -EINVAL,
1249    };
1250    stat(&format!("/dev/syd/default/create:{action}"))
1251}
1252
1253/// Set the default action for Delete Sandboxing.
1254#[no_mangle]
1255pub extern "C" fn syd_default_delete(action: action_t) -> c_int {
1256    // Convert action_t enum to corresponding action string.
1257    let action = match Action::try_from(action) {
1258        Ok(action) => action,
1259        Err(_) => return -EINVAL,
1260    };
1261    stat(&format!("/dev/syd/default/delete:{action}"))
1262}
1263
1264/// Set the default action for Rename Sandboxing.
1265#[no_mangle]
1266pub extern "C" fn syd_default_rename(action: action_t) -> c_int {
1267    // Convert action_t enum to corresponding action string.
1268    let action = match Action::try_from(action) {
1269        Ok(action) => action,
1270        Err(_) => return -EINVAL,
1271    };
1272    stat(&format!("/dev/syd/default/rename:{action}"))
1273}
1274
1275/// Set the default action for Symlink Sandboxing.
1276#[no_mangle]
1277pub extern "C" fn syd_default_symlink(action: action_t) -> c_int {
1278    // Convert action_t enum to corresponding action string.
1279    let action = match Action::try_from(action) {
1280        Ok(action) => action,
1281        Err(_) => return -EINVAL,
1282    };
1283    stat(&format!("/dev/syd/default/symlink:{action}"))
1284}
1285
1286/// Set the default action for Truncate Sandboxing.
1287#[no_mangle]
1288pub extern "C" fn syd_default_truncate(action: action_t) -> c_int {
1289    // Convert action_t enum to corresponding action string.
1290    let action = match Action::try_from(action) {
1291        Ok(action) => action,
1292        Err(_) => return -EINVAL,
1293    };
1294    stat(&format!("/dev/syd/default/truncate:{action}"))
1295}
1296
1297/// Set the default action for Chdir Sandboxing.
1298#[no_mangle]
1299pub extern "C" fn syd_default_chdir(action: action_t) -> c_int {
1300    // Convert action_t enum to corresponding action string.
1301    let action = match Action::try_from(action) {
1302        Ok(action) => action,
1303        Err(_) => return -EINVAL,
1304    };
1305    stat(&format!("/dev/syd/default/chdir:{action}"))
1306}
1307
1308/// Set the default action for Readdir Sandboxing.
1309#[no_mangle]
1310pub extern "C" fn syd_default_readdir(action: action_t) -> c_int {
1311    // Convert action_t enum to corresponding action string.
1312    let action = match Action::try_from(action) {
1313        Ok(action) => action,
1314        Err(_) => return -EINVAL,
1315    };
1316    stat(&format!("/dev/syd/default/readdir:{action}"))
1317}
1318
1319/// Set the default action for Mkdir Sandboxing.
1320#[no_mangle]
1321pub extern "C" fn syd_default_mkdir(action: action_t) -> c_int {
1322    // Convert action_t enum to corresponding action string.
1323    let action = match Action::try_from(action) {
1324        Ok(action) => action,
1325        Err(_) => return -EINVAL,
1326    };
1327    stat(&format!("/dev/syd/default/mkdir:{action}"))
1328}
1329
1330/// Set the default action for Rmdir Sandboxing.
1331#[no_mangle]
1332pub extern "C" fn syd_default_rmdir(action: action_t) -> c_int {
1333    // Convert action_t enum to corresponding action string.
1334    let action = match Action::try_from(action) {
1335        Ok(action) => action,
1336        Err(_) => return -EINVAL,
1337    };
1338    stat(&format!("/dev/syd/default/rmdir:{action}"))
1339}
1340
1341/// Set the default action for Chown Sandboxing.
1342#[no_mangle]
1343pub extern "C" fn syd_default_chown(action: action_t) -> c_int {
1344    // Convert action_t enum to corresponding action string.
1345    let action = match Action::try_from(action) {
1346        Ok(action) => action,
1347        Err(_) => return -EINVAL,
1348    };
1349    stat(&format!("/dev/syd/default/chown:{action}"))
1350}
1351
1352/// Set the default action for Chgrp Sandboxing.
1353#[no_mangle]
1354pub extern "C" fn syd_default_chgrp(action: action_t) -> c_int {
1355    // Convert action_t enum to corresponding action string.
1356    let action = match Action::try_from(action) {
1357        Ok(action) => action,
1358        Err(_) => return -EINVAL,
1359    };
1360    stat(&format!("/dev/syd/default/chgrp:{action}"))
1361}
1362
1363/// Set the default action for Chmod Sandboxing.
1364#[no_mangle]
1365pub extern "C" fn syd_default_chmod(action: action_t) -> c_int {
1366    // Convert action_t enum to corresponding action string.
1367    let action = match Action::try_from(action) {
1368        Ok(action) => action,
1369        Err(_) => return -EINVAL,
1370    };
1371    stat(&format!("/dev/syd/default/chmod:{action}"))
1372}
1373
1374/// Set the default action for Chattr Sandboxing.
1375#[no_mangle]
1376pub extern "C" fn syd_default_chattr(action: action_t) -> c_int {
1377    // Convert action_t enum to corresponding action string.
1378    let action = match Action::try_from(action) {
1379        Ok(action) => action,
1380        Err(_) => return -EINVAL,
1381    };
1382    stat(&format!("/dev/syd/default/chattr:{action}"))
1383}
1384
1385/// Set the default action for Chroot Sandboxing.
1386#[no_mangle]
1387pub extern "C" fn syd_default_chroot(action: action_t) -> c_int {
1388    // Convert action_t enum to corresponding action string.
1389    let action = match Action::try_from(action) {
1390        Ok(action) => action,
1391        Err(_) => return -EINVAL,
1392    };
1393    stat(&format!("/dev/syd/default/chroot:{action}"))
1394}
1395
1396/// Set the default action for Notify Sandboxing.
1397#[no_mangle]
1398pub extern "C" fn syd_default_notify(action: action_t) -> c_int {
1399    // Convert action_t enum to corresponding action string.
1400    let action = match Action::try_from(action) {
1401        Ok(action) => action,
1402        Err(_) => return -EINVAL,
1403    };
1404    stat(&format!("/dev/syd/default/notify:{action}"))
1405}
1406
1407/// Set the default action for Utime Sandboxing.
1408#[no_mangle]
1409pub extern "C" fn syd_default_utime(action: action_t) -> c_int {
1410    // Convert action_t enum to corresponding action string.
1411    let action = match Action::try_from(action) {
1412        Ok(action) => action,
1413        Err(_) => return -EINVAL,
1414    };
1415    stat(&format!("/dev/syd/default/utime:{action}"))
1416}
1417
1418/// Set the default action for Mkbdev Sandboxing.
1419#[no_mangle]
1420pub extern "C" fn syd_default_mkbdev(action: action_t) -> c_int {
1421    // Convert action_t enum to corresponding action string.
1422    let action = match Action::try_from(action) {
1423        Ok(action) => action,
1424        Err(_) => return -EINVAL,
1425    };
1426    stat(&format!("/dev/syd/default/mkbdev:{action}"))
1427}
1428
1429/// Set the default action for Mkcdev Sandboxing.
1430#[no_mangle]
1431pub extern "C" fn syd_default_mkcdev(action: action_t) -> c_int {
1432    // Convert action_t enum to corresponding action string.
1433    let action = match Action::try_from(action) {
1434        Ok(action) => action,
1435        Err(_) => return -EINVAL,
1436    };
1437    stat(&format!("/dev/syd/default/mkcdev:{action}"))
1438}
1439
1440/// Set the default action for Mkfifo Sandboxing.
1441#[no_mangle]
1442pub extern "C" fn syd_default_mkfifo(action: action_t) -> c_int {
1443    // Convert action_t enum to corresponding action string.
1444    let action = match Action::try_from(action) {
1445        Ok(action) => action,
1446        Err(_) => return -EINVAL,
1447    };
1448    stat(&format!("/dev/syd/default/mkfifo:{action}"))
1449}
1450
1451/// Set the default action for Mktemp Sandboxing.
1452#[no_mangle]
1453pub extern "C" fn syd_default_mktemp(action: action_t) -> c_int {
1454    // Convert action_t enum to corresponding action string.
1455    let action = match Action::try_from(action) {
1456        Ok(action) => action,
1457        Err(_) => return -EINVAL,
1458    };
1459    stat(&format!("/dev/syd/default/mktemp:{action}"))
1460}
1461
1462/// Set the default action for Network Sandboxing.
1463#[no_mangle]
1464pub extern "C" fn syd_default_net(action: action_t) -> c_int {
1465    // Convert action_t enum to corresponding action string.
1466    let action = match Action::try_from(action) {
1467        Ok(action) => action,
1468        Err(_) => return -EINVAL,
1469    };
1470    stat(&format!("/dev/syd/default/net:{action}"))
1471}
1472
1473/// Set the default action for IP blocklist violations.
1474#[no_mangle]
1475pub extern "C" fn syd_default_block(action: action_t) -> c_int {
1476    // Convert action_t enum to corresponding action string.
1477    let action = match Action::try_from(action) {
1478        Ok(action) => action,
1479        Err(_) => return -EINVAL,
1480    };
1481    stat(&format!("/dev/syd/default/block:{action}"))
1482}
1483
1484/// Set the default action for Memory Sandboxing.
1485#[no_mangle]
1486pub extern "C" fn syd_default_mem(action: action_t) -> c_int {
1487    // Convert action_t enum to corresponding action string.
1488    let action = match Action::try_from(action) {
1489        Ok(action) => action,
1490        Err(_) => return -EINVAL,
1491    };
1492    stat(&format!("/dev/syd/default/mem:{action}"))
1493}
1494
1495/// Set the default action for PID Sandboxing.
1496#[no_mangle]
1497pub extern "C" fn syd_default_pid(action: action_t) -> c_int {
1498    // Convert action_t enum to corresponding action string.
1499    let action = match Action::try_from(action) {
1500        Ok(action) => action,
1501        Err(_) => return -EINVAL,
1502    };
1503    stat(&format!("/dev/syd/default/pid:{action}"))
1504}
1505
1506/// Set the default action for Force Sandboxing.
1507#[no_mangle]
1508pub extern "C" fn syd_default_force(action: action_t) -> c_int {
1509    // Convert action_t enum to corresponding action string.
1510    let action = match Action::try_from(action) {
1511        Ok(action) => action,
1512        Err(_) => return -EINVAL,
1513    };
1514    stat(&format!("/dev/syd/default/force:{action}"))
1515}
1516
1517/// Set the default action for SegvGuard
1518#[no_mangle]
1519pub extern "C" fn syd_default_segvguard(action: action_t) -> c_int {
1520    // Convert action_t enum to corresponding action string.
1521    let action = match Action::try_from(action) {
1522        Ok(action) => action,
1523        Err(_) => return -EINVAL,
1524    };
1525    stat(&format!("/dev/syd/default/segvguard:{action}"))
1526}
1527
1528/// Set the default action for TPE Sandboxing.
1529#[no_mangle]
1530pub extern "C" fn syd_default_tpe(action: action_t) -> c_int {
1531    // Convert action_t enum to corresponding action string.
1532    let action = match Action::try_from(action) {
1533        Ok(action) => action,
1534        Err(_) => return -EINVAL,
1535    };
1536    stat(&format!("/dev/syd/default/tpe:{action}"))
1537}
1538
1539/// Adds a request to the _ioctl_(2) denylist.
1540#[no_mangle]
1541pub extern "C" fn syd_ioctl_deny(request: u64) -> c_int {
1542    stat(&format!("/dev/syd/deny/ioctl+{request}"))
1543}
1544
1545/// Adds an entry to the Integrity Force map for Force Sandboxing.
1546///
1547/// # Safety
1548///
1549/// This function is marked `unsafe` because it dereferences raw
1550/// pointers, which is inherently unsafe in Rust.
1551///
1552/// The caller must ensure the following conditions are met to safely
1553/// use this function:
1554///
1555/// 1. The `path` pointer must point to a valid, null-terminated C-style
1556///    string.
1557/// 2. The `hash` pointer must point to a valid, null-terminated C-style
1558///    string.
1559#[no_mangle]
1560pub unsafe extern "C" fn syd_force_add(
1561    path: *const c_char,
1562    hash: *const c_char,
1563    action: action_t,
1564) -> c_int {
1565    // Convert action_t enum to corresponding action string.
1566    let action = match Action::try_from(action) {
1567        Ok(action) => action,
1568        Err(_) => return -EINVAL,
1569    };
1570
1571    if path.is_null() || hash.is_null() {
1572        return -EFAULT;
1573    }
1574
1575    // SAFETY: Trust that `path` and `hash` are a null-terminated strings.
1576    let path = unsafe { CStr::from_ptr(path) };
1577    // SAFETY: ditto
1578    let hash = unsafe { CStr::from_ptr(hash) };
1579    let path = match path.to_str() {
1580        Ok(s) => s,
1581        Err(_) => return -EINVAL,
1582    };
1583    let hash = match hash.to_str() {
1584        Ok(s) => s,
1585        Err(_) => return -EINVAL,
1586    };
1587
1588    // Call the stat function with the formatted string.
1589    stat(format!("/dev/syd/force+{path}:{hash}:{action}"))
1590}
1591
1592/// Removes an entry from the Integrity Force map for Force Sandboxing.
1593/// # Safety
1594///
1595/// This function is marked `unsafe` because it dereferences raw
1596/// pointers, which is inherently unsafe in Rust.
1597///
1598/// The caller must ensure the following conditions are met to safely
1599/// use this function:
1600///
1601/// 1. The `path` pointer must point to a valid, null-terminated C-style
1602///    string.
1603#[no_mangle]
1604pub unsafe extern "C" fn syd_force_del(path: *const c_char) -> c_int {
1605    if path.is_null() {
1606        return -EFAULT;
1607    }
1608
1609    // SAFETY: Trust that `path` is a null-terminated string.
1610    let path = unsafe { CStr::from_ptr(path) };
1611    let path = match path.to_str() {
1612        Ok(s) => s,
1613        Err(_) => return -EINVAL,
1614    };
1615
1616    // Call the stat function with the formatted string.
1617    stat(format!("/dev/syd/force-{path}"))
1618}
1619
1620/// Clears the Integrity Force map for Force Sandboxing.
1621#[no_mangle]
1622pub extern "C" fn syd_force_clr() -> c_int {
1623    stat("/dev/syd/force^")
1624}
1625
1626/// Adds to the given actionlist of Filesystem sandboxing.
1627///
1628/// Returns 0 on success, negated errno on failure.
1629#[no_mangle]
1630pub extern "C" fn syd_fs_add(action: action_t, name: *const c_char) -> c_int {
1631    // Convert action_t enum to corresponding action string.
1632    let action = match Action::try_from(action) {
1633        Ok(action) => action,
1634        Err(_) => return -EINVAL,
1635    };
1636
1637    // Call magic function with add operator.
1638    esyd(&format!("{action}/fs"), name, b'+')
1639}
1640
1641/// Removes the first instance from the end of the given actionlist of
1642/// Filesystem sandboxing.
1643///
1644/// Returns 0 on success, negated errno on failure.
1645#[no_mangle]
1646pub extern "C" fn syd_fs_del(action: action_t, name: *const c_char) -> c_int {
1647    // Convert action_t enum to corresponding action string.
1648    let action = match Action::try_from(action) {
1649        Ok(action) => action,
1650        Err(_) => return -EINVAL,
1651    };
1652
1653    // Call magic function with del operator.
1654    esyd(&format!("{action}/fs"), name, b'-')
1655}
1656
1657/// Removes all matching patterns from the given actionlist of Filesystem sandboxing.
1658///
1659/// Returns 0 on success, negated errno on failure.
1660#[no_mangle]
1661pub extern "C" fn syd_fs_rem(action: action_t, name: *const c_char) -> c_int {
1662    // Convert action_t enum to corresponding action string.
1663    let action = match Action::try_from(action) {
1664        Ok(action) => action,
1665        Err(_) => return -EINVAL,
1666    };
1667
1668    // Call magic function with rem operator.
1669    esyd(&format!("{action}/fs"), name, b'^')
1670}
1671
1672/// Adds to the given actionlist of walk sandboxing.
1673///
1674/// Returns 0 on success, negated errno on failure.
1675#[no_mangle]
1676pub extern "C" fn syd_walk_add(action: action_t, glob: *const c_char) -> c_int {
1677    // Convert action_t enum to corresponding action string.
1678    let action = match Action::try_from(action) {
1679        Ok(action) => action,
1680        Err(_) => return -EINVAL,
1681    };
1682
1683    // Call magic function with add operator.
1684    esyd(&format!("{action}/walk"), glob, b'+')
1685}
1686
1687/// Removes the first instance from the end of the given actionlist of
1688/// walk sandboxing.
1689///
1690/// Returns 0 on success, negated errno on failure.
1691#[no_mangle]
1692pub extern "C" fn syd_walk_del(action: action_t, glob: *const c_char) -> c_int {
1693    // Convert action_t enum to corresponding action string.
1694    let action = match Action::try_from(action) {
1695        Ok(action) => action,
1696        Err(_) => return -EINVAL,
1697    };
1698
1699    // Call magic function with del operator.
1700    esyd(&format!("{action}/walk"), glob, b'-')
1701}
1702
1703/// Removes all matching patterns from the given actionlist of walk sandboxing.
1704///
1705/// Returns 0 on success, negated errno on failure.
1706#[no_mangle]
1707pub extern "C" fn syd_walk_rem(action: action_t, glob: *const c_char) -> c_int {
1708    // Convert action_t enum to corresponding action string.
1709    let action = match Action::try_from(action) {
1710        Ok(action) => action,
1711        Err(_) => return -EINVAL,
1712    };
1713
1714    // Call magic function with rem operator.
1715    esyd(&format!("{action}/walk"), glob, b'^')
1716}
1717
1718/// Adds to the given actionlist of stat sandboxing.
1719///
1720/// Returns 0 on success, negated errno on failure.
1721#[no_mangle]
1722pub extern "C" fn syd_stat_add(action: action_t, glob: *const c_char) -> c_int {
1723    // Convert action_t enum to corresponding action string.
1724    let action = match Action::try_from(action) {
1725        Ok(action) => action,
1726        Err(_) => return -EINVAL,
1727    };
1728
1729    // Call magic function with add operator.
1730    esyd(&format!("{action}/stat"), glob, b'+')
1731}
1732
1733/// Removes the first instance from the end of the given actionlist of
1734/// stat sandboxing.
1735///
1736/// Returns 0 on success, negated errno on failure.
1737#[no_mangle]
1738pub extern "C" fn syd_stat_del(action: action_t, glob: *const c_char) -> c_int {
1739    // Convert action_t enum to corresponding action string.
1740    let action = match Action::try_from(action) {
1741        Ok(action) => action,
1742        Err(_) => return -EINVAL,
1743    };
1744
1745    // Call magic function with del operator.
1746    esyd(&format!("{action}/stat"), glob, b'-')
1747}
1748
1749/// Removes all matching patterns from the given actionlist of stat sandboxing.
1750///
1751/// Returns 0 on success, negated errno on failure.
1752#[no_mangle]
1753pub extern "C" fn syd_stat_rem(action: action_t, glob: *const c_char) -> c_int {
1754    // Convert action_t enum to corresponding action string.
1755    let action = match Action::try_from(action) {
1756        Ok(action) => action,
1757        Err(_) => return -EINVAL,
1758    };
1759
1760    // Call magic function with rem operator.
1761    esyd(&format!("{action}/stat"), glob, b'^')
1762}
1763
1764/// Adds to the given actionlist of read sandboxing.
1765///
1766/// Returns 0 on success, negated errno on failure.
1767#[no_mangle]
1768pub extern "C" fn syd_read_add(action: action_t, glob: *const c_char) -> c_int {
1769    // Convert action_t enum to corresponding action string.
1770    let action = match Action::try_from(action) {
1771        Ok(action) => action,
1772        Err(_) => return -EINVAL,
1773    };
1774
1775    // Call magic function with add operator.
1776    esyd(&format!("{action}/read"), glob, b'+')
1777}
1778
1779/// Removes the first instance from the end of the given actionlist of
1780/// read sandboxing.
1781///
1782/// Returns 0 on success, negated errno on failure.
1783#[no_mangle]
1784pub extern "C" fn syd_read_del(action: action_t, glob: *const c_char) -> c_int {
1785    // Convert action_t enum to corresponding action string.
1786    let action = match Action::try_from(action) {
1787        Ok(action) => action,
1788        Err(_) => return -EINVAL,
1789    };
1790
1791    // Call magic function with del operator.
1792    esyd(&format!("{action}/read"), glob, b'-')
1793}
1794
1795/// Removes all matching patterns from the given actionlist of read sandboxing.
1796///
1797/// Returns 0 on success, negated errno on failure.
1798#[no_mangle]
1799pub extern "C" fn syd_read_rem(action: action_t, glob: *const c_char) -> c_int {
1800    // Convert action_t enum to corresponding action string.
1801    let action = match Action::try_from(action) {
1802        Ok(action) => action,
1803        Err(_) => return -EINVAL,
1804    };
1805
1806    // Call magic function with rem operator.
1807    esyd(&format!("{action}/read"), glob, b'^')
1808}
1809
1810/// Adds to the given actionlist of write sandboxing.
1811///
1812/// Returns 0 on success, negated errno on failure.
1813#[no_mangle]
1814pub extern "C" fn syd_write_add(action: action_t, glob: *const c_char) -> c_int {
1815    // Convert action_t enum to corresponding action string.
1816    let action = match Action::try_from(action) {
1817        Ok(action) => action,
1818        Err(_) => return -EINVAL,
1819    };
1820
1821    // Call magic function with add operator.
1822    esyd(&format!("{action}/write"), glob, b'+')
1823}
1824
1825/// Removes the first instance from the end of the given actionlist of
1826/// write sandboxing.
1827///
1828/// Returns 0 on success, negated errno on failure.
1829#[no_mangle]
1830pub extern "C" fn syd_write_del(action: action_t, glob: *const c_char) -> c_int {
1831    // Convert action_t enum to corresponding action string.
1832    let action = match Action::try_from(action) {
1833        Ok(action) => action,
1834        Err(_) => return -EINVAL,
1835    };
1836
1837    // Call magic function with del operator.
1838    esyd(&format!("{action}/write"), glob, b'-')
1839}
1840
1841/// Removes all matching patterns from the given actionlist of write sandboxing.
1842///
1843/// Returns 0 on success, negated errno on failure.
1844#[no_mangle]
1845pub extern "C" fn syd_write_rem(action: action_t, glob: *const c_char) -> c_int {
1846    // Convert action_t enum to corresponding action string.
1847    let action = match Action::try_from(action) {
1848        Ok(action) => action,
1849        Err(_) => return -EINVAL,
1850    };
1851
1852    // Call magic function with rem operator.
1853    esyd(&format!("{action}/write"), glob, b'^')
1854}
1855
1856/// Adds to the given actionlist of exec sandboxing.
1857///
1858/// Returns 0 on success, negated errno on failure.
1859#[no_mangle]
1860pub extern "C" fn syd_exec_add(action: action_t, glob: *const c_char) -> c_int {
1861    // Convert action_t enum to corresponding action string.
1862    let action = match Action::try_from(action) {
1863        Ok(action) => action,
1864        Err(_) => return -EINVAL,
1865    };
1866
1867    // Call magic function with add operator.
1868    esyd(&format!("{action}/exec"), glob, b'+')
1869}
1870
1871/// Removes the first instance from the end of the given actionlist of
1872/// exec sandboxing.
1873///
1874/// Returns 0 on success, negated errno on failure.
1875#[no_mangle]
1876pub extern "C" fn syd_exec_del(action: action_t, glob: *const c_char) -> c_int {
1877    // Convert action_t enum to corresponding action string.
1878    let action = match Action::try_from(action) {
1879        Ok(action) => action,
1880        Err(_) => return -EINVAL,
1881    };
1882
1883    // Call magic function with del operator.
1884    esyd(&format!("{action}/exec"), glob, b'-')
1885}
1886
1887/// Removes all matching patterns from the given actionlist of exec sandboxing.
1888///
1889/// Returns 0 on success, negated errno on failure.
1890#[no_mangle]
1891pub extern "C" fn syd_exec_rem(action: action_t, glob: *const c_char) -> c_int {
1892    // Convert action_t enum to corresponding action string.
1893    let action = match Action::try_from(action) {
1894        Ok(action) => action,
1895        Err(_) => return -EINVAL,
1896    };
1897
1898    // Call magic function with rem operator.
1899    esyd(&format!("{action}/exec"), glob, b'^')
1900}
1901
1902/// Adds to the given actionlist of create sandboxing.
1903///
1904/// Returns 0 on success, negated errno on failure.
1905#[no_mangle]
1906pub extern "C" fn syd_create_add(action: action_t, glob: *const c_char) -> c_int {
1907    // Convert action_t enum to corresponding action string.
1908    let action = match Action::try_from(action) {
1909        Ok(action) => action,
1910        Err(_) => return -EINVAL,
1911    };
1912
1913    // Call magic function with add operator.
1914    esyd(&format!("{action}/create"), glob, b'+')
1915}
1916
1917/// Removes the first instance from the end of the given actionlist of
1918/// create sandboxing.
1919///
1920/// Returns 0 on success, negated errno on failure.
1921#[no_mangle]
1922pub extern "C" fn syd_create_del(action: action_t, glob: *const c_char) -> c_int {
1923    // Convert action_t enum to corresponding action string.
1924    let action = match Action::try_from(action) {
1925        Ok(action) => action,
1926        Err(_) => return -EINVAL,
1927    };
1928
1929    // Call magic function with del operator.
1930    esyd(&format!("{action}/create"), glob, b'-')
1931}
1932
1933/// Removes all matching patterns from the given actionlist of create sandboxing.
1934///
1935/// Returns 0 on success, negated errno on failure.
1936#[no_mangle]
1937pub extern "C" fn syd_create_rem(action: action_t, glob: *const c_char) -> c_int {
1938    // Convert action_t enum to corresponding action string.
1939    let action = match Action::try_from(action) {
1940        Ok(action) => action,
1941        Err(_) => return -EINVAL,
1942    };
1943
1944    // Call magic function with rem operator.
1945    esyd(&format!("{action}/create"), glob, b'^')
1946}
1947
1948/// Adds to the given actionlist of delete sandboxing.
1949///
1950/// Returns 0 on success, negated errno on failure.
1951#[no_mangle]
1952pub extern "C" fn syd_delete_add(action: action_t, glob: *const c_char) -> c_int {
1953    // Convert action_t enum to corresponding action string.
1954    let action = match Action::try_from(action) {
1955        Ok(action) => action,
1956        Err(_) => return -EINVAL,
1957    };
1958
1959    // Call magic function with add operator.
1960    esyd(&format!("{action}/delete"), glob, b'+')
1961}
1962
1963/// Removes the first instance from the end of the given actionlist of
1964/// delete sandboxing.
1965///
1966/// Returns 0 on success, negated errno on failure.
1967#[no_mangle]
1968pub extern "C" fn syd_delete_del(action: action_t, glob: *const c_char) -> c_int {
1969    // Convert action_t enum to corresponding action string.
1970    let action = match Action::try_from(action) {
1971        Ok(action) => action,
1972        Err(_) => return -EINVAL,
1973    };
1974
1975    // Call magic function with del operator.
1976    esyd(&format!("{action}/delete"), glob, b'-')
1977}
1978
1979/// Removes all matching patterns from the given actionlist of delete sandboxing.
1980///
1981/// Returns 0 on success, negated errno on failure.
1982#[no_mangle]
1983pub extern "C" fn syd_delete_rem(action: action_t, glob: *const c_char) -> c_int {
1984    // Convert action_t enum to corresponding action string.
1985    let action = match Action::try_from(action) {
1986        Ok(action) => action,
1987        Err(_) => return -EINVAL,
1988    };
1989
1990    // Call magic function with rem operator.
1991    esyd(&format!("{action}/delete"), glob, b'^')
1992}
1993
1994/// Adds to the given actionlist of rename sandboxing.
1995///
1996/// Returns 0 on success, negated errno on failure.
1997#[no_mangle]
1998pub extern "C" fn syd_rename_add(action: action_t, glob: *const c_char) -> c_int {
1999    // Convert action_t enum to corresponding action string.
2000    let action = match Action::try_from(action) {
2001        Ok(action) => action,
2002        Err(_) => return -EINVAL,
2003    };
2004
2005    // Call magic function with add operator.
2006    esyd(&format!("{action}/rename"), glob, b'+')
2007}
2008
2009/// Removes the first instance from the end of the given actionlist of
2010/// rename sandboxing.
2011///
2012/// Returns 0 on success, negated errno on failure.
2013#[no_mangle]
2014pub extern "C" fn syd_rename_del(action: action_t, glob: *const c_char) -> c_int {
2015    // Convert action_t enum to corresponding action string.
2016    let action = match Action::try_from(action) {
2017        Ok(action) => action,
2018        Err(_) => return -EINVAL,
2019    };
2020
2021    // Call magic function with del operator.
2022    esyd(&format!("{action}/rename"), glob, b'-')
2023}
2024
2025/// Removes all matching patterns from the given actionlist of rename sandboxing.
2026///
2027/// Returns 0 on success, negated errno on failure.
2028#[no_mangle]
2029pub extern "C" fn syd_rename_rem(action: action_t, glob: *const c_char) -> c_int {
2030    // Convert action_t enum to corresponding action string.
2031    let action = match Action::try_from(action) {
2032        Ok(action) => action,
2033        Err(_) => return -EINVAL,
2034    };
2035
2036    // Call magic function with rem operator.
2037    esyd(&format!("{action}/rename"), glob, b'^')
2038}
2039
2040/// Adds to the given actionlist of symlink sandboxing.
2041///
2042/// Returns 0 on success, negated errno on failure.
2043#[no_mangle]
2044pub extern "C" fn syd_symlink_add(action: action_t, glob: *const c_char) -> c_int {
2045    // Convert action_t enum to corresponding action string.
2046    let action = match Action::try_from(action) {
2047        Ok(action) => action,
2048        Err(_) => return -EINVAL,
2049    };
2050
2051    // Call magic function with add operator.
2052    esyd(&format!("{action}/symlink"), glob, b'+')
2053}
2054
2055/// Removes the first instance from the end of the given actionlist of
2056/// symlink sandboxing.
2057///
2058/// Returns 0 on success, negated errno on failure.
2059#[no_mangle]
2060pub extern "C" fn syd_symlink_del(action: action_t, glob: *const c_char) -> c_int {
2061    // Convert action_t enum to corresponding action string.
2062    let action = match Action::try_from(action) {
2063        Ok(action) => action,
2064        Err(_) => return -EINVAL,
2065    };
2066
2067    // Call magic function with del operator.
2068    esyd(&format!("{action}/symlink"), glob, b'-')
2069}
2070
2071/// Removes all matching patterns from the given actionlist of symlink sandboxing.
2072///
2073/// Returns 0 on success, negated errno on failure.
2074#[no_mangle]
2075pub extern "C" fn syd_symlink_rem(action: action_t, glob: *const c_char) -> c_int {
2076    // Convert action_t enum to corresponding action string.
2077    let action = match Action::try_from(action) {
2078        Ok(action) => action,
2079        Err(_) => return -EINVAL,
2080    };
2081
2082    // Call magic function with rem operator.
2083    esyd(&format!("{action}/symlink"), glob, b'^')
2084}
2085
2086/// Adds to the given actionlist of truncate sandboxing.
2087///
2088/// Returns 0 on success, negated errno on failure.
2089#[no_mangle]
2090pub extern "C" fn syd_truncate_add(action: action_t, glob: *const c_char) -> c_int {
2091    // Convert action_t enum to corresponding action string.
2092    let action = match Action::try_from(action) {
2093        Ok(action) => action,
2094        Err(_) => return -EINVAL,
2095    };
2096
2097    // Call magic function with add operator.
2098    esyd(&format!("{action}/truncate"), glob, b'+')
2099}
2100
2101/// Removes the first instance from the end of the given actionlist of
2102/// truncate sandboxing.
2103///
2104/// Returns 0 on success, negated errno on failure.
2105#[no_mangle]
2106pub extern "C" fn syd_truncate_del(action: action_t, glob: *const c_char) -> c_int {
2107    // Convert action_t enum to corresponding action string.
2108    let action = match Action::try_from(action) {
2109        Ok(action) => action,
2110        Err(_) => return -EINVAL,
2111    };
2112
2113    // Call magic function with del operator.
2114    esyd(&format!("{action}/truncate"), glob, b'-')
2115}
2116
2117/// Removes all matching patterns from the given actionlist of truncate sandboxing.
2118///
2119/// Returns 0 on success, negated errno on failure.
2120#[no_mangle]
2121pub extern "C" fn syd_truncate_rem(action: action_t, glob: *const c_char) -> c_int {
2122    // Convert action_t enum to corresponding action string.
2123    let action = match Action::try_from(action) {
2124        Ok(action) => action,
2125        Err(_) => return -EINVAL,
2126    };
2127
2128    // Call magic function with rem operator.
2129    esyd(&format!("{action}/truncate"), glob, b'^')
2130}
2131
2132/// Adds to the given actionlist of chdir sandboxing.
2133///
2134/// Returns 0 on success, negated errno on failure.
2135#[no_mangle]
2136pub extern "C" fn syd_chdir_add(action: action_t, glob: *const c_char) -> c_int {
2137    // Convert action_t enum to corresponding action string.
2138    let action = match Action::try_from(action) {
2139        Ok(action) => action,
2140        Err(_) => return -EINVAL,
2141    };
2142
2143    // Call magic function with add operator.
2144    esyd(&format!("{action}/chdir"), glob, b'+')
2145}
2146
2147/// Removes the first instance from the end of the given actionlist of
2148/// chdir sandboxing.
2149///
2150/// Returns 0 on success, negated errno on failure.
2151#[no_mangle]
2152pub extern "C" fn syd_chdir_del(action: action_t, glob: *const c_char) -> c_int {
2153    // Convert action_t enum to corresponding action string.
2154    let action = match Action::try_from(action) {
2155        Ok(action) => action,
2156        Err(_) => return -EINVAL,
2157    };
2158
2159    // Call magic function with del operator.
2160    esyd(&format!("{action}/chdir"), glob, b'-')
2161}
2162
2163/// Removes all matching patterns from the given actionlist of chdir sandboxing.
2164///
2165/// Returns 0 on success, negated errno on failure.
2166#[no_mangle]
2167pub extern "C" fn syd_chdir_rem(action: action_t, glob: *const c_char) -> c_int {
2168    // Convert action_t enum to corresponding action string.
2169    let action = match Action::try_from(action) {
2170        Ok(action) => action,
2171        Err(_) => return -EINVAL,
2172    };
2173
2174    // Call magic function with rem operator.
2175    esyd(&format!("{action}/chdir"), glob, b'^')
2176}
2177
2178/// Adds to the given actionlist of readdir sandboxing.
2179///
2180/// Returns 0 on success, negated errno on failure.
2181#[no_mangle]
2182pub extern "C" fn syd_readdir_add(action: action_t, glob: *const c_char) -> c_int {
2183    // Convert action_t enum to corresponding action string.
2184    let action = match Action::try_from(action) {
2185        Ok(action) => action,
2186        Err(_) => return -EINVAL,
2187    };
2188
2189    // Call magic function with add operator.
2190    esyd(&format!("{action}/readdir"), glob, b'+')
2191}
2192
2193/// Removes the first instance from the end of the given actionlist of
2194/// readdir sandboxing.
2195///
2196/// Returns 0 on success, negated errno on failure.
2197#[no_mangle]
2198pub extern "C" fn syd_readdir_del(action: action_t, glob: *const c_char) -> c_int {
2199    // Convert action_t enum to corresponding action string.
2200    let action = match Action::try_from(action) {
2201        Ok(action) => action,
2202        Err(_) => return -EINVAL,
2203    };
2204
2205    // Call magic function with del operator.
2206    esyd(&format!("{action}/readdir"), glob, b'-')
2207}
2208
2209/// Removes all matching patterns from the given actionlist of readdir sandboxing.
2210///
2211/// Returns 0 on success, negated errno on failure.
2212#[no_mangle]
2213pub extern "C" fn syd_readdir_rem(action: action_t, glob: *const c_char) -> c_int {
2214    // Convert action_t enum to corresponding action string.
2215    let action = match Action::try_from(action) {
2216        Ok(action) => action,
2217        Err(_) => return -EINVAL,
2218    };
2219
2220    // Call magic function with del operator.
2221    esyd(&format!("{action}/readdir"), glob, b'^')
2222}
2223
2224/// Adds to the given actionlist of mkdir sandboxing.
2225///
2226/// Returns 0 on success, negated errno on failure.
2227#[no_mangle]
2228pub extern "C" fn syd_mkdir_add(action: action_t, glob: *const c_char) -> c_int {
2229    // Convert action_t enum to corresponding action string.
2230    let action = match Action::try_from(action) {
2231        Ok(action) => action,
2232        Err(_) => return -EINVAL,
2233    };
2234
2235    // Call magic function with add operator.
2236    esyd(&format!("{action}/mkdir"), glob, b'+')
2237}
2238
2239/// Removes the first instance from the end of the given actionlist of
2240/// mkdir sandboxing.
2241///
2242/// Returns 0 on success, negated errno on failure.
2243#[no_mangle]
2244pub extern "C" fn syd_mkdir_del(action: action_t, glob: *const c_char) -> c_int {
2245    // Convert action_t enum to corresponding action string.
2246    let action = match Action::try_from(action) {
2247        Ok(action) => action,
2248        Err(_) => return -EINVAL,
2249    };
2250
2251    // Call magic function with del operator.
2252    esyd(&format!("{action}/mkdir"), glob, b'-')
2253}
2254
2255/// Removes all matching patterns from the given actionlist of mkdir sandboxing.
2256///
2257/// Returns 0 on success, negated errno on failure.
2258#[no_mangle]
2259pub extern "C" fn syd_mkdir_rem(action: action_t, glob: *const c_char) -> c_int {
2260    // Convert action_t enum to corresponding action string.
2261    let action = match Action::try_from(action) {
2262        Ok(action) => action,
2263        Err(_) => return -EINVAL,
2264    };
2265
2266    // Call magic function with del operator.
2267    esyd(&format!("{action}/mkdir"), glob, b'^')
2268}
2269
2270/// Adds to the given actionlist of rmdir sandboxing.
2271///
2272/// Returns 0 on success, negated errno on failure.
2273#[no_mangle]
2274pub extern "C" fn syd_rmdir_add(action: action_t, glob: *const c_char) -> c_int {
2275    // Convert action_t enum to corresponding action string.
2276    let action = match Action::try_from(action) {
2277        Ok(action) => action,
2278        Err(_) => return -EINVAL,
2279    };
2280
2281    // Call magic function with add operator.
2282    esyd(&format!("{action}/rmdir"), glob, b'+')
2283}
2284
2285/// Removes the first instance from the end of the given actionlist of
2286/// rmdir sandboxing.
2287///
2288/// Returns 0 on success, negated errno on failure.
2289#[no_mangle]
2290pub extern "C" fn syd_rmdir_del(action: action_t, glob: *const c_char) -> c_int {
2291    // Convert action_t enum to corresponding action string.
2292    let action = match Action::try_from(action) {
2293        Ok(action) => action,
2294        Err(_) => return -EINVAL,
2295    };
2296
2297    // Call magic function with del operator.
2298    esyd(&format!("{action}/rmdir"), glob, b'-')
2299}
2300
2301/// Removes all matching patterns from the given actionlist of rmdir sandboxing.
2302///
2303/// Returns 0 on success, negated errno on failure.
2304#[no_mangle]
2305pub extern "C" fn syd_rmdir_rem(action: action_t, glob: *const c_char) -> c_int {
2306    // Convert action_t enum to corresponding action string.
2307    let action = match Action::try_from(action) {
2308        Ok(action) => action,
2309        Err(_) => return -EINVAL,
2310    };
2311
2312    // Call magic function with del operator.
2313    esyd(&format!("{action}/rmdir"), glob, b'^')
2314}
2315
2316/// Adds to the given actionlist of chown sandboxing.
2317///
2318/// Returns 0 on success, negated errno on failure.
2319#[no_mangle]
2320pub extern "C" fn syd_chown_add(action: action_t, glob: *const c_char) -> c_int {
2321    // Convert action_t enum to corresponding action string.
2322    let action = match Action::try_from(action) {
2323        Ok(action) => action,
2324        Err(_) => return -EINVAL,
2325    };
2326
2327    // Call magic function with add operator.
2328    esyd(&format!("{action}/chown"), glob, b'+')
2329}
2330
2331/// Removes the first instance from the end of the given actionlist of
2332/// chown sandboxing.
2333///
2334/// Returns 0 on success, negated errno on failure.
2335#[no_mangle]
2336pub extern "C" fn syd_chown_del(action: action_t, glob: *const c_char) -> c_int {
2337    // Convert action_t enum to corresponding action string.
2338    let action = match Action::try_from(action) {
2339        Ok(action) => action,
2340        Err(_) => return -EINVAL,
2341    };
2342
2343    // Call magic function with del operator.
2344    esyd(&format!("{action}/chown"), glob, b'-')
2345}
2346
2347/// Removes all matching patterns from the given actionlist of chown sandboxing.
2348///
2349/// Returns 0 on success, negated errno on failure.
2350#[no_mangle]
2351pub extern "C" fn syd_chown_rem(action: action_t, glob: *const c_char) -> c_int {
2352    // Convert action_t enum to corresponding action string.
2353    let action = match Action::try_from(action) {
2354        Ok(action) => action,
2355        Err(_) => return -EINVAL,
2356    };
2357
2358    // Call magic function with rem operator.
2359    esyd(&format!("{action}/chown"), glob, b'^')
2360}
2361
2362/// Adds to the given actionlist of chgrp sandboxing.
2363///
2364/// Returns 0 on success, negated errno on failure.
2365#[no_mangle]
2366pub extern "C" fn syd_chgrp_add(action: action_t, glob: *const c_char) -> c_int {
2367    // Convert action_t enum to corresponding action string.
2368    let action = match Action::try_from(action) {
2369        Ok(action) => action,
2370        Err(_) => return -EINVAL,
2371    };
2372
2373    // Call magic function with add operator.
2374    esyd(&format!("{action}/chgrp"), glob, b'+')
2375}
2376
2377/// Removes the first instance from the end of the given actionlist of
2378/// chgrp sandboxing.
2379///
2380/// Returns 0 on success, negated errno on failure.
2381#[no_mangle]
2382pub extern "C" fn syd_chgrp_del(action: action_t, glob: *const c_char) -> c_int {
2383    // Convert action_t enum to corresponding action string.
2384    let action = match Action::try_from(action) {
2385        Ok(action) => action,
2386        Err(_) => return -EINVAL,
2387    };
2388
2389    // Call magic function with del operator.
2390    esyd(&format!("{action}/chgrp"), glob, b'-')
2391}
2392
2393/// Removes all matching patterns from the given actionlist of chgrp sandboxing.
2394///
2395/// Returns 0 on success, negated errno on failure.
2396#[no_mangle]
2397pub extern "C" fn syd_chgrp_rem(action: action_t, glob: *const c_char) -> c_int {
2398    // Convert action_t enum to corresponding action string.
2399    let action = match Action::try_from(action) {
2400        Ok(action) => action,
2401        Err(_) => return -EINVAL,
2402    };
2403
2404    // Call magic function with rem operator.
2405    esyd(&format!("{action}/chgrp"), glob, b'^')
2406}
2407
2408/// Adds to the given actionlist of chmod sandboxing.
2409///
2410/// Returns 0 on success, negated errno on failure.
2411#[no_mangle]
2412pub extern "C" fn syd_chmod_add(action: action_t, glob: *const c_char) -> c_int {
2413    // Convert action_t enum to corresponding action string.
2414    let action = match Action::try_from(action) {
2415        Ok(action) => action,
2416        Err(_) => return -EINVAL,
2417    };
2418
2419    // Call magic function with add operator.
2420    esyd(&format!("{action}/chmod"), glob, b'+')
2421}
2422
2423/// Removes the first instance from the end of the given actionlist of
2424/// chmod sandboxing.
2425///
2426/// Returns 0 on success, negated errno on failure.
2427#[no_mangle]
2428pub extern "C" fn syd_chmod_del(action: action_t, glob: *const c_char) -> c_int {
2429    // Convert action_t enum to corresponding action string.
2430    let action = match Action::try_from(action) {
2431        Ok(action) => action,
2432        Err(_) => return -EINVAL,
2433    };
2434
2435    // Call magic function with del operator.
2436    esyd(&format!("{action}/chmod"), glob, b'-')
2437}
2438
2439/// Removes all matching patterns from the given actionlist of chmod sandboxing.
2440///
2441/// Returns 0 on success, negated errno on failure.
2442#[no_mangle]
2443pub extern "C" fn syd_chmod_rem(action: action_t, glob: *const c_char) -> c_int {
2444    // Convert action_t enum to corresponding action string.
2445    let action = match Action::try_from(action) {
2446        Ok(action) => action,
2447        Err(_) => return -EINVAL,
2448    };
2449
2450    // Call magic function with rem operator.
2451    esyd(&format!("{action}/chmod"), glob, b'^')
2452}
2453
2454/// Adds to the given actionlist of chattr sandboxing.
2455///
2456/// Returns 0 on success, negated errno on failure.
2457#[no_mangle]
2458pub extern "C" fn syd_chattr_add(action: action_t, glob: *const c_char) -> c_int {
2459    // Convert action_t enum to corresponding action string.
2460    let action = match Action::try_from(action) {
2461        Ok(action) => action,
2462        Err(_) => return -EINVAL,
2463    };
2464
2465    // Call magic function with add operator.
2466    esyd(&format!("{action}/chattr"), glob, b'+')
2467}
2468
2469/// Removes the first instance from the end of the given actionlist of
2470/// chattr sandboxing.
2471///
2472/// Returns 0 on success, negated errno on failure.
2473#[no_mangle]
2474pub extern "C" fn syd_chattr_del(action: action_t, glob: *const c_char) -> c_int {
2475    // Convert action_t enum to corresponding action string.
2476    let action = match Action::try_from(action) {
2477        Ok(action) => action,
2478        Err(_) => return -EINVAL,
2479    };
2480
2481    // Call magic function with del operator.
2482    esyd(&format!("{action}/chattr"), glob, b'-')
2483}
2484
2485/// Removes all matching patterns from the given actionlist of chattr sandboxing.
2486///
2487/// Returns 0 on success, negated errno on failure.
2488#[no_mangle]
2489pub extern "C" fn syd_chattr_rem(action: action_t, glob: *const c_char) -> c_int {
2490    // Convert action_t enum to corresponding action string.
2491    let action = match Action::try_from(action) {
2492        Ok(action) => action,
2493        Err(_) => return -EINVAL,
2494    };
2495
2496    // Call magic function with rem operator.
2497    esyd(&format!("{action}/chattr"), glob, b'^')
2498}
2499
2500/// Adds to the given actionlist of chroot sandboxing.
2501///
2502/// Returns 0 on success, negated errno on failure.
2503#[no_mangle]
2504pub extern "C" fn syd_chroot_add(action: action_t, glob: *const c_char) -> c_int {
2505    // Convert action_t enum to corresponding action string.
2506    let action = match Action::try_from(action) {
2507        Ok(action) => action,
2508        Err(_) => return -EINVAL,
2509    };
2510
2511    // Call magic function with add operator.
2512    esyd(&format!("{action}/chroot"), glob, b'+')
2513}
2514
2515/// Removes the first instance from the end of the given actionlist of
2516/// chroot sandboxing.
2517///
2518/// Returns 0 on success, negated errno on failure.
2519#[no_mangle]
2520pub extern "C" fn syd_chroot_del(action: action_t, glob: *const c_char) -> c_int {
2521    // Convert action_t enum to corresponding action string.
2522    let action = match Action::try_from(action) {
2523        Ok(action) => action,
2524        Err(_) => return -EINVAL,
2525    };
2526
2527    // Call magic function with del operator.
2528    esyd(&format!("{action}/chroot"), glob, b'-')
2529}
2530
2531/// Removes all matching patterns from the given actionlist of chroot sandboxing.
2532///
2533/// Returns 0 on success, negated errno on failure.
2534#[no_mangle]
2535pub extern "C" fn syd_chroot_rem(action: action_t, glob: *const c_char) -> c_int {
2536    // Convert action_t enum to corresponding action string.
2537    let action = match Action::try_from(action) {
2538        Ok(action) => action,
2539        Err(_) => return -EINVAL,
2540    };
2541
2542    // Call magic function with rem operator.
2543    esyd(&format!("{action}/chroot"), glob, b'^')
2544}
2545
2546/// Adds to the given actionlist of notify sandboxing.
2547///
2548/// Returns 0 on success, negated errno on failure.
2549#[no_mangle]
2550pub extern "C" fn syd_notify_add(action: action_t, glob: *const c_char) -> c_int {
2551    // Convert action_t enum to corresponding action string.
2552    let action = match Action::try_from(action) {
2553        Ok(action) => action,
2554        Err(_) => return -EINVAL,
2555    };
2556
2557    // Call magic function with add operator.
2558    esyd(&format!("{action}/notify"), glob, b'+')
2559}
2560
2561/// Removes the first instance from the end of the given actionlist of
2562/// notify sandboxing.
2563///
2564/// Returns 0 on success, negated errno on failure.
2565#[no_mangle]
2566pub extern "C" fn syd_notify_del(action: action_t, glob: *const c_char) -> c_int {
2567    // Convert action_t enum to corresponding action string.
2568    let action = match Action::try_from(action) {
2569        Ok(action) => action,
2570        Err(_) => return -EINVAL,
2571    };
2572
2573    // Call magic function with del operator.
2574    esyd(&format!("{action}/notify"), glob, b'-')
2575}
2576
2577/// Removes all matching patterns from the given actionlist of notify sandboxing.
2578///
2579/// Returns 0 on success, negated errno on failure.
2580#[no_mangle]
2581pub extern "C" fn syd_notify_rem(action: action_t, glob: *const c_char) -> c_int {
2582    // Convert action_t enum to corresponding action string.
2583    let action = match Action::try_from(action) {
2584        Ok(action) => action,
2585        Err(_) => return -EINVAL,
2586    };
2587
2588    // Call magic function with rem operator.
2589    esyd(&format!("{action}/notify"), glob, b'^')
2590}
2591
2592/// Adds to the given actionlist of utime sandboxing.
2593///
2594/// Returns 0 on success, negated errno on failure.
2595#[no_mangle]
2596pub extern "C" fn syd_utime_add(action: action_t, glob: *const c_char) -> c_int {
2597    // Convert action_t enum to corresponding action string.
2598    let action = match Action::try_from(action) {
2599        Ok(action) => action,
2600        Err(_) => return -EINVAL,
2601    };
2602
2603    // Call magic function with add operator.
2604    esyd(&format!("{action}/utime"), glob, b'+')
2605}
2606
2607/// Removes the first instance from the end of the given actionlist of
2608/// utime sandboxing.
2609///
2610/// Returns 0 on success, negated errno on failure.
2611#[no_mangle]
2612pub extern "C" fn syd_utime_del(action: action_t, glob: *const c_char) -> c_int {
2613    // Convert action_t enum to corresponding action string.
2614    let action = match Action::try_from(action) {
2615        Ok(action) => action,
2616        Err(_) => return -EINVAL,
2617    };
2618
2619    // Call magic function with del operator.
2620    esyd(&format!("{action}/utime"), glob, b'-')
2621}
2622
2623/// Removes all matching patterns from the given actionlist of utime sandboxing.
2624///
2625/// Returns 0 on success, negated errno on failure.
2626#[no_mangle]
2627pub extern "C" fn syd_utime_rem(action: action_t, glob: *const c_char) -> c_int {
2628    // Convert action_t enum to corresponding action string.
2629    let action = match Action::try_from(action) {
2630        Ok(action) => action,
2631        Err(_) => return -EINVAL,
2632    };
2633
2634    // Call magic function with rem operator.
2635    esyd(&format!("{action}/utime"), glob, b'^')
2636}
2637
2638/// Adds to the given actionlist of mkbdev sandboxing.
2639///
2640/// Returns 0 on success, negated errno on failure.
2641#[no_mangle]
2642pub extern "C" fn syd_mkbdev_add(action: action_t, glob: *const c_char) -> c_int {
2643    // Convert action_t enum to corresponding action string.
2644    let action = match Action::try_from(action) {
2645        Ok(action) => action,
2646        Err(_) => return -EINVAL,
2647    };
2648
2649    // Call magic function with add operator.
2650    esyd(&format!("{action}/mkbdev"), glob, b'+')
2651}
2652
2653/// Removes the first instance from the end of the given actionlist of
2654/// mkbdev sandboxing.
2655///
2656/// Returns 0 on success, negated errno on failure.
2657#[no_mangle]
2658pub extern "C" fn syd_mkbdev_del(action: action_t, glob: *const c_char) -> c_int {
2659    // Convert action_t enum to corresponding action string.
2660    let action = match Action::try_from(action) {
2661        Ok(action) => action,
2662        Err(_) => return -EINVAL,
2663    };
2664
2665    // Call magic function with del operator.
2666    esyd(&format!("{action}/mkbdev"), glob, b'-')
2667}
2668
2669/// Removes all matching patterns from the given actionlist of mkbdev sandboxing.
2670///
2671/// Returns 0 on success, negated errno on failure.
2672#[no_mangle]
2673pub extern "C" fn syd_mkbdev_rem(action: action_t, glob: *const c_char) -> c_int {
2674    // Convert action_t enum to corresponding action string.
2675    let action = match Action::try_from(action) {
2676        Ok(action) => action,
2677        Err(_) => return -EINVAL,
2678    };
2679
2680    // Call magic function with rem operator.
2681    esyd(&format!("{action}/mkbdev"), glob, b'^')
2682}
2683
2684/// Adds to the given actionlist of mkcdev sandboxing.
2685///
2686/// Returns 0 on success, negated errno on failure.
2687#[no_mangle]
2688pub extern "C" fn syd_mkcdev_add(action: action_t, glob: *const c_char) -> c_int {
2689    // Convert action_t enum to corresponding action string.
2690    let action = match Action::try_from(action) {
2691        Ok(action) => action,
2692        Err(_) => return -EINVAL,
2693    };
2694
2695    // Call magic function with add operator.
2696    esyd(&format!("{action}/mkcdev"), glob, b'+')
2697}
2698
2699/// Removes the first instance from the end of the given actionlist of
2700/// mkcdev sandboxing.
2701///
2702/// Returns 0 on success, negated errno on failure.
2703#[no_mangle]
2704pub extern "C" fn syd_mkcdev_del(action: action_t, glob: *const c_char) -> c_int {
2705    // Convert action_t enum to corresponding action string.
2706    let action = match Action::try_from(action) {
2707        Ok(action) => action,
2708        Err(_) => return -EINVAL,
2709    };
2710
2711    // Call magic function with del operator.
2712    esyd(&format!("{action}/mkcdev"), glob, b'-')
2713}
2714
2715/// Removes all matching patterns from the given actionlist of mkcdev sandboxing.
2716///
2717/// Returns 0 on success, negated errno on failure.
2718#[no_mangle]
2719pub extern "C" fn syd_mkcdev_rem(action: action_t, glob: *const c_char) -> c_int {
2720    // Convert action_t enum to corresponding action string.
2721    let action = match Action::try_from(action) {
2722        Ok(action) => action,
2723        Err(_) => return -EINVAL,
2724    };
2725
2726    // Call magic function with rem operator.
2727    esyd(&format!("{action}/mkcdev"), glob, b'^')
2728}
2729
2730/// Adds to the given actionlist of mkfifo sandboxing.
2731///
2732/// Returns 0 on success, negated errno on failure.
2733#[no_mangle]
2734pub extern "C" fn syd_mkfifo_add(action: action_t, glob: *const c_char) -> c_int {
2735    // Convert action_t enum to corresponding action string.
2736    let action = match Action::try_from(action) {
2737        Ok(action) => action,
2738        Err(_) => return -EINVAL,
2739    };
2740
2741    // Call magic function with add operator.
2742    esyd(&format!("{action}/mkfifo"), glob, b'+')
2743}
2744
2745/// Removes the first instance from the end of the given actionlist of
2746/// mkfifo sandboxing.
2747///
2748/// Returns 0 on success, negated errno on failure.
2749#[no_mangle]
2750pub extern "C" fn syd_mkfifo_del(action: action_t, glob: *const c_char) -> c_int {
2751    // Convert action_t enum to corresponding action string.
2752    let action = match Action::try_from(action) {
2753        Ok(action) => action,
2754        Err(_) => return -EINVAL,
2755    };
2756
2757    // Call magic function with del operator.
2758    esyd(&format!("{action}/mkfifo"), glob, b'-')
2759}
2760
2761/// Removes all matching patterns from the given actionlist of mkfifo sandboxing.
2762///
2763/// Returns 0 on success, negated errno on failure.
2764#[no_mangle]
2765pub extern "C" fn syd_mkfifo_rem(action: action_t, glob: *const c_char) -> c_int {
2766    // Convert action_t enum to corresponding action string.
2767    let action = match Action::try_from(action) {
2768        Ok(action) => action,
2769        Err(_) => return -EINVAL,
2770    };
2771
2772    // Call magic function with rem operator.
2773    esyd(&format!("{action}/mkfifo"), glob, b'^')
2774}
2775
2776/// Adds to the given actionlist of mktemp sandboxing.
2777///
2778/// Returns 0 on success, negated errno on failure.
2779#[no_mangle]
2780pub extern "C" fn syd_mktemp_add(action: action_t, glob: *const c_char) -> c_int {
2781    // Convert action_t enum to corresponding action string.
2782    let action = match Action::try_from(action) {
2783        Ok(action) => action,
2784        Err(_) => return -EINVAL,
2785    };
2786
2787    // Call magic function with add operator.
2788    esyd(&format!("{action}/mktemp"), glob, b'+')
2789}
2790
2791/// Removes the first instance from the end of the given actionlist of
2792/// mktemp sandboxing.
2793///
2794/// Returns 0 on success, negated errno on failure.
2795#[no_mangle]
2796pub extern "C" fn syd_mktemp_del(action: action_t, glob: *const c_char) -> c_int {
2797    // Convert action_t enum to corresponding action string.
2798    let action = match Action::try_from(action) {
2799        Ok(action) => action,
2800        Err(_) => return -EINVAL,
2801    };
2802
2803    // Call magic function with del operator.
2804    esyd(&format!("{action}/mktemp"), glob, b'-')
2805}
2806
2807/// Removes all matching patterns from the given actionlist of mktemp sandboxing.
2808///
2809/// Returns 0 on success, negated errno on failure.
2810#[no_mangle]
2811pub extern "C" fn syd_mktemp_rem(action: action_t, glob: *const c_char) -> c_int {
2812    // Convert action_t enum to corresponding action string.
2813    let action = match Action::try_from(action) {
2814        Ok(action) => action,
2815        Err(_) => return -EINVAL,
2816    };
2817
2818    // Call magic function with rem operator.
2819    esyd(&format!("{action}/mktemp"), glob, b'^')
2820}
2821
2822/// Adds to the given actionlist of net/bind sandboxing.
2823///
2824/// Returns 0 on success, negated errno on failure.
2825#[no_mangle]
2826pub extern "C" fn syd_net_bind_add(action: action_t, glob: *const c_char) -> c_int {
2827    // Convert action_t enum to corresponding action string.
2828    let action = match Action::try_from(action) {
2829        Ok(action) => action,
2830        Err(_) => return -EINVAL,
2831    };
2832
2833    // Call magic function with add operator.
2834    esyd(&format!("{action}/net/bind"), glob, b'+')
2835}
2836
2837/// Removes the first instance from the end of the given actionlist of
2838/// net/bind sandboxing.
2839///
2840/// Returns 0 on success, negated errno on failure.
2841#[no_mangle]
2842pub extern "C" fn syd_net_bind_del(action: action_t, glob: *const c_char) -> c_int {
2843    // Convert action_t enum to corresponding action string.
2844    let action = match Action::try_from(action) {
2845        Ok(action) => action,
2846        Err(_) => return -EINVAL,
2847    };
2848
2849    // Call magic function with del operator.
2850    esyd(&format!("{action}/net/bind"), glob, b'-')
2851}
2852
2853/// Removes all matching patterns from the given actionlist of net/bind sandboxing.
2854///
2855/// Returns 0 on success, negated errno on failure.
2856#[no_mangle]
2857pub extern "C" fn syd_net_bind_rem(action: action_t, glob: *const c_char) -> c_int {
2858    // Convert action_t enum to corresponding action string.
2859    let action = match Action::try_from(action) {
2860        Ok(action) => action,
2861        Err(_) => return -EINVAL,
2862    };
2863
2864    // Call magic function with rem operator.
2865    esyd(&format!("{action}/net/bind"), glob, b'^')
2866}
2867
2868/// Adds to the given actionlist of net/connect sandboxing.
2869///
2870/// Returns 0 on success, negated errno on failure.
2871#[no_mangle]
2872pub extern "C" fn syd_net_connect_add(action: action_t, glob: *const c_char) -> c_int {
2873    // Convert action_t enum to corresponding action string.
2874    let action = match Action::try_from(action) {
2875        Ok(action) => action,
2876        Err(_) => return -EINVAL,
2877    };
2878
2879    // Call magic function with add operator.
2880    esyd(&format!("{action}/net/connect"), glob, b'+')
2881}
2882
2883/// Removes the first instance from the end of the given actionlist of
2884/// net/connect sandboxing.
2885///
2886/// Returns 0 on success, negated errno on failure.
2887#[no_mangle]
2888pub extern "C" fn syd_net_connect_del(action: action_t, glob: *const c_char) -> c_int {
2889    // Convert action_t enum to corresponding action string.
2890    let action = match Action::try_from(action) {
2891        Ok(action) => action,
2892        Err(_) => return -EINVAL,
2893    };
2894
2895    // Call magic function with del operator.
2896    esyd(&format!("{action}/net/connect"), glob, b'-')
2897}
2898
2899/// Removes all matching patterns from the given actionlist of net/connect sandboxing.
2900///
2901/// Returns 0 on success, negated errno on failure.
2902#[no_mangle]
2903pub extern "C" fn syd_net_connect_rem(action: action_t, glob: *const c_char) -> c_int {
2904    // Convert action_t enum to corresponding action string.
2905    let action = match Action::try_from(action) {
2906        Ok(action) => action,
2907        Err(_) => return -EINVAL,
2908    };
2909
2910    // Call magic function with rem operator.
2911    esyd(&format!("{action}/net/connect"), glob, b'^')
2912}
2913
2914/// Adds to the given actionlist of net/sendfd sandboxing.
2915///
2916/// Returns 0 on success, negated errno on failure.
2917#[no_mangle]
2918pub extern "C" fn syd_net_sendfd_add(action: action_t, glob: *const c_char) -> c_int {
2919    // Convert action_t enum to corresponding action string.
2920    let action = match Action::try_from(action) {
2921        Ok(action) => action,
2922        Err(_) => return -EINVAL,
2923    };
2924
2925    // Call magic function with add operator.
2926    esyd(&format!("{action}/net/sendfd"), glob, b'+')
2927}
2928
2929/// Removes the first instance from the end of the given actionlist of
2930/// net/sendfd sandboxing.
2931///
2932/// Returns 0 on success, negated errno on failure.
2933#[no_mangle]
2934pub extern "C" fn syd_net_sendfd_del(action: action_t, glob: *const c_char) -> c_int {
2935    // Convert action_t enum to corresponding action string.
2936    let action = match Action::try_from(action) {
2937        Ok(action) => action,
2938        Err(_) => return -EINVAL,
2939    };
2940
2941    // Call magic function with del operator.
2942    esyd(&format!("{action}/net/sendfd"), glob, b'-')
2943}
2944
2945/// Removes all matching patterns from the given actionlist of net/sendfd sandboxing.
2946///
2947/// Returns 0 on success, negated errno on failure.
2948#[no_mangle]
2949pub extern "C" fn syd_net_sendfd_rem(action: action_t, glob: *const c_char) -> c_int {
2950    // Convert action_t enum to corresponding action string.
2951    let action = match Action::try_from(action) {
2952        Ok(action) => action,
2953        Err(_) => return -EINVAL,
2954    };
2955
2956    // Call magic function with rem operator.
2957    esyd(&format!("{action}/net/sendfd"), glob, b'^')
2958}
2959
2960/// Adds to the given actionlist of net/link sandboxing.
2961///
2962/// Returns 0 on success, negated errno on failure.
2963#[no_mangle]
2964pub extern "C" fn syd_net_link_add(action: action_t, family: *const c_char) -> c_int {
2965    // Convert action_t enum to corresponding action string.
2966    let action = match Action::try_from(action) {
2967        Ok(action) => action,
2968        Err(_) => return -EINVAL,
2969    };
2970
2971    // Call magic function with add operator.
2972    esyd(&format!("{action}/net/link"), family, b'+')
2973}
2974
2975/// Removes the first instance from the end of the given actionlist of
2976/// net/link sandboxing.
2977///
2978/// Returns 0 on success, negated errno on failure.
2979#[no_mangle]
2980pub extern "C" fn syd_net_link_del(action: action_t, family: *const c_char) -> c_int {
2981    // Convert action_t enum to corresponding action string.
2982    let action = match Action::try_from(action) {
2983        Ok(action) => action,
2984        Err(_) => return -EINVAL,
2985    };
2986
2987    // Call magic function with del operator.
2988    esyd(&format!("{action}/net/link"), family, b'-')
2989}
2990
2991/// Removes all matching patterns from the given actionlist of net/link sandboxing.
2992///
2993/// Returns 0 on success, negated errno on failure.
2994#[no_mangle]
2995pub extern "C" fn syd_net_link_rem(action: action_t, family: *const c_char) -> c_int {
2996    // Convert action_t enum to corresponding action string.
2997    let action = match Action::try_from(action) {
2998        Ok(action) => action,
2999        Err(_) => return -EINVAL,
3000    };
3001
3002    // Call magic function with rem operator.
3003    esyd(&format!("{action}/net/link"), family, b'^')
3004}
3005
3006/// Set syd maximum per-process memory usage limit for memory sandboxing.
3007///
3008/// parse-size crate is used to parse the value so formatted strings are OK.
3009///
3010/// Returns 0 on success, negated errno on failure.
3011#[no_mangle]
3012pub extern "C" fn syd_mem_max(size: *const c_char) -> c_int {
3013    esyd("mem/max", size, b':')
3014}
3015
3016/// Set syd maximum per-process virtual memory usage limit for memory sandboxing.
3017///
3018/// parse-size crate is used to parse the value so formatted strings are OK.
3019///
3020/// Returns 0 on success, negated errno on failure.
3021#[no_mangle]
3022pub extern "C" fn syd_mem_vm_max(size: *const c_char) -> c_int {
3023    esyd("mem/vm_max", size, b':')
3024}
3025
3026/// Set syd maximum process id limit for PID sandboxing
3027///
3028/// Returns 0 on success, negated errno on failure.
3029#[no_mangle]
3030pub extern "C" fn syd_pid_max(size: usize) -> c_int {
3031    stat(&format!("/dev/syd/pid/max:{size}"))
3032}
3033
3034/// Specify SegvGuard entry expiry timeout in seconds.
3035/// Setting this timeout to 0 effectively disables SegvGuard.
3036///
3037/// Returns 0 on success, negated errno on failure.
3038#[no_mangle]
3039pub extern "C" fn syd_segvguard_expiry(timeout: u64) -> c_int {
3040    stat(&format!("/dev/syd/segvguard/expiry:{timeout}"))
3041}
3042
3043/// Specify SegvGuard entry suspension timeout in seconds.
3044///
3045/// Returns 0 on success, negated errno on failure.
3046#[no_mangle]
3047pub extern "C" fn syd_segvguard_suspension(timeout: u64) -> c_int {
3048    stat(&format!("/dev/syd/segvguard/suspension:{timeout}"))
3049}
3050
3051/// Specify SegvGuard max number of crashes before suspension.
3052///
3053/// Returns 0 on success, negated errno on failure.
3054#[no_mangle]
3055pub extern "C" fn syd_segvguard_maxcrashes(max: u8) -> c_int {
3056    stat(&format!("/dev/syd/segvguard/maxcrashes:{max}"))
3057}
3058
3059/// Execute a command outside the sandbox without sandboxing
3060///
3061/// # Safety
3062///
3063/// This function is marked `unsafe` because it dereferences raw
3064/// pointers, which is inherently unsafe in Rust.
3065///
3066/// The caller must ensure the following conditions are met to safely
3067/// use this function:
3068///
3069/// 1. The `file` pointer must point to a valid, null-terminated C-style
3070///    string.
3071///
3072/// 2. The `argv` pointer must point to an array of pointers, where each
3073///    pointer refers to a valid, null-terminated C-style string. The
3074///    last pointer in the array must be null, indicating the end of the
3075///    array.
3076///
3077/// 3. The memory pointed to by `file` and `argv` must remain valid for
3078///    the duration of the call.
3079///
3080/// Failing to uphold these guarantees can lead to undefined behavior,
3081/// including memory corruption and data races.
3082///
3083/// Returns 0 on success, negated errno on failure.
3084#[no_mangle]
3085pub unsafe extern "C" fn syd_exec(file: *const c_char, argv: *const *const c_char) -> c_int {
3086    if file.is_null() || argv.is_null() {
3087        return -EFAULT;
3088    }
3089
3090    // SAFETY: Trust that `file` is a null-terminated string.
3091    let file = CStr::from_ptr(file);
3092    let file = OsStr::from_bytes(file.to_bytes());
3093
3094    let mut path = OsString::from("/dev/syd/cmd/exec!");
3095    path.push(file);
3096
3097    let mut idx: isize = 0;
3098    while !(*argv.offset(idx)).is_null() {
3099        // SAFETY: Trust that each `argv` element is a null-terminated string.
3100        let arg = CStr::from_ptr(*argv.offset(idx));
3101        let arg = OsStr::from_bytes(arg.to_bytes());
3102
3103        path.push(OsStr::from_bytes(&[b'\x1F'])); // ASCII Unit Separator
3104        path.push(arg);
3105
3106        idx = idx.saturating_add(1);
3107    }
3108
3109    let path = PathBuf::from(path);
3110    stat(path)
3111}