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: &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 list sandboxing is enabled.
422///
423/// Returns true if list sandboxing is enabled, false otherwise.
424#[no_mangle]
425pub extern "C" fn syd_enabled_list() -> bool {
426    stat("/dev/syd/sandbox/list?") == 0
427}
428
429/// Enable list sandboxing.
430///
431/// Returns 0 on success, negated errno on failure.
432#[no_mangle]
433pub extern "C" fn syd_enable_list() -> c_int {
434    stat("/dev/syd/sandbox/list:on")
435}
436
437/// Disable list sandboxing.
438///
439/// Returns 0 on success, negated errno on failure.
440#[no_mangle]
441pub extern "C" fn syd_disable_list() -> c_int {
442    stat("/dev/syd/sandbox/list:off")
443}
444
445/// Checks if stat sandboxing is enabled.
446///
447/// Returns true if stat sandboxing is enabled, false otherwise.
448#[no_mangle]
449pub extern "C" fn syd_enabled_stat() -> bool {
450    stat("/dev/syd/sandbox/stat?") == 0
451}
452
453/// Enable stat sandboxing.
454///
455/// Returns 0 on success, negated errno on failure.
456#[no_mangle]
457pub extern "C" fn syd_enable_stat() -> c_int {
458    stat("/dev/syd/sandbox/stat:on")
459}
460
461/// Disable stat sandboxing.
462///
463/// Returns 0 on success, negated errno on failure.
464#[no_mangle]
465pub extern "C" fn syd_disable_stat() -> c_int {
466    stat("/dev/syd/sandbox/stat:off")
467}
468
469/// Checks if read sandboxing is enabled.
470///
471/// Returns true if read sandboxing is enabled, false otherwise.
472#[no_mangle]
473pub extern "C" fn syd_enabled_read() -> bool {
474    stat("/dev/syd/sandbox/read?") == 0
475}
476
477/// Enable read sandboxing.
478///
479/// Returns 0 on success, negated errno on failure.
480#[no_mangle]
481pub extern "C" fn syd_enable_read() -> c_int {
482    stat("/dev/syd/sandbox/read:on")
483}
484
485/// Disable read sandboxing.
486///
487/// Returns 0 on success, negated errno on failure.
488#[no_mangle]
489pub extern "C" fn syd_disable_read() -> c_int {
490    stat("/dev/syd/sandbox/read:off")
491}
492
493/// Checks if write sandboxing is enabled.
494///
495/// Returns true if write sandboxing is enabled, false otherwise.
496#[no_mangle]
497pub extern "C" fn syd_enabled_write() -> bool {
498    stat("/dev/syd/sandbox/write?") == 0
499}
500
501/// Enable write sandboxing.
502///
503/// Returns 0 on success, negated errno on failure.
504#[no_mangle]
505pub extern "C" fn syd_enable_write() -> c_int {
506    stat("/dev/syd/sandbox/write:on")
507}
508
509/// Disable write sandboxing.
510///
511/// Returns 0 on success, negated errno on failure.
512#[no_mangle]
513pub extern "C" fn syd_disable_write() -> c_int {
514    stat("/dev/syd/sandbox/write:off")
515}
516
517/// Checks if exec sandboxing is enabled.
518///
519/// Returns true if exec sandboxing is enabled, false otherwise.
520#[no_mangle]
521pub extern "C" fn syd_enabled_exec() -> bool {
522    stat("/dev/syd/sandbox/exec?") == 0
523}
524
525/// Enable exec sandboxing.
526///
527/// Returns 0 on success, negated errno on failure.
528#[no_mangle]
529pub extern "C" fn syd_enable_exec() -> c_int {
530    stat("/dev/syd/sandbox/exec:on")
531}
532
533/// Disable exec sandboxing.
534///
535/// Returns 0 on success, negated errno on failure.
536#[no_mangle]
537pub extern "C" fn syd_disable_exec() -> c_int {
538    stat("/dev/syd/sandbox/exec:off")
539}
540
541/// Checks if ioctl sandboxing is enabled.
542///
543/// Returns true if ioctl sandboxing is enabled, false otherwise.
544#[no_mangle]
545pub extern "C" fn syd_enabled_ioctl() -> bool {
546    stat("/dev/syd/sandbox/ioctl?") == 0
547}
548
549/// Enable ioctl sandboxing.
550///
551/// Returns 0 on success, negated errno on failure.
552#[no_mangle]
553pub extern "C" fn syd_enable_ioctl() -> c_int {
554    stat("/dev/syd/sandbox/ioctl:on")
555}
556
557/// Disable ioctl sandboxing.
558///
559/// Returns 0 on success, negated errno on failure.
560#[no_mangle]
561pub extern "C" fn syd_disable_ioctl() -> c_int {
562    stat("/dev/syd/sandbox/ioctl:off")
563}
564
565/// Checks if create sandboxing is enabled.
566///
567/// Returns true if create sandboxing is enabled, false otherwise.
568#[no_mangle]
569pub extern "C" fn syd_enabled_create() -> bool {
570    stat("/dev/syd/sandbox/create?") == 0
571}
572
573/// Enable create sandboxing.
574///
575/// Returns 0 on success, negated errno on failure.
576#[no_mangle]
577pub extern "C" fn syd_enable_create() -> c_int {
578    stat("/dev/syd/sandbox/create:on")
579}
580
581/// Disable create sandboxing.
582///
583/// Returns 0 on success, negated errno on failure.
584#[no_mangle]
585pub extern "C" fn syd_disable_create() -> c_int {
586    stat("/dev/syd/sandbox/create:off")
587}
588
589/// Checks if delete sandboxing is enabled.
590///
591/// Returns true if delete sandboxing is enabled, false otherwise.
592#[no_mangle]
593pub extern "C" fn syd_enabled_delete() -> bool {
594    stat("/dev/syd/sandbox/delete?") == 0
595}
596
597/// Enable delete sandboxing.
598///
599/// Returns 0 on success, negated errno on failure.
600#[no_mangle]
601pub extern "C" fn syd_enable_delete() -> c_int {
602    stat("/dev/syd/sandbox/delete:on")
603}
604
605/// Disable delete sandboxing.
606///
607/// Returns 0 on success, negated errno on failure.
608#[no_mangle]
609pub extern "C" fn syd_disable_delete() -> c_int {
610    stat("/dev/syd/sandbox/delete:off")
611}
612
613/// Checks if rename sandboxing is enabled.
614///
615/// Returns true if rename sandboxing is enabled, false otherwise.
616#[no_mangle]
617pub extern "C" fn syd_enabled_rename() -> bool {
618    stat("/dev/syd/sandbox/rename?") == 0
619}
620
621/// Enable rename sandboxing.
622///
623/// Returns 0 on success, negated errno on failure.
624#[no_mangle]
625pub extern "C" fn syd_enable_rename() -> c_int {
626    stat("/dev/syd/sandbox/rename:on")
627}
628
629/// Disable rename sandboxing.
630///
631/// Returns 0 on success, negated errno on failure.
632#[no_mangle]
633pub extern "C" fn syd_disable_rename() -> c_int {
634    stat("/dev/syd/sandbox/rename:off")
635}
636
637/// Checks if readlink sandboxing is enabled.
638///
639/// Returns true if readlink sandboxing is enabled, false otherwise.
640#[no_mangle]
641pub extern "C" fn syd_enabled_readlink() -> bool {
642    stat("/dev/syd/sandbox/readlink?") == 0
643}
644
645/// Enable readlink sandboxing.
646///
647/// Returns 0 on success, negated errno on failure.
648#[no_mangle]
649pub extern "C" fn syd_enable_readlink() -> c_int {
650    stat("/dev/syd/sandbox/readlink:on")
651}
652
653/// Disable readlink sandboxing.
654///
655/// Returns 0 on success, negated errno on failure.
656#[no_mangle]
657pub extern "C" fn syd_disable_readlink() -> c_int {
658    stat("/dev/syd/sandbox/readlink:off")
659}
660
661/// Checks if symlink sandboxing is enabled.
662///
663/// Returns true if symlink sandboxing is enabled, false otherwise.
664#[no_mangle]
665pub extern "C" fn syd_enabled_symlink() -> bool {
666    stat("/dev/syd/sandbox/symlink?") == 0
667}
668
669/// Enable symlink sandboxing.
670///
671/// Returns 0 on success, negated errno on failure.
672#[no_mangle]
673pub extern "C" fn syd_enable_symlink() -> c_int {
674    stat("/dev/syd/sandbox/symlink:on")
675}
676
677/// Disable symlink sandboxing.
678///
679/// Returns 0 on success, negated errno on failure.
680#[no_mangle]
681pub extern "C" fn syd_disable_symlink() -> c_int {
682    stat("/dev/syd/sandbox/symlink:off")
683}
684
685/// Checks if truncate sandboxing is enabled.
686///
687/// Returns true if truncate sandboxing is enabled, false otherwise.
688#[no_mangle]
689pub extern "C" fn syd_enabled_truncate() -> bool {
690    stat("/dev/syd/sandbox/truncate?") == 0
691}
692
693/// Enable truncate sandboxing.
694///
695/// Returns 0 on success, negated errno on failure.
696#[no_mangle]
697pub extern "C" fn syd_enable_truncate() -> c_int {
698    stat("/dev/syd/sandbox/truncate:on")
699}
700
701/// Disable truncate sandboxing.
702///
703/// Returns 0 on success, negated errno on failure.
704#[no_mangle]
705pub extern "C" fn syd_disable_truncate() -> c_int {
706    stat("/dev/syd/sandbox/truncate:off")
707}
708
709/// Checks if chdir sandboxing is enabled.
710///
711/// Returns true if chdir sandboxing is enabled, false otherwise.
712#[no_mangle]
713pub extern "C" fn syd_enabled_chdir() -> bool {
714    stat("/dev/syd/sandbox/chdir?") == 0
715}
716
717/// Enable chdir sandboxing.
718///
719/// Returns 0 on success, negated errno on failure.
720#[no_mangle]
721pub extern "C" fn syd_enable_chdir() -> c_int {
722    stat("/dev/syd/sandbox/chdir:on")
723}
724
725/// Disable chdir sandboxing.
726///
727/// Returns 0 on success, negated errno on failure.
728#[no_mangle]
729pub extern "C" fn syd_disable_chdir() -> c_int {
730    stat("/dev/syd/sandbox/chdir:off")
731}
732
733/// Checks if readdir sandboxing is enabled.
734///
735/// Returns true if readdir sandboxing is enabled, false otherwise.
736#[no_mangle]
737pub extern "C" fn syd_enabled_readdir() -> bool {
738    stat("/dev/syd/sandbox/readdir?") == 0
739}
740
741/// Enable readdir sandboxing.
742///
743/// Returns 0 on success, negated errno on failure.
744#[no_mangle]
745pub extern "C" fn syd_enable_readdir() -> c_int {
746    stat("/dev/syd/sandbox/readdir:on")
747}
748
749/// Disable readdir sandboxing.
750///
751/// Returns 0 on success, negated errno on failure.
752#[no_mangle]
753pub extern "C" fn syd_disable_readdir() -> c_int {
754    stat("/dev/syd/sandbox/readdir:off")
755}
756
757/// Checks if mkdir sandboxing is enabled.
758///
759/// Returns true if mkdir sandboxing is enabled, false otherwise.
760#[no_mangle]
761pub extern "C" fn syd_enabled_mkdir() -> bool {
762    stat("/dev/syd/sandbox/mkdir?") == 0
763}
764
765/// Enable mkdir sandboxing.
766///
767/// Returns 0 on success, negated errno on failure.
768#[no_mangle]
769pub extern "C" fn syd_enable_mkdir() -> c_int {
770    stat("/dev/syd/sandbox/mkdir:on")
771}
772
773/// Disable mkdir sandboxing.
774///
775/// Returns 0 on success, negated errno on failure.
776#[no_mangle]
777pub extern "C" fn syd_disable_mkdir() -> c_int {
778    stat("/dev/syd/sandbox/mkdir:off")
779}
780
781/// Checks if rmdir sandboxing is enabled.
782///
783/// Returns true if rmdir sandboxing is enabled, false otherwise.
784#[no_mangle]
785pub extern "C" fn syd_enabled_rmdir() -> bool {
786    stat("/dev/syd/sandbox/rmdir?") == 0
787}
788
789/// Enable rmdir sandboxing.
790///
791/// Returns 0 on success, negated errno on failure.
792#[no_mangle]
793pub extern "C" fn syd_enable_rmdir() -> c_int {
794    stat("/dev/syd/sandbox/rmdir:on")
795}
796
797/// Disable rmdir sandboxing.
798///
799/// Returns 0 on success, negated errno on failure.
800#[no_mangle]
801pub extern "C" fn syd_disable_rmdir() -> c_int {
802    stat("/dev/syd/sandbox/rmdir:off")
803}
804
805/// Checks if chown sandboxing is enabled.
806///
807/// Returns true if chown sandboxing is enabled, false otherwise.
808#[no_mangle]
809pub extern "C" fn syd_enabled_chown() -> bool {
810    stat("/dev/syd/sandbox/chown?") == 0
811}
812
813/// Enable chown sandboxing.
814///
815/// Returns 0 on success, negated errno on failure.
816#[no_mangle]
817pub extern "C" fn syd_enable_chown() -> c_int {
818    stat("/dev/syd/sandbox/chown:on")
819}
820
821/// Disable chown sandboxing.
822///
823/// Returns 0 on success, negated errno on failure.
824#[no_mangle]
825pub extern "C" fn syd_disable_chown() -> c_int {
826    stat("/dev/syd/sandbox/chown:off")
827}
828
829/// Checks if chgrp sandboxing is enabled.
830///
831/// Returns true if chgrp sandboxing is enabled, false otherwise.
832#[no_mangle]
833pub extern "C" fn syd_enabled_chgrp() -> bool {
834    stat("/dev/syd/sandbox/chgrp?") == 0
835}
836
837/// Enable chgrp sandboxing.
838///
839/// Returns 0 on success, negated errno on failure.
840#[no_mangle]
841pub extern "C" fn syd_enable_chgrp() -> c_int {
842    stat("/dev/syd/sandbox/chgrp:on")
843}
844
845/// Disable chgrp sandboxing.
846///
847/// Returns 0 on success, negated errno on failure.
848#[no_mangle]
849pub extern "C" fn syd_disable_chgrp() -> c_int {
850    stat("/dev/syd/sandbox/chgrp:off")
851}
852
853/// Checks if chmod sandboxing is enabled.
854///
855/// Returns true if chmod sandboxing is enabled, false otherwise.
856#[no_mangle]
857pub extern "C" fn syd_enabled_chmod() -> bool {
858    stat("/dev/syd/sandbox/chmod?") == 0
859}
860
861/// Enable chmod sandboxing.
862///
863/// Returns 0 on success, negated errno on failure.
864#[no_mangle]
865pub extern "C" fn syd_enable_chmod() -> c_int {
866    stat("/dev/syd/sandbox/chmod:on")
867}
868
869/// Disable chmod sandboxing.
870///
871/// Returns 0 on success, negated errno on failure.
872#[no_mangle]
873pub extern "C" fn syd_disable_chmod() -> c_int {
874    stat("/dev/syd/sandbox/chmod:off")
875}
876
877/// Checks if chattr sandboxing is enabled.
878///
879/// Returns true if chattr sandboxing is enabled, false otherwise.
880#[no_mangle]
881pub extern "C" fn syd_enabled_chattr() -> bool {
882    stat("/dev/syd/sandbox/chattr?") == 0
883}
884
885/// Enable chattr sandboxing.
886///
887/// Returns 0 on success, negated errno on failure.
888#[no_mangle]
889pub extern "C" fn syd_enable_chattr() -> c_int {
890    stat("/dev/syd/sandbox/chattr:on")
891}
892
893/// Disable chattr sandboxing.
894///
895/// Returns 0 on success, negated errno on failure.
896#[no_mangle]
897pub extern "C" fn syd_disable_chattr() -> c_int {
898    stat("/dev/syd/sandbox/chattr:off")
899}
900
901/// Checks if chroot sandboxing is enabled.
902///
903/// Returns true if chroot sandboxing is enabled, false otherwise.
904#[no_mangle]
905pub extern "C" fn syd_enabled_chroot() -> bool {
906    stat("/dev/syd/sandbox/chroot?") == 0
907}
908
909/// Enable chroot sandboxing.
910///
911/// Returns 0 on success, negated errno on failure.
912#[no_mangle]
913pub extern "C" fn syd_enable_chroot() -> c_int {
914    stat("/dev/syd/sandbox/chroot:on")
915}
916
917/// Disable chroot sandboxing.
918///
919/// Returns 0 on success, negated errno on failure.
920#[no_mangle]
921pub extern "C" fn syd_disable_chroot() -> c_int {
922    stat("/dev/syd/sandbox/chroot:off")
923}
924
925/// Checks if notify sandboxing is enabled.
926///
927/// Returns true if notify sandboxing is enabled, false otherwise.
928#[no_mangle]
929pub extern "C" fn syd_enabled_notify() -> bool {
930    stat("/dev/syd/sandbox/notify?") == 0
931}
932
933/// Enable notify sandboxing.
934///
935/// Returns 0 on success, negated errno on failure.
936#[no_mangle]
937pub extern "C" fn syd_enable_notify() -> c_int {
938    stat("/dev/syd/sandbox/notify:on")
939}
940
941/// Disable notify sandboxing.
942///
943/// Returns 0 on success, negated errno on failure.
944#[no_mangle]
945pub extern "C" fn syd_disable_notify() -> c_int {
946    stat("/dev/syd/sandbox/notify:off")
947}
948
949/// Checks if utime sandboxing is enabled.
950///
951/// Returns true if utime sandboxing is enabled, false otherwise.
952#[no_mangle]
953pub extern "C" fn syd_enabled_utime() -> bool {
954    stat("/dev/syd/sandbox/utime?") == 0
955}
956
957/// Enable utime sandboxing.
958///
959/// Returns 0 on success, negated errno on failure.
960#[no_mangle]
961pub extern "C" fn syd_enable_utime() -> c_int {
962    stat("/dev/syd/sandbox/utime:on")
963}
964
965/// Disable utime sandboxing.
966///
967/// Returns 0 on success, negated errno on failure.
968#[no_mangle]
969pub extern "C" fn syd_disable_utime() -> c_int {
970    stat("/dev/syd/sandbox/utime:off")
971}
972
973/// Checks if mkbdev sandboxing is enabled.
974///
975/// Returns true if mkbdev sandboxing is enabled, false otherwise.
976#[no_mangle]
977pub extern "C" fn syd_enabled_mkbdev() -> bool {
978    stat("/dev/syd/sandbox/mkbdev?") == 0
979}
980
981/// Enable mkbdev sandboxing.
982///
983/// Returns 0 on success, negated errno on failure.
984#[no_mangle]
985pub extern "C" fn syd_enable_mkbdev() -> c_int {
986    stat("/dev/syd/sandbox/mkbdev:on")
987}
988
989/// Disable mkbdev sandboxing.
990///
991/// Returns 0 on success, negated errno on failure.
992#[no_mangle]
993pub extern "C" fn syd_disable_mkbdev() -> c_int {
994    stat("/dev/syd/sandbox/mkbdev:off")
995}
996
997/// Checks if mkcdev sandboxing is enabled.
998///
999/// Returns true if mkcdev sandboxing is enabled, false otherwise.
1000#[no_mangle]
1001pub extern "C" fn syd_enabled_mkcdev() -> bool {
1002    stat("/dev/syd/sandbox/mkcdev?") == 0
1003}
1004
1005/// Enable mkcdev sandboxing.
1006///
1007/// Returns 0 on success, negated errno on failure.
1008#[no_mangle]
1009pub extern "C" fn syd_enable_mkcdev() -> c_int {
1010    stat("/dev/syd/sandbox/mkcdev:on")
1011}
1012
1013/// Disable mkcdev sandboxing.
1014///
1015/// Returns 0 on success, negated errno on failure.
1016#[no_mangle]
1017pub extern "C" fn syd_disable_mkcdev() -> c_int {
1018    stat("/dev/syd/sandbox/mkcdev:off")
1019}
1020
1021/// Checks if mkfifo sandboxing is enabled.
1022///
1023/// Returns true if mkfifo sandboxing is enabled, false otherwise.
1024#[no_mangle]
1025pub extern "C" fn syd_enabled_mkfifo() -> bool {
1026    stat("/dev/syd/sandbox/mkfifo?") == 0
1027}
1028
1029/// Enable mkfifo sandboxing.
1030///
1031/// Returns 0 on success, negated errno on failure.
1032#[no_mangle]
1033pub extern "C" fn syd_enable_mkfifo() -> c_int {
1034    stat("/dev/syd/sandbox/mkfifo:on")
1035}
1036
1037/// Disable mkfifo sandboxing.
1038///
1039/// Returns 0 on success, negated errno on failure.
1040#[no_mangle]
1041pub extern "C" fn syd_disable_mkfifo() -> c_int {
1042    stat("/dev/syd/sandbox/mkfifo:off")
1043}
1044
1045/// Checks if mktemp sandboxing is enabled.
1046///
1047/// Returns true if mktemp sandboxing is enabled, false otherwise.
1048#[no_mangle]
1049pub extern "C" fn syd_enabled_mktemp() -> bool {
1050    stat("/dev/syd/sandbox/mktemp?") == 0
1051}
1052
1053/// Enable mktemp sandboxing.
1054///
1055/// Returns 0 on success, negated errno on failure.
1056#[no_mangle]
1057pub extern "C" fn syd_enable_mktemp() -> c_int {
1058    stat("/dev/syd/sandbox/mktemp:on")
1059}
1060
1061/// Disable mktemp sandboxing.
1062///
1063/// Returns 0 on success, negated errno on failure.
1064#[no_mangle]
1065pub extern "C" fn syd_disable_mktemp() -> c_int {
1066    stat("/dev/syd/sandbox/mktemp:off")
1067}
1068
1069/// Checks if net sandboxing is enabled.
1070///
1071/// Returns true if net sandboxing is enabled, false otherwise.
1072#[no_mangle]
1073pub extern "C" fn syd_enabled_net() -> bool {
1074    stat("/dev/syd/sandbox/net?") == 0
1075}
1076
1077/// Enable net sandboxing.
1078///
1079/// Returns 0 on success, negated errno on failure.
1080#[no_mangle]
1081pub extern "C" fn syd_enable_net() -> c_int {
1082    stat("/dev/syd/sandbox/net:on")
1083}
1084
1085/// Disable net sandboxing.
1086///
1087/// Returns 0 on success, negated errno on failure.
1088#[no_mangle]
1089pub extern "C" fn syd_disable_net() -> c_int {
1090    stat("/dev/syd/sandbox/net:off")
1091}
1092
1093/// Checks if memory sandboxing is enabled.
1094///
1095/// Returns true if memory sandboxing is enabled, false otherwise.
1096#[no_mangle]
1097pub extern "C" fn syd_enabled_mem() -> bool {
1098    stat("/dev/syd/sandbox/mem?") == 0
1099}
1100
1101/// Disable memory sandboxing.
1102///
1103/// Returns 0 on success, negated errno on failure.
1104#[no_mangle]
1105pub extern "C" fn syd_disable_mem() -> c_int {
1106    stat("/dev/syd/sandbox/mem:off")
1107}
1108
1109/// Checks if PID sandboxing is enabled.
1110///
1111/// Returns true if PID sandboxing is enabled, false otherwise.
1112#[no_mangle]
1113pub extern "C" fn syd_enabled_pid() -> bool {
1114    stat("/dev/syd/sandbox/pid?") == 0
1115}
1116
1117/// Enable PID sandboxing.
1118///
1119/// Returns 0 on success, negated errno on failure.
1120#[no_mangle]
1121pub extern "C" fn syd_enable_pid() -> c_int {
1122    stat("/dev/syd/sandbox/pid:on")
1123}
1124
1125/// Disable PID sandboxing.
1126///
1127/// Returns 0 on success, negated errno on failure.
1128#[no_mangle]
1129pub extern "C" fn syd_disable_pid() -> c_int {
1130    stat("/dev/syd/sandbox/pid:off")
1131}
1132
1133/// Checks if lock sandboxing is enabled.
1134///
1135/// Returns true if lock sandboxing is enabled, false otherwise.
1136#[no_mangle]
1137pub extern "C" fn syd_enabled_lock() -> bool {
1138    stat("/dev/syd/sandbox/lock?") == 0
1139}
1140
1141/// Checks if crypt sandboxing is enabled.
1142///
1143/// Returns true if crypt sandboxing is enabled, false otherwise.
1144#[no_mangle]
1145pub extern "C" fn syd_enabled_crypt() -> bool {
1146    stat("/dev/syd/sandbox/crypt?") == 0
1147}
1148
1149/// Checks if proxy sandboxing is enabled.
1150///
1151/// Returns true if proxy sandboxing is enabled, false otherwise.
1152#[no_mangle]
1153pub extern "C" fn syd_enabled_proxy() -> bool {
1154    stat("/dev/syd/sandbox/proxy?") == 0
1155}
1156
1157/// Checks if force sandboxing is enabled.
1158///
1159/// Returns true if force sandboxing is enabled, false otherwise.
1160#[no_mangle]
1161pub extern "C" fn syd_enabled_force() -> bool {
1162    stat("/dev/syd/sandbox/force?") == 0
1163}
1164
1165/// Disable force sandboxing.
1166///
1167/// Returns 0 on success, negated errno on failure.
1168#[no_mangle]
1169pub extern "C" fn syd_disable_force() -> c_int {
1170    stat("/dev/syd/sandbox/force:off")
1171}
1172
1173/// Checks if TPE sandboxing is enabled.
1174///
1175/// Returns true if TPE sandboxing is enabled, false otherwise.
1176#[no_mangle]
1177pub extern "C" fn syd_enabled_tpe() -> bool {
1178    stat("/dev/syd/sandbox/tpe?") == 0
1179}
1180
1181/// Enable TPE sandboxing.
1182///
1183/// Returns 0 on success, negated errno on failure.
1184#[no_mangle]
1185pub extern "C" fn syd_enable_tpe() -> c_int {
1186    stat("/dev/syd/sandbox/tpe:on")
1187}
1188
1189/// Disable TPE sandboxing.
1190///
1191/// Returns 0 on success, negated errno on failure.
1192#[no_mangle]
1193pub extern "C" fn syd_disable_tpe() -> c_int {
1194    stat("/dev/syd/sandbox/tpe:off")
1195}
1196
1197/// Set the default action for Filesystem sandboxing.
1198#[no_mangle]
1199pub extern "C" fn syd_default_fs(action: action_t) -> c_int {
1200    // Convert action_t enum to corresponding action string.
1201    let action = match Action::try_from(action) {
1202        Ok(action) => action,
1203        Err(_) => return -EINVAL,
1204    };
1205    stat(format!("/dev/syd/default/fs:{action}"))
1206}
1207
1208/// Set the default action for Walk Sandboxing.
1209#[no_mangle]
1210pub extern "C" fn syd_default_walk(action: action_t) -> c_int {
1211    // Convert action_t enum to corresponding action string.
1212    let action = match Action::try_from(action) {
1213        Ok(action) => action,
1214        Err(_) => return -EINVAL,
1215    };
1216    stat(format!("/dev/syd/default/walk:{action}"))
1217}
1218
1219/// Set the default action for List Sandboxing.
1220#[no_mangle]
1221pub extern "C" fn syd_default_list(action: action_t) -> c_int {
1222    // Convert action_t enum to corresponding action string.
1223    let action = match Action::try_from(action) {
1224        Ok(action) => action,
1225        Err(_) => return -EINVAL,
1226    };
1227    stat(format!("/dev/syd/default/list:{action}"))
1228}
1229
1230/// Set the default action for Stat Sandboxing.
1231#[no_mangle]
1232pub extern "C" fn syd_default_stat(action: action_t) -> c_int {
1233    // Convert action_t enum to corresponding action string.
1234    let action = match Action::try_from(action) {
1235        Ok(action) => action,
1236        Err(_) => return -EINVAL,
1237    };
1238    stat(format!("/dev/syd/default/stat:{action}"))
1239}
1240
1241/// Set the default action for Read Sandboxing.
1242#[no_mangle]
1243pub extern "C" fn syd_default_read(action: action_t) -> c_int {
1244    // Convert action_t enum to corresponding action string.
1245    let action = match Action::try_from(action) {
1246        Ok(action) => action,
1247        Err(_) => return -EINVAL,
1248    };
1249    stat(format!("/dev/syd/default/read:{action}"))
1250}
1251
1252/// Set the default action for Write Sandboxing.
1253#[no_mangle]
1254pub extern "C" fn syd_default_write(action: action_t) -> c_int {
1255    // Convert action_t enum to corresponding action string.
1256    let action = match Action::try_from(action) {
1257        Ok(action) => action,
1258        Err(_) => return -EINVAL,
1259    };
1260    stat(format!("/dev/syd/default/write:{action}"))
1261}
1262
1263/// Set the default action for Exec Sandboxing.
1264#[no_mangle]
1265pub extern "C" fn syd_default_exec(action: action_t) -> c_int {
1266    // Convert action_t enum to corresponding action string.
1267    let action = match Action::try_from(action) {
1268        Ok(action) => action,
1269        Err(_) => return -EINVAL,
1270    };
1271    stat(format!("/dev/syd/default/exec:{action}"))
1272}
1273
1274/// Set the default action for Ioctl Sandboxing.
1275#[no_mangle]
1276pub extern "C" fn syd_default_ioctl(action: action_t) -> c_int {
1277    // Convert action_t enum to corresponding action string.
1278    let action = match Action::try_from(action) {
1279        Ok(action) => action,
1280        Err(_) => return -EINVAL,
1281    };
1282    stat(format!("/dev/syd/default/ioctl:{action}"))
1283}
1284
1285/// Set the default action for Create Sandboxing.
1286#[no_mangle]
1287pub extern "C" fn syd_default_create(action: action_t) -> c_int {
1288    // Convert action_t enum to corresponding action string.
1289    let action = match Action::try_from(action) {
1290        Ok(action) => action,
1291        Err(_) => return -EINVAL,
1292    };
1293    stat(format!("/dev/syd/default/create:{action}"))
1294}
1295
1296/// Set the default action for Delete Sandboxing.
1297#[no_mangle]
1298pub extern "C" fn syd_default_delete(action: action_t) -> c_int {
1299    // Convert action_t enum to corresponding action string.
1300    let action = match Action::try_from(action) {
1301        Ok(action) => action,
1302        Err(_) => return -EINVAL,
1303    };
1304    stat(format!("/dev/syd/default/delete:{action}"))
1305}
1306
1307/// Set the default action for Rename Sandboxing.
1308#[no_mangle]
1309pub extern "C" fn syd_default_rename(action: action_t) -> c_int {
1310    // Convert action_t enum to corresponding action string.
1311    let action = match Action::try_from(action) {
1312        Ok(action) => action,
1313        Err(_) => return -EINVAL,
1314    };
1315    stat(format!("/dev/syd/default/rename:{action}"))
1316}
1317
1318/// Set the default action for Readlink Sandboxing.
1319#[no_mangle]
1320pub extern "C" fn syd_default_readlink(action: action_t) -> c_int {
1321    // Convert action_t enum to corresponding action string.
1322    let action = match Action::try_from(action) {
1323        Ok(action) => action,
1324        Err(_) => return -EINVAL,
1325    };
1326    stat(format!("/dev/syd/default/readlink:{action}"))
1327}
1328
1329/// Set the default action for Symlink Sandboxing.
1330#[no_mangle]
1331pub extern "C" fn syd_default_symlink(action: action_t) -> c_int {
1332    // Convert action_t enum to corresponding action string.
1333    let action = match Action::try_from(action) {
1334        Ok(action) => action,
1335        Err(_) => return -EINVAL,
1336    };
1337    stat(format!("/dev/syd/default/symlink:{action}"))
1338}
1339
1340/// Set the default action for Truncate Sandboxing.
1341#[no_mangle]
1342pub extern "C" fn syd_default_truncate(action: action_t) -> c_int {
1343    // Convert action_t enum to corresponding action string.
1344    let action = match Action::try_from(action) {
1345        Ok(action) => action,
1346        Err(_) => return -EINVAL,
1347    };
1348    stat(format!("/dev/syd/default/truncate:{action}"))
1349}
1350
1351/// Set the default action for Chdir Sandboxing.
1352#[no_mangle]
1353pub extern "C" fn syd_default_chdir(action: action_t) -> c_int {
1354    // Convert action_t enum to corresponding action string.
1355    let action = match Action::try_from(action) {
1356        Ok(action) => action,
1357        Err(_) => return -EINVAL,
1358    };
1359    stat(format!("/dev/syd/default/chdir:{action}"))
1360}
1361
1362/// Set the default action for Readdir Sandboxing.
1363#[no_mangle]
1364pub extern "C" fn syd_default_readdir(action: action_t) -> c_int {
1365    // Convert action_t enum to corresponding action string.
1366    let action = match Action::try_from(action) {
1367        Ok(action) => action,
1368        Err(_) => return -EINVAL,
1369    };
1370    stat(format!("/dev/syd/default/readdir:{action}"))
1371}
1372
1373/// Set the default action for Mkdir Sandboxing.
1374#[no_mangle]
1375pub extern "C" fn syd_default_mkdir(action: action_t) -> c_int {
1376    // Convert action_t enum to corresponding action string.
1377    let action = match Action::try_from(action) {
1378        Ok(action) => action,
1379        Err(_) => return -EINVAL,
1380    };
1381    stat(format!("/dev/syd/default/mkdir:{action}"))
1382}
1383
1384/// Set the default action for Rmdir Sandboxing.
1385#[no_mangle]
1386pub extern "C" fn syd_default_rmdir(action: action_t) -> c_int {
1387    // Convert action_t enum to corresponding action string.
1388    let action = match Action::try_from(action) {
1389        Ok(action) => action,
1390        Err(_) => return -EINVAL,
1391    };
1392    stat(format!("/dev/syd/default/rmdir:{action}"))
1393}
1394
1395/// Set the default action for Chown Sandboxing.
1396#[no_mangle]
1397pub extern "C" fn syd_default_chown(action: action_t) -> c_int {
1398    // Convert action_t enum to corresponding action string.
1399    let action = match Action::try_from(action) {
1400        Ok(action) => action,
1401        Err(_) => return -EINVAL,
1402    };
1403    stat(format!("/dev/syd/default/chown:{action}"))
1404}
1405
1406/// Set the default action for Chgrp Sandboxing.
1407#[no_mangle]
1408pub extern "C" fn syd_default_chgrp(action: action_t) -> c_int {
1409    // Convert action_t enum to corresponding action string.
1410    let action = match Action::try_from(action) {
1411        Ok(action) => action,
1412        Err(_) => return -EINVAL,
1413    };
1414    stat(format!("/dev/syd/default/chgrp:{action}"))
1415}
1416
1417/// Set the default action for Chmod Sandboxing.
1418#[no_mangle]
1419pub extern "C" fn syd_default_chmod(action: action_t) -> c_int {
1420    // Convert action_t enum to corresponding action string.
1421    let action = match Action::try_from(action) {
1422        Ok(action) => action,
1423        Err(_) => return -EINVAL,
1424    };
1425    stat(format!("/dev/syd/default/chmod:{action}"))
1426}
1427
1428/// Set the default action for Chattr Sandboxing.
1429#[no_mangle]
1430pub extern "C" fn syd_default_chattr(action: action_t) -> c_int {
1431    // Convert action_t enum to corresponding action string.
1432    let action = match Action::try_from(action) {
1433        Ok(action) => action,
1434        Err(_) => return -EINVAL,
1435    };
1436    stat(format!("/dev/syd/default/chattr:{action}"))
1437}
1438
1439/// Set the default action for Chroot Sandboxing.
1440#[no_mangle]
1441pub extern "C" fn syd_default_chroot(action: action_t) -> c_int {
1442    // Convert action_t enum to corresponding action string.
1443    let action = match Action::try_from(action) {
1444        Ok(action) => action,
1445        Err(_) => return -EINVAL,
1446    };
1447    stat(format!("/dev/syd/default/chroot:{action}"))
1448}
1449
1450/// Set the default action for Notify Sandboxing.
1451#[no_mangle]
1452pub extern "C" fn syd_default_notify(action: action_t) -> c_int {
1453    // Convert action_t enum to corresponding action string.
1454    let action = match Action::try_from(action) {
1455        Ok(action) => action,
1456        Err(_) => return -EINVAL,
1457    };
1458    stat(format!("/dev/syd/default/notify:{action}"))
1459}
1460
1461/// Set the default action for Utime Sandboxing.
1462#[no_mangle]
1463pub extern "C" fn syd_default_utime(action: action_t) -> c_int {
1464    // Convert action_t enum to corresponding action string.
1465    let action = match Action::try_from(action) {
1466        Ok(action) => action,
1467        Err(_) => return -EINVAL,
1468    };
1469    stat(format!("/dev/syd/default/utime:{action}"))
1470}
1471
1472/// Set the default action for Mkbdev Sandboxing.
1473#[no_mangle]
1474pub extern "C" fn syd_default_mkbdev(action: action_t) -> c_int {
1475    // Convert action_t enum to corresponding action string.
1476    let action = match Action::try_from(action) {
1477        Ok(action) => action,
1478        Err(_) => return -EINVAL,
1479    };
1480    stat(format!("/dev/syd/default/mkbdev:{action}"))
1481}
1482
1483/// Set the default action for Mkcdev Sandboxing.
1484#[no_mangle]
1485pub extern "C" fn syd_default_mkcdev(action: action_t) -> c_int {
1486    // Convert action_t enum to corresponding action string.
1487    let action = match Action::try_from(action) {
1488        Ok(action) => action,
1489        Err(_) => return -EINVAL,
1490    };
1491    stat(format!("/dev/syd/default/mkcdev:{action}"))
1492}
1493
1494/// Set the default action for Mkfifo Sandboxing.
1495#[no_mangle]
1496pub extern "C" fn syd_default_mkfifo(action: action_t) -> c_int {
1497    // Convert action_t enum to corresponding action string.
1498    let action = match Action::try_from(action) {
1499        Ok(action) => action,
1500        Err(_) => return -EINVAL,
1501    };
1502    stat(format!("/dev/syd/default/mkfifo:{action}"))
1503}
1504
1505/// Set the default action for Mktemp Sandboxing.
1506#[no_mangle]
1507pub extern "C" fn syd_default_mktemp(action: action_t) -> c_int {
1508    // Convert action_t enum to corresponding action string.
1509    let action = match Action::try_from(action) {
1510        Ok(action) => action,
1511        Err(_) => return -EINVAL,
1512    };
1513    stat(format!("/dev/syd/default/mktemp:{action}"))
1514}
1515
1516/// Set the default action for Network Sandboxing.
1517#[no_mangle]
1518pub extern "C" fn syd_default_net(action: action_t) -> c_int {
1519    // Convert action_t enum to corresponding action string.
1520    let action = match Action::try_from(action) {
1521        Ok(action) => action,
1522        Err(_) => return -EINVAL,
1523    };
1524    stat(format!("/dev/syd/default/net:{action}"))
1525}
1526
1527/// Set the default action for IP blocklist violations.
1528#[no_mangle]
1529pub extern "C" fn syd_default_block(action: action_t) -> c_int {
1530    // Convert action_t enum to corresponding action string.
1531    let action = match Action::try_from(action) {
1532        Ok(action) => action,
1533        Err(_) => return -EINVAL,
1534    };
1535    stat(format!("/dev/syd/default/block:{action}"))
1536}
1537
1538/// Set the default action for Memory Sandboxing.
1539#[no_mangle]
1540pub extern "C" fn syd_default_mem(action: action_t) -> c_int {
1541    // Convert action_t enum to corresponding action string.
1542    let action = match Action::try_from(action) {
1543        Ok(action) => action,
1544        Err(_) => return -EINVAL,
1545    };
1546    stat(format!("/dev/syd/default/mem:{action}"))
1547}
1548
1549/// Set the default action for PID Sandboxing.
1550#[no_mangle]
1551pub extern "C" fn syd_default_pid(action: action_t) -> c_int {
1552    // Convert action_t enum to corresponding action string.
1553    let action = match Action::try_from(action) {
1554        Ok(action) => action,
1555        Err(_) => return -EINVAL,
1556    };
1557    stat(format!("/dev/syd/default/pid:{action}"))
1558}
1559
1560/// Set the default action for Force Sandboxing.
1561#[no_mangle]
1562pub extern "C" fn syd_default_force(action: action_t) -> c_int {
1563    // Convert action_t enum to corresponding action string.
1564    let action = match Action::try_from(action) {
1565        Ok(action) => action,
1566        Err(_) => return -EINVAL,
1567    };
1568    stat(format!("/dev/syd/default/force:{action}"))
1569}
1570
1571/// Set the default action for `SegvGuard`
1572#[no_mangle]
1573pub extern "C" fn syd_default_segvguard(action: action_t) -> c_int {
1574    // Convert action_t enum to corresponding action string.
1575    let action = match Action::try_from(action) {
1576        Ok(action) => action,
1577        Err(_) => return -EINVAL,
1578    };
1579    stat(format!("/dev/syd/default/segvguard:{action}"))
1580}
1581
1582/// Set the default action for TPE Sandboxing.
1583#[no_mangle]
1584pub extern "C" fn syd_default_tpe(action: action_t) -> c_int {
1585    // Convert action_t enum to corresponding action string.
1586    let action = match Action::try_from(action) {
1587        Ok(action) => action,
1588        Err(_) => return -EINVAL,
1589    };
1590    stat(format!("/dev/syd/default/tpe:{action}"))
1591}
1592
1593/// Adds a request to the _ioctl_(2) denylist.
1594#[no_mangle]
1595pub extern "C" fn syd_ioctl_deny(request: u64) -> c_int {
1596    stat(format!("/dev/syd/deny/ioctl+{request}"))
1597}
1598
1599/// Adds an entry to the Integrity Force map for Force Sandboxing.
1600///
1601/// # Safety
1602///
1603/// This function is marked `unsafe` because it dereferences raw
1604/// pointers, which is inherently unsafe in Rust.
1605///
1606/// The caller must ensure the following conditions are met to safely
1607/// use this function:
1608///
1609/// 1. The `path` pointer must point to a valid, null-terminated C-style
1610///    string.
1611/// 2. The `alg` pointer must point to a valid, null-terminated C-style
1612///    string naming the hash algorithm (e.g. "sha3-512").
1613/// 3. The `hash` pointer must point to a valid, null-terminated C-style
1614///    string.
1615#[no_mangle]
1616pub unsafe extern "C" fn syd_force_add(
1617    path: *const c_char,
1618    alg: *const c_char,
1619    hash: *const c_char,
1620    action: action_t,
1621) -> c_int {
1622    // Convert action_t enum to corresponding action string.
1623    let action = match Action::try_from(action) {
1624        Ok(action) => action,
1625        Err(_) => return -EINVAL,
1626    };
1627
1628    if path.is_null() || alg.is_null() || hash.is_null() {
1629        return -EFAULT;
1630    }
1631
1632    // SAFETY: Trust that `path`, `alg` and `hash` are null-terminated strings.
1633    let path = unsafe { CStr::from_ptr(path) };
1634    // SAFETY: ditto.
1635    let alg = unsafe { CStr::from_ptr(alg) };
1636    // SAFETY: ditto.
1637    let hash = unsafe { CStr::from_ptr(hash) };
1638    let path = match path.to_str() {
1639        Ok(s) => s,
1640        Err(_) => return -EINVAL,
1641    };
1642    let alg = match alg.to_str() {
1643        Ok(s) => s,
1644        Err(_) => return -EINVAL,
1645    };
1646    let hash = match hash.to_str() {
1647        Ok(s) => s,
1648        Err(_) => return -EINVAL,
1649    };
1650
1651    // Call the stat function with the formatted string.
1652    stat(format!("/dev/syd/force+{path}:{alg}:{hash}:{action}"))
1653}
1654
1655/// Removes an entry from the Integrity Force map for Force Sandboxing.
1656/// # Safety
1657///
1658/// This function is marked `unsafe` because it dereferences raw
1659/// pointers, which is inherently unsafe in Rust.
1660///
1661/// The caller must ensure the following conditions are met to safely
1662/// use this function:
1663///
1664/// 1. The `path` pointer must point to a valid, null-terminated C-style
1665///    string.
1666#[no_mangle]
1667pub unsafe extern "C" fn syd_force_del(path: *const c_char) -> c_int {
1668    if path.is_null() {
1669        return -EFAULT;
1670    }
1671
1672    // SAFETY: Trust that `path` is a null-terminated string.
1673    let path = unsafe { CStr::from_ptr(path) };
1674    let path = match path.to_str() {
1675        Ok(s) => s,
1676        Err(_) => return -EINVAL,
1677    };
1678
1679    // Call the stat function with the formatted string.
1680    stat(format!("/dev/syd/force-{path}"))
1681}
1682
1683/// Clears the Integrity Force map for Force Sandboxing.
1684#[no_mangle]
1685pub extern "C" fn syd_force_clr() -> c_int {
1686    stat("/dev/syd/force^")
1687}
1688
1689/// Adds to the given actionlist of Filesystem sandboxing.
1690///
1691/// Returns 0 on success, negated errno on failure.
1692#[no_mangle]
1693pub extern "C" fn syd_fs_add(action: action_t, name: *const c_char) -> c_int {
1694    // Convert action_t enum to corresponding action string.
1695    let action = match Action::try_from(action) {
1696        Ok(action) => action,
1697        Err(_) => return -EINVAL,
1698    };
1699
1700    // Call magic function with add operator.
1701    esyd(format!("{action}/fs"), name, b'+')
1702}
1703
1704/// Removes the first instance from the end of the given actionlist of
1705/// Filesystem sandboxing.
1706///
1707/// Returns 0 on success, negated errno on failure.
1708#[no_mangle]
1709pub extern "C" fn syd_fs_del(action: action_t, name: *const c_char) -> c_int {
1710    // Convert action_t enum to corresponding action string.
1711    let action = match Action::try_from(action) {
1712        Ok(action) => action,
1713        Err(_) => return -EINVAL,
1714    };
1715
1716    // Call magic function with del operator.
1717    esyd(format!("{action}/fs"), name, b'-')
1718}
1719
1720/// Removes all matching patterns from the given actionlist of Filesystem sandboxing.
1721///
1722/// Returns 0 on success, negated errno on failure.
1723#[no_mangle]
1724pub extern "C" fn syd_fs_rem(action: action_t, name: *const c_char) -> c_int {
1725    // Convert action_t enum to corresponding action string.
1726    let action = match Action::try_from(action) {
1727        Ok(action) => action,
1728        Err(_) => return -EINVAL,
1729    };
1730
1731    // Call magic function with rem operator.
1732    esyd(format!("{action}/fs"), name, b'^')
1733}
1734
1735/// Adds to the given actionlist of walk sandboxing.
1736///
1737/// Returns 0 on success, negated errno on failure.
1738#[no_mangle]
1739pub extern "C" fn syd_walk_add(action: action_t, glob: *const c_char) -> c_int {
1740    // Convert action_t enum to corresponding action string.
1741    let action = match Action::try_from(action) {
1742        Ok(action) => action,
1743        Err(_) => return -EINVAL,
1744    };
1745
1746    // Call magic function with add operator.
1747    esyd(format!("{action}/walk"), glob, b'+')
1748}
1749
1750/// Removes the first instance from the end of the given actionlist of
1751/// walk sandboxing.
1752///
1753/// Returns 0 on success, negated errno on failure.
1754#[no_mangle]
1755pub extern "C" fn syd_walk_del(action: action_t, glob: *const c_char) -> c_int {
1756    // Convert action_t enum to corresponding action string.
1757    let action = match Action::try_from(action) {
1758        Ok(action) => action,
1759        Err(_) => return -EINVAL,
1760    };
1761
1762    // Call magic function with del operator.
1763    esyd(format!("{action}/walk"), glob, b'-')
1764}
1765
1766/// Removes all matching patterns from the given actionlist of walk sandboxing.
1767///
1768/// Returns 0 on success, negated errno on failure.
1769#[no_mangle]
1770pub extern "C" fn syd_walk_rem(action: action_t, glob: *const c_char) -> c_int {
1771    // Convert action_t enum to corresponding action string.
1772    let action = match Action::try_from(action) {
1773        Ok(action) => action,
1774        Err(_) => return -EINVAL,
1775    };
1776
1777    // Call magic function with rem operator.
1778    esyd(format!("{action}/walk"), glob, b'^')
1779}
1780
1781/// Adds to the given actionlist of list sandboxing.
1782///
1783/// Returns 0 on success, negated errno on failure.
1784#[no_mangle]
1785pub extern "C" fn syd_list_add(action: action_t, glob: *const c_char) -> c_int {
1786    // Convert action_t enum to corresponding action string.
1787    let action = match Action::try_from(action) {
1788        Ok(action) => action,
1789        Err(_) => return -EINVAL,
1790    };
1791
1792    // Call magic function with add operator.
1793    esyd(format!("{action}/list"), glob, b'+')
1794}
1795
1796/// Removes the first instance from the end of the given actionlist of
1797/// list sandboxing.
1798///
1799/// Returns 0 on success, negated errno on failure.
1800#[no_mangle]
1801pub extern "C" fn syd_list_del(action: action_t, glob: *const c_char) -> c_int {
1802    // Convert action_t enum to corresponding action string.
1803    let action = match Action::try_from(action) {
1804        Ok(action) => action,
1805        Err(_) => return -EINVAL,
1806    };
1807
1808    // Call magic function with del operator.
1809    esyd(format!("{action}/list"), glob, b'-')
1810}
1811
1812/// Removes all matching patterns from the given actionlist of list sandboxing.
1813///
1814/// Returns 0 on success, negated errno on failure.
1815#[no_mangle]
1816pub extern "C" fn syd_list_rem(action: action_t, glob: *const c_char) -> c_int {
1817    // Convert action_t enum to corresponding action string.
1818    let action = match Action::try_from(action) {
1819        Ok(action) => action,
1820        Err(_) => return -EINVAL,
1821    };
1822
1823    // Call magic function with rem operator.
1824    esyd(format!("{action}/list"), glob, b'^')
1825}
1826
1827/// Adds to the given actionlist of stat sandboxing.
1828///
1829/// Returns 0 on success, negated errno on failure.
1830#[no_mangle]
1831pub extern "C" fn syd_stat_add(action: action_t, glob: *const c_char) -> c_int {
1832    // Convert action_t enum to corresponding action string.
1833    let action = match Action::try_from(action) {
1834        Ok(action) => action,
1835        Err(_) => return -EINVAL,
1836    };
1837
1838    // Call magic function with add operator.
1839    esyd(format!("{action}/stat"), glob, b'+')
1840}
1841
1842/// Removes the first instance from the end of the given actionlist of
1843/// stat sandboxing.
1844///
1845/// Returns 0 on success, negated errno on failure.
1846#[no_mangle]
1847pub extern "C" fn syd_stat_del(action: action_t, glob: *const c_char) -> c_int {
1848    // Convert action_t enum to corresponding action string.
1849    let action = match Action::try_from(action) {
1850        Ok(action) => action,
1851        Err(_) => return -EINVAL,
1852    };
1853
1854    // Call magic function with del operator.
1855    esyd(format!("{action}/stat"), glob, b'-')
1856}
1857
1858/// Removes all matching patterns from the given actionlist of stat sandboxing.
1859///
1860/// Returns 0 on success, negated errno on failure.
1861#[no_mangle]
1862pub extern "C" fn syd_stat_rem(action: action_t, glob: *const c_char) -> c_int {
1863    // Convert action_t enum to corresponding action string.
1864    let action = match Action::try_from(action) {
1865        Ok(action) => action,
1866        Err(_) => return -EINVAL,
1867    };
1868
1869    // Call magic function with rem operator.
1870    esyd(format!("{action}/stat"), glob, b'^')
1871}
1872
1873/// Adds to the given actionlist of read sandboxing.
1874///
1875/// Returns 0 on success, negated errno on failure.
1876#[no_mangle]
1877pub extern "C" fn syd_read_add(action: action_t, glob: *const c_char) -> c_int {
1878    // Convert action_t enum to corresponding action string.
1879    let action = match Action::try_from(action) {
1880        Ok(action) => action,
1881        Err(_) => return -EINVAL,
1882    };
1883
1884    // Call magic function with add operator.
1885    esyd(format!("{action}/read"), glob, b'+')
1886}
1887
1888/// Removes the first instance from the end of the given actionlist of
1889/// read sandboxing.
1890///
1891/// Returns 0 on success, negated errno on failure.
1892#[no_mangle]
1893pub extern "C" fn syd_read_del(action: action_t, glob: *const c_char) -> c_int {
1894    // Convert action_t enum to corresponding action string.
1895    let action = match Action::try_from(action) {
1896        Ok(action) => action,
1897        Err(_) => return -EINVAL,
1898    };
1899
1900    // Call magic function with del operator.
1901    esyd(format!("{action}/read"), glob, b'-')
1902}
1903
1904/// Removes all matching patterns from the given actionlist of read sandboxing.
1905///
1906/// Returns 0 on success, negated errno on failure.
1907#[no_mangle]
1908pub extern "C" fn syd_read_rem(action: action_t, glob: *const c_char) -> c_int {
1909    // Convert action_t enum to corresponding action string.
1910    let action = match Action::try_from(action) {
1911        Ok(action) => action,
1912        Err(_) => return -EINVAL,
1913    };
1914
1915    // Call magic function with rem operator.
1916    esyd(format!("{action}/read"), glob, b'^')
1917}
1918
1919/// Adds to the given actionlist of write sandboxing.
1920///
1921/// Returns 0 on success, negated errno on failure.
1922#[no_mangle]
1923pub extern "C" fn syd_write_add(action: action_t, glob: *const c_char) -> c_int {
1924    // Convert action_t enum to corresponding action string.
1925    let action = match Action::try_from(action) {
1926        Ok(action) => action,
1927        Err(_) => return -EINVAL,
1928    };
1929
1930    // Call magic function with add operator.
1931    esyd(format!("{action}/write"), glob, b'+')
1932}
1933
1934/// Removes the first instance from the end of the given actionlist of
1935/// write sandboxing.
1936///
1937/// Returns 0 on success, negated errno on failure.
1938#[no_mangle]
1939pub extern "C" fn syd_write_del(action: action_t, glob: *const c_char) -> c_int {
1940    // Convert action_t enum to corresponding action string.
1941    let action = match Action::try_from(action) {
1942        Ok(action) => action,
1943        Err(_) => return -EINVAL,
1944    };
1945
1946    // Call magic function with del operator.
1947    esyd(format!("{action}/write"), glob, b'-')
1948}
1949
1950/// Removes all matching patterns from the given actionlist of write sandboxing.
1951///
1952/// Returns 0 on success, negated errno on failure.
1953#[no_mangle]
1954pub extern "C" fn syd_write_rem(action: action_t, glob: *const c_char) -> c_int {
1955    // Convert action_t enum to corresponding action string.
1956    let action = match Action::try_from(action) {
1957        Ok(action) => action,
1958        Err(_) => return -EINVAL,
1959    };
1960
1961    // Call magic function with rem operator.
1962    esyd(format!("{action}/write"), glob, b'^')
1963}
1964
1965/// Adds to the given actionlist of exec sandboxing.
1966///
1967/// Returns 0 on success, negated errno on failure.
1968#[no_mangle]
1969pub extern "C" fn syd_exec_add(action: action_t, glob: *const c_char) -> c_int {
1970    // Convert action_t enum to corresponding action string.
1971    let action = match Action::try_from(action) {
1972        Ok(action) => action,
1973        Err(_) => return -EINVAL,
1974    };
1975
1976    // Call magic function with add operator.
1977    esyd(format!("{action}/exec"), glob, b'+')
1978}
1979
1980/// Removes the first instance from the end of the given actionlist of
1981/// exec sandboxing.
1982///
1983/// Returns 0 on success, negated errno on failure.
1984#[no_mangle]
1985pub extern "C" fn syd_exec_del(action: action_t, glob: *const c_char) -> c_int {
1986    // Convert action_t enum to corresponding action string.
1987    let action = match Action::try_from(action) {
1988        Ok(action) => action,
1989        Err(_) => return -EINVAL,
1990    };
1991
1992    // Call magic function with del operator.
1993    esyd(format!("{action}/exec"), glob, b'-')
1994}
1995
1996/// Removes all matching patterns from the given actionlist of exec sandboxing.
1997///
1998/// Returns 0 on success, negated errno on failure.
1999#[no_mangle]
2000pub extern "C" fn syd_exec_rem(action: action_t, glob: *const c_char) -> c_int {
2001    // Convert action_t enum to corresponding action string.
2002    let action = match Action::try_from(action) {
2003        Ok(action) => action,
2004        Err(_) => return -EINVAL,
2005    };
2006
2007    // Call magic function with rem operator.
2008    esyd(format!("{action}/exec"), glob, b'^')
2009}
2010
2011/// Adds to the given actionlist of create sandboxing.
2012///
2013/// Returns 0 on success, negated errno on failure.
2014#[no_mangle]
2015pub extern "C" fn syd_create_add(action: action_t, glob: *const c_char) -> c_int {
2016    // Convert action_t enum to corresponding action string.
2017    let action = match Action::try_from(action) {
2018        Ok(action) => action,
2019        Err(_) => return -EINVAL,
2020    };
2021
2022    // Call magic function with add operator.
2023    esyd(format!("{action}/create"), glob, b'+')
2024}
2025
2026/// Removes the first instance from the end of the given actionlist of
2027/// create sandboxing.
2028///
2029/// Returns 0 on success, negated errno on failure.
2030#[no_mangle]
2031pub extern "C" fn syd_create_del(action: action_t, glob: *const c_char) -> c_int {
2032    // Convert action_t enum to corresponding action string.
2033    let action = match Action::try_from(action) {
2034        Ok(action) => action,
2035        Err(_) => return -EINVAL,
2036    };
2037
2038    // Call magic function with del operator.
2039    esyd(format!("{action}/create"), glob, b'-')
2040}
2041
2042/// Removes all matching patterns from the given actionlist of create sandboxing.
2043///
2044/// Returns 0 on success, negated errno on failure.
2045#[no_mangle]
2046pub extern "C" fn syd_create_rem(action: action_t, glob: *const c_char) -> c_int {
2047    // Convert action_t enum to corresponding action string.
2048    let action = match Action::try_from(action) {
2049        Ok(action) => action,
2050        Err(_) => return -EINVAL,
2051    };
2052
2053    // Call magic function with rem operator.
2054    esyd(format!("{action}/create"), glob, b'^')
2055}
2056
2057/// Adds to the given actionlist of delete sandboxing.
2058///
2059/// Returns 0 on success, negated errno on failure.
2060#[no_mangle]
2061pub extern "C" fn syd_delete_add(action: action_t, glob: *const c_char) -> c_int {
2062    // Convert action_t enum to corresponding action string.
2063    let action = match Action::try_from(action) {
2064        Ok(action) => action,
2065        Err(_) => return -EINVAL,
2066    };
2067
2068    // Call magic function with add operator.
2069    esyd(format!("{action}/delete"), glob, b'+')
2070}
2071
2072/// Removes the first instance from the end of the given actionlist of
2073/// delete sandboxing.
2074///
2075/// Returns 0 on success, negated errno on failure.
2076#[no_mangle]
2077pub extern "C" fn syd_delete_del(action: action_t, glob: *const c_char) -> c_int {
2078    // Convert action_t enum to corresponding action string.
2079    let action = match Action::try_from(action) {
2080        Ok(action) => action,
2081        Err(_) => return -EINVAL,
2082    };
2083
2084    // Call magic function with del operator.
2085    esyd(format!("{action}/delete"), glob, b'-')
2086}
2087
2088/// Removes all matching patterns from the given actionlist of delete sandboxing.
2089///
2090/// Returns 0 on success, negated errno on failure.
2091#[no_mangle]
2092pub extern "C" fn syd_delete_rem(action: action_t, glob: *const c_char) -> c_int {
2093    // Convert action_t enum to corresponding action string.
2094    let action = match Action::try_from(action) {
2095        Ok(action) => action,
2096        Err(_) => return -EINVAL,
2097    };
2098
2099    // Call magic function with rem operator.
2100    esyd(format!("{action}/delete"), glob, b'^')
2101}
2102
2103/// Adds to the given actionlist of rename sandboxing.
2104///
2105/// Returns 0 on success, negated errno on failure.
2106#[no_mangle]
2107pub extern "C" fn syd_rename_add(action: action_t, glob: *const c_char) -> c_int {
2108    // Convert action_t enum to corresponding action string.
2109    let action = match Action::try_from(action) {
2110        Ok(action) => action,
2111        Err(_) => return -EINVAL,
2112    };
2113
2114    // Call magic function with add operator.
2115    esyd(format!("{action}/rename"), glob, b'+')
2116}
2117
2118/// Removes the first instance from the end of the given actionlist of
2119/// rename sandboxing.
2120///
2121/// Returns 0 on success, negated errno on failure.
2122#[no_mangle]
2123pub extern "C" fn syd_rename_del(action: action_t, glob: *const c_char) -> c_int {
2124    // Convert action_t enum to corresponding action string.
2125    let action = match Action::try_from(action) {
2126        Ok(action) => action,
2127        Err(_) => return -EINVAL,
2128    };
2129
2130    // Call magic function with del operator.
2131    esyd(format!("{action}/rename"), glob, b'-')
2132}
2133
2134/// Removes all matching patterns from the given actionlist of rename sandboxing.
2135///
2136/// Returns 0 on success, negated errno on failure.
2137#[no_mangle]
2138pub extern "C" fn syd_rename_rem(action: action_t, glob: *const c_char) -> c_int {
2139    // Convert action_t enum to corresponding action string.
2140    let action = match Action::try_from(action) {
2141        Ok(action) => action,
2142        Err(_) => return -EINVAL,
2143    };
2144
2145    // Call magic function with rem operator.
2146    esyd(format!("{action}/rename"), glob, b'^')
2147}
2148
2149/// Adds to the given actionlist of readlink sandboxing.
2150///
2151/// Returns 0 on success, negated errno on failure.
2152#[no_mangle]
2153pub extern "C" fn syd_readlink_add(action: action_t, glob: *const c_char) -> c_int {
2154    // Convert action_t enum to corresponding action string.
2155    let action = match Action::try_from(action) {
2156        Ok(action) => action,
2157        Err(_) => return -EINVAL,
2158    };
2159
2160    // Call magic function with add operator.
2161    esyd(format!("{action}/readlink"), glob, b'+')
2162}
2163
2164/// Removes the first instance from the end of the given actionlist of
2165/// readlink sandboxing.
2166///
2167/// Returns 0 on success, negated errno on failure.
2168#[no_mangle]
2169pub extern "C" fn syd_readlink_del(action: action_t, glob: *const c_char) -> c_int {
2170    // Convert action_t enum to corresponding action string.
2171    let action = match Action::try_from(action) {
2172        Ok(action) => action,
2173        Err(_) => return -EINVAL,
2174    };
2175
2176    // Call magic function with del operator.
2177    esyd(format!("{action}/readlink"), glob, b'-')
2178}
2179
2180/// Removes all matching patterns from the given actionlist of readlink sandboxing.
2181///
2182/// Returns 0 on success, negated errno on failure.
2183#[no_mangle]
2184pub extern "C" fn syd_readlink_rem(action: action_t, glob: *const c_char) -> c_int {
2185    // Convert action_t enum to corresponding action string.
2186    let action = match Action::try_from(action) {
2187        Ok(action) => action,
2188        Err(_) => return -EINVAL,
2189    };
2190
2191    // Call magic function with rem operator.
2192    esyd(format!("{action}/readlink"), glob, b'^')
2193}
2194
2195/// Adds to the given actionlist of symlink sandboxing.
2196///
2197/// Returns 0 on success, negated errno on failure.
2198#[no_mangle]
2199pub extern "C" fn syd_symlink_add(action: action_t, glob: *const c_char) -> c_int {
2200    // Convert action_t enum to corresponding action string.
2201    let action = match Action::try_from(action) {
2202        Ok(action) => action,
2203        Err(_) => return -EINVAL,
2204    };
2205
2206    // Call magic function with add operator.
2207    esyd(format!("{action}/symlink"), glob, b'+')
2208}
2209
2210/// Removes the first instance from the end of the given actionlist of
2211/// symlink sandboxing.
2212///
2213/// Returns 0 on success, negated errno on failure.
2214#[no_mangle]
2215pub extern "C" fn syd_symlink_del(action: action_t, glob: *const c_char) -> c_int {
2216    // Convert action_t enum to corresponding action string.
2217    let action = match Action::try_from(action) {
2218        Ok(action) => action,
2219        Err(_) => return -EINVAL,
2220    };
2221
2222    // Call magic function with del operator.
2223    esyd(format!("{action}/symlink"), glob, b'-')
2224}
2225
2226/// Removes all matching patterns from the given actionlist of symlink sandboxing.
2227///
2228/// Returns 0 on success, negated errno on failure.
2229#[no_mangle]
2230pub extern "C" fn syd_symlink_rem(action: action_t, glob: *const c_char) -> c_int {
2231    // Convert action_t enum to corresponding action string.
2232    let action = match Action::try_from(action) {
2233        Ok(action) => action,
2234        Err(_) => return -EINVAL,
2235    };
2236
2237    // Call magic function with rem operator.
2238    esyd(format!("{action}/symlink"), glob, b'^')
2239}
2240
2241/// Adds to the given actionlist of truncate sandboxing.
2242///
2243/// Returns 0 on success, negated errno on failure.
2244#[no_mangle]
2245pub extern "C" fn syd_truncate_add(action: action_t, glob: *const c_char) -> c_int {
2246    // Convert action_t enum to corresponding action string.
2247    let action = match Action::try_from(action) {
2248        Ok(action) => action,
2249        Err(_) => return -EINVAL,
2250    };
2251
2252    // Call magic function with add operator.
2253    esyd(format!("{action}/truncate"), glob, b'+')
2254}
2255
2256/// Removes the first instance from the end of the given actionlist of
2257/// truncate sandboxing.
2258///
2259/// Returns 0 on success, negated errno on failure.
2260#[no_mangle]
2261pub extern "C" fn syd_truncate_del(action: action_t, glob: *const c_char) -> c_int {
2262    // Convert action_t enum to corresponding action string.
2263    let action = match Action::try_from(action) {
2264        Ok(action) => action,
2265        Err(_) => return -EINVAL,
2266    };
2267
2268    // Call magic function with del operator.
2269    esyd(format!("{action}/truncate"), glob, b'-')
2270}
2271
2272/// Removes all matching patterns from the given actionlist of truncate sandboxing.
2273///
2274/// Returns 0 on success, negated errno on failure.
2275#[no_mangle]
2276pub extern "C" fn syd_truncate_rem(action: action_t, glob: *const c_char) -> c_int {
2277    // Convert action_t enum to corresponding action string.
2278    let action = match Action::try_from(action) {
2279        Ok(action) => action,
2280        Err(_) => return -EINVAL,
2281    };
2282
2283    // Call magic function with rem operator.
2284    esyd(format!("{action}/truncate"), glob, b'^')
2285}
2286
2287/// Adds to the given actionlist of chdir sandboxing.
2288///
2289/// Returns 0 on success, negated errno on failure.
2290#[no_mangle]
2291pub extern "C" fn syd_chdir_add(action: action_t, glob: *const c_char) -> c_int {
2292    // Convert action_t enum to corresponding action string.
2293    let action = match Action::try_from(action) {
2294        Ok(action) => action,
2295        Err(_) => return -EINVAL,
2296    };
2297
2298    // Call magic function with add operator.
2299    esyd(format!("{action}/chdir"), glob, b'+')
2300}
2301
2302/// Removes the first instance from the end of the given actionlist of
2303/// chdir sandboxing.
2304///
2305/// Returns 0 on success, negated errno on failure.
2306#[no_mangle]
2307pub extern "C" fn syd_chdir_del(action: action_t, glob: *const c_char) -> c_int {
2308    // Convert action_t enum to corresponding action string.
2309    let action = match Action::try_from(action) {
2310        Ok(action) => action,
2311        Err(_) => return -EINVAL,
2312    };
2313
2314    // Call magic function with del operator.
2315    esyd(format!("{action}/chdir"), glob, b'-')
2316}
2317
2318/// Removes all matching patterns from the given actionlist of chdir sandboxing.
2319///
2320/// Returns 0 on success, negated errno on failure.
2321#[no_mangle]
2322pub extern "C" fn syd_chdir_rem(action: action_t, glob: *const c_char) -> c_int {
2323    // Convert action_t enum to corresponding action string.
2324    let action = match Action::try_from(action) {
2325        Ok(action) => action,
2326        Err(_) => return -EINVAL,
2327    };
2328
2329    // Call magic function with rem operator.
2330    esyd(format!("{action}/chdir"), glob, b'^')
2331}
2332
2333/// Adds to the given actionlist of readdir sandboxing.
2334///
2335/// Returns 0 on success, negated errno on failure.
2336#[no_mangle]
2337pub extern "C" fn syd_readdir_add(action: action_t, glob: *const c_char) -> c_int {
2338    // Convert action_t enum to corresponding action string.
2339    let action = match Action::try_from(action) {
2340        Ok(action) => action,
2341        Err(_) => return -EINVAL,
2342    };
2343
2344    // Call magic function with add operator.
2345    esyd(format!("{action}/readdir"), glob, b'+')
2346}
2347
2348/// Removes the first instance from the end of the given actionlist of
2349/// readdir sandboxing.
2350///
2351/// Returns 0 on success, negated errno on failure.
2352#[no_mangle]
2353pub extern "C" fn syd_readdir_del(action: action_t, glob: *const c_char) -> c_int {
2354    // Convert action_t enum to corresponding action string.
2355    let action = match Action::try_from(action) {
2356        Ok(action) => action,
2357        Err(_) => return -EINVAL,
2358    };
2359
2360    // Call magic function with del operator.
2361    esyd(format!("{action}/readdir"), glob, b'-')
2362}
2363
2364/// Removes all matching patterns from the given actionlist of readdir sandboxing.
2365///
2366/// Returns 0 on success, negated errno on failure.
2367#[no_mangle]
2368pub extern "C" fn syd_readdir_rem(action: action_t, glob: *const c_char) -> c_int {
2369    // Convert action_t enum to corresponding action string.
2370    let action = match Action::try_from(action) {
2371        Ok(action) => action,
2372        Err(_) => return -EINVAL,
2373    };
2374
2375    // Call magic function with del operator.
2376    esyd(format!("{action}/readdir"), glob, b'^')
2377}
2378
2379/// Adds to the given actionlist of mkdir sandboxing.
2380///
2381/// Returns 0 on success, negated errno on failure.
2382#[no_mangle]
2383pub extern "C" fn syd_mkdir_add(action: action_t, glob: *const c_char) -> c_int {
2384    // Convert action_t enum to corresponding action string.
2385    let action = match Action::try_from(action) {
2386        Ok(action) => action,
2387        Err(_) => return -EINVAL,
2388    };
2389
2390    // Call magic function with add operator.
2391    esyd(format!("{action}/mkdir"), glob, b'+')
2392}
2393
2394/// Removes the first instance from the end of the given actionlist of
2395/// mkdir sandboxing.
2396///
2397/// Returns 0 on success, negated errno on failure.
2398#[no_mangle]
2399pub extern "C" fn syd_mkdir_del(action: action_t, glob: *const c_char) -> c_int {
2400    // Convert action_t enum to corresponding action string.
2401    let action = match Action::try_from(action) {
2402        Ok(action) => action,
2403        Err(_) => return -EINVAL,
2404    };
2405
2406    // Call magic function with del operator.
2407    esyd(format!("{action}/mkdir"), glob, b'-')
2408}
2409
2410/// Removes all matching patterns from the given actionlist of mkdir sandboxing.
2411///
2412/// Returns 0 on success, negated errno on failure.
2413#[no_mangle]
2414pub extern "C" fn syd_mkdir_rem(action: action_t, glob: *const c_char) -> c_int {
2415    // Convert action_t enum to corresponding action string.
2416    let action = match Action::try_from(action) {
2417        Ok(action) => action,
2418        Err(_) => return -EINVAL,
2419    };
2420
2421    // Call magic function with del operator.
2422    esyd(format!("{action}/mkdir"), glob, b'^')
2423}
2424
2425/// Adds to the given actionlist of rmdir sandboxing.
2426///
2427/// Returns 0 on success, negated errno on failure.
2428#[no_mangle]
2429pub extern "C" fn syd_rmdir_add(action: action_t, glob: *const c_char) -> c_int {
2430    // Convert action_t enum to corresponding action string.
2431    let action = match Action::try_from(action) {
2432        Ok(action) => action,
2433        Err(_) => return -EINVAL,
2434    };
2435
2436    // Call magic function with add operator.
2437    esyd(format!("{action}/rmdir"), glob, b'+')
2438}
2439
2440/// Removes the first instance from the end of the given actionlist of
2441/// rmdir sandboxing.
2442///
2443/// Returns 0 on success, negated errno on failure.
2444#[no_mangle]
2445pub extern "C" fn syd_rmdir_del(action: action_t, glob: *const c_char) -> c_int {
2446    // Convert action_t enum to corresponding action string.
2447    let action = match Action::try_from(action) {
2448        Ok(action) => action,
2449        Err(_) => return -EINVAL,
2450    };
2451
2452    // Call magic function with del operator.
2453    esyd(format!("{action}/rmdir"), glob, b'-')
2454}
2455
2456/// Removes all matching patterns from the given actionlist of rmdir sandboxing.
2457///
2458/// Returns 0 on success, negated errno on failure.
2459#[no_mangle]
2460pub extern "C" fn syd_rmdir_rem(action: action_t, glob: *const c_char) -> c_int {
2461    // Convert action_t enum to corresponding action string.
2462    let action = match Action::try_from(action) {
2463        Ok(action) => action,
2464        Err(_) => return -EINVAL,
2465    };
2466
2467    // Call magic function with del operator.
2468    esyd(format!("{action}/rmdir"), glob, b'^')
2469}
2470
2471/// Adds to the given actionlist of chown sandboxing.
2472///
2473/// Returns 0 on success, negated errno on failure.
2474#[no_mangle]
2475pub extern "C" fn syd_chown_add(action: action_t, glob: *const c_char) -> c_int {
2476    // Convert action_t enum to corresponding action string.
2477    let action = match Action::try_from(action) {
2478        Ok(action) => action,
2479        Err(_) => return -EINVAL,
2480    };
2481
2482    // Call magic function with add operator.
2483    esyd(format!("{action}/chown"), glob, b'+')
2484}
2485
2486/// Removes the first instance from the end of the given actionlist of
2487/// chown sandboxing.
2488///
2489/// Returns 0 on success, negated errno on failure.
2490#[no_mangle]
2491pub extern "C" fn syd_chown_del(action: action_t, glob: *const c_char) -> c_int {
2492    // Convert action_t enum to corresponding action string.
2493    let action = match Action::try_from(action) {
2494        Ok(action) => action,
2495        Err(_) => return -EINVAL,
2496    };
2497
2498    // Call magic function with del operator.
2499    esyd(format!("{action}/chown"), glob, b'-')
2500}
2501
2502/// Removes all matching patterns from the given actionlist of chown sandboxing.
2503///
2504/// Returns 0 on success, negated errno on failure.
2505#[no_mangle]
2506pub extern "C" fn syd_chown_rem(action: action_t, glob: *const c_char) -> c_int {
2507    // Convert action_t enum to corresponding action string.
2508    let action = match Action::try_from(action) {
2509        Ok(action) => action,
2510        Err(_) => return -EINVAL,
2511    };
2512
2513    // Call magic function with rem operator.
2514    esyd(format!("{action}/chown"), glob, b'^')
2515}
2516
2517/// Adds to the given actionlist of chgrp sandboxing.
2518///
2519/// Returns 0 on success, negated errno on failure.
2520#[no_mangle]
2521pub extern "C" fn syd_chgrp_add(action: action_t, glob: *const c_char) -> c_int {
2522    // Convert action_t enum to corresponding action string.
2523    let action = match Action::try_from(action) {
2524        Ok(action) => action,
2525        Err(_) => return -EINVAL,
2526    };
2527
2528    // Call magic function with add operator.
2529    esyd(format!("{action}/chgrp"), glob, b'+')
2530}
2531
2532/// Removes the first instance from the end of the given actionlist of
2533/// chgrp sandboxing.
2534///
2535/// Returns 0 on success, negated errno on failure.
2536#[no_mangle]
2537pub extern "C" fn syd_chgrp_del(action: action_t, glob: *const c_char) -> c_int {
2538    // Convert action_t enum to corresponding action string.
2539    let action = match Action::try_from(action) {
2540        Ok(action) => action,
2541        Err(_) => return -EINVAL,
2542    };
2543
2544    // Call magic function with del operator.
2545    esyd(format!("{action}/chgrp"), glob, b'-')
2546}
2547
2548/// Removes all matching patterns from the given actionlist of chgrp sandboxing.
2549///
2550/// Returns 0 on success, negated errno on failure.
2551#[no_mangle]
2552pub extern "C" fn syd_chgrp_rem(action: action_t, glob: *const c_char) -> c_int {
2553    // Convert action_t enum to corresponding action string.
2554    let action = match Action::try_from(action) {
2555        Ok(action) => action,
2556        Err(_) => return -EINVAL,
2557    };
2558
2559    // Call magic function with rem operator.
2560    esyd(format!("{action}/chgrp"), glob, b'^')
2561}
2562
2563/// Adds to the given actionlist of chmod sandboxing.
2564///
2565/// Returns 0 on success, negated errno on failure.
2566#[no_mangle]
2567pub extern "C" fn syd_chmod_add(action: action_t, glob: *const c_char) -> c_int {
2568    // Convert action_t enum to corresponding action string.
2569    let action = match Action::try_from(action) {
2570        Ok(action) => action,
2571        Err(_) => return -EINVAL,
2572    };
2573
2574    // Call magic function with add operator.
2575    esyd(format!("{action}/chmod"), glob, b'+')
2576}
2577
2578/// Removes the first instance from the end of the given actionlist of
2579/// chmod sandboxing.
2580///
2581/// Returns 0 on success, negated errno on failure.
2582#[no_mangle]
2583pub extern "C" fn syd_chmod_del(action: action_t, glob: *const c_char) -> c_int {
2584    // Convert action_t enum to corresponding action string.
2585    let action = match Action::try_from(action) {
2586        Ok(action) => action,
2587        Err(_) => return -EINVAL,
2588    };
2589
2590    // Call magic function with del operator.
2591    esyd(format!("{action}/chmod"), glob, b'-')
2592}
2593
2594/// Removes all matching patterns from the given actionlist of chmod sandboxing.
2595///
2596/// Returns 0 on success, negated errno on failure.
2597#[no_mangle]
2598pub extern "C" fn syd_chmod_rem(action: action_t, glob: *const c_char) -> c_int {
2599    // Convert action_t enum to corresponding action string.
2600    let action = match Action::try_from(action) {
2601        Ok(action) => action,
2602        Err(_) => return -EINVAL,
2603    };
2604
2605    // Call magic function with rem operator.
2606    esyd(format!("{action}/chmod"), glob, b'^')
2607}
2608
2609/// Adds to the given actionlist of chattr sandboxing.
2610///
2611/// Returns 0 on success, negated errno on failure.
2612#[no_mangle]
2613pub extern "C" fn syd_chattr_add(action: action_t, glob: *const c_char) -> c_int {
2614    // Convert action_t enum to corresponding action string.
2615    let action = match Action::try_from(action) {
2616        Ok(action) => action,
2617        Err(_) => return -EINVAL,
2618    };
2619
2620    // Call magic function with add operator.
2621    esyd(format!("{action}/chattr"), glob, b'+')
2622}
2623
2624/// Removes the first instance from the end of the given actionlist of
2625/// chattr sandboxing.
2626///
2627/// Returns 0 on success, negated errno on failure.
2628#[no_mangle]
2629pub extern "C" fn syd_chattr_del(action: action_t, glob: *const c_char) -> c_int {
2630    // Convert action_t enum to corresponding action string.
2631    let action = match Action::try_from(action) {
2632        Ok(action) => action,
2633        Err(_) => return -EINVAL,
2634    };
2635
2636    // Call magic function with del operator.
2637    esyd(format!("{action}/chattr"), glob, b'-')
2638}
2639
2640/// Removes all matching patterns from the given actionlist of chattr sandboxing.
2641///
2642/// Returns 0 on success, negated errno on failure.
2643#[no_mangle]
2644pub extern "C" fn syd_chattr_rem(action: action_t, glob: *const c_char) -> c_int {
2645    // Convert action_t enum to corresponding action string.
2646    let action = match Action::try_from(action) {
2647        Ok(action) => action,
2648        Err(_) => return -EINVAL,
2649    };
2650
2651    // Call magic function with rem operator.
2652    esyd(format!("{action}/chattr"), glob, b'^')
2653}
2654
2655/// Adds to the given actionlist of chroot sandboxing.
2656///
2657/// Returns 0 on success, negated errno on failure.
2658#[no_mangle]
2659pub extern "C" fn syd_chroot_add(action: action_t, glob: *const c_char) -> c_int {
2660    // Convert action_t enum to corresponding action string.
2661    let action = match Action::try_from(action) {
2662        Ok(action) => action,
2663        Err(_) => return -EINVAL,
2664    };
2665
2666    // Call magic function with add operator.
2667    esyd(format!("{action}/chroot"), glob, b'+')
2668}
2669
2670/// Removes the first instance from the end of the given actionlist of
2671/// chroot sandboxing.
2672///
2673/// Returns 0 on success, negated errno on failure.
2674#[no_mangle]
2675pub extern "C" fn syd_chroot_del(action: action_t, glob: *const c_char) -> c_int {
2676    // Convert action_t enum to corresponding action string.
2677    let action = match Action::try_from(action) {
2678        Ok(action) => action,
2679        Err(_) => return -EINVAL,
2680    };
2681
2682    // Call magic function with del operator.
2683    esyd(format!("{action}/chroot"), glob, b'-')
2684}
2685
2686/// Removes all matching patterns from the given actionlist of chroot sandboxing.
2687///
2688/// Returns 0 on success, negated errno on failure.
2689#[no_mangle]
2690pub extern "C" fn syd_chroot_rem(action: action_t, glob: *const c_char) -> c_int {
2691    // Convert action_t enum to corresponding action string.
2692    let action = match Action::try_from(action) {
2693        Ok(action) => action,
2694        Err(_) => return -EINVAL,
2695    };
2696
2697    // Call magic function with rem operator.
2698    esyd(format!("{action}/chroot"), glob, b'^')
2699}
2700
2701/// Adds to the given actionlist of notify sandboxing.
2702///
2703/// Returns 0 on success, negated errno on failure.
2704#[no_mangle]
2705pub extern "C" fn syd_notify_add(action: action_t, glob: *const c_char) -> c_int {
2706    // Convert action_t enum to corresponding action string.
2707    let action = match Action::try_from(action) {
2708        Ok(action) => action,
2709        Err(_) => return -EINVAL,
2710    };
2711
2712    // Call magic function with add operator.
2713    esyd(format!("{action}/notify"), glob, b'+')
2714}
2715
2716/// Removes the first instance from the end of the given actionlist of
2717/// notify sandboxing.
2718///
2719/// Returns 0 on success, negated errno on failure.
2720#[no_mangle]
2721pub extern "C" fn syd_notify_del(action: action_t, glob: *const c_char) -> c_int {
2722    // Convert action_t enum to corresponding action string.
2723    let action = match Action::try_from(action) {
2724        Ok(action) => action,
2725        Err(_) => return -EINVAL,
2726    };
2727
2728    // Call magic function with del operator.
2729    esyd(format!("{action}/notify"), glob, b'-')
2730}
2731
2732/// Removes all matching patterns from the given actionlist of notify sandboxing.
2733///
2734/// Returns 0 on success, negated errno on failure.
2735#[no_mangle]
2736pub extern "C" fn syd_notify_rem(action: action_t, glob: *const c_char) -> c_int {
2737    // Convert action_t enum to corresponding action string.
2738    let action = match Action::try_from(action) {
2739        Ok(action) => action,
2740        Err(_) => return -EINVAL,
2741    };
2742
2743    // Call magic function with rem operator.
2744    esyd(format!("{action}/notify"), glob, b'^')
2745}
2746
2747/// Adds to the given actionlist of utime sandboxing.
2748///
2749/// Returns 0 on success, negated errno on failure.
2750#[no_mangle]
2751pub extern "C" fn syd_utime_add(action: action_t, glob: *const c_char) -> c_int {
2752    // Convert action_t enum to corresponding action string.
2753    let action = match Action::try_from(action) {
2754        Ok(action) => action,
2755        Err(_) => return -EINVAL,
2756    };
2757
2758    // Call magic function with add operator.
2759    esyd(format!("{action}/utime"), glob, b'+')
2760}
2761
2762/// Removes the first instance from the end of the given actionlist of
2763/// utime sandboxing.
2764///
2765/// Returns 0 on success, negated errno on failure.
2766#[no_mangle]
2767pub extern "C" fn syd_utime_del(action: action_t, glob: *const c_char) -> c_int {
2768    // Convert action_t enum to corresponding action string.
2769    let action = match Action::try_from(action) {
2770        Ok(action) => action,
2771        Err(_) => return -EINVAL,
2772    };
2773
2774    // Call magic function with del operator.
2775    esyd(format!("{action}/utime"), glob, b'-')
2776}
2777
2778/// Removes all matching patterns from the given actionlist of utime sandboxing.
2779///
2780/// Returns 0 on success, negated errno on failure.
2781#[no_mangle]
2782pub extern "C" fn syd_utime_rem(action: action_t, glob: *const c_char) -> c_int {
2783    // Convert action_t enum to corresponding action string.
2784    let action = match Action::try_from(action) {
2785        Ok(action) => action,
2786        Err(_) => return -EINVAL,
2787    };
2788
2789    // Call magic function with rem operator.
2790    esyd(format!("{action}/utime"), glob, b'^')
2791}
2792
2793/// Adds to the given actionlist of mkbdev sandboxing.
2794///
2795/// Returns 0 on success, negated errno on failure.
2796#[no_mangle]
2797pub extern "C" fn syd_mkbdev_add(action: action_t, glob: *const c_char) -> c_int {
2798    // Convert action_t enum to corresponding action string.
2799    let action = match Action::try_from(action) {
2800        Ok(action) => action,
2801        Err(_) => return -EINVAL,
2802    };
2803
2804    // Call magic function with add operator.
2805    esyd(format!("{action}/mkbdev"), glob, b'+')
2806}
2807
2808/// Removes the first instance from the end of the given actionlist of
2809/// mkbdev sandboxing.
2810///
2811/// Returns 0 on success, negated errno on failure.
2812#[no_mangle]
2813pub extern "C" fn syd_mkbdev_del(action: action_t, glob: *const c_char) -> c_int {
2814    // Convert action_t enum to corresponding action string.
2815    let action = match Action::try_from(action) {
2816        Ok(action) => action,
2817        Err(_) => return -EINVAL,
2818    };
2819
2820    // Call magic function with del operator.
2821    esyd(format!("{action}/mkbdev"), glob, b'-')
2822}
2823
2824/// Removes all matching patterns from the given actionlist of mkbdev sandboxing.
2825///
2826/// Returns 0 on success, negated errno on failure.
2827#[no_mangle]
2828pub extern "C" fn syd_mkbdev_rem(action: action_t, glob: *const c_char) -> c_int {
2829    // Convert action_t enum to corresponding action string.
2830    let action = match Action::try_from(action) {
2831        Ok(action) => action,
2832        Err(_) => return -EINVAL,
2833    };
2834
2835    // Call magic function with rem operator.
2836    esyd(format!("{action}/mkbdev"), glob, b'^')
2837}
2838
2839/// Adds to the given actionlist of mkcdev sandboxing.
2840///
2841/// Returns 0 on success, negated errno on failure.
2842#[no_mangle]
2843pub extern "C" fn syd_mkcdev_add(action: action_t, glob: *const c_char) -> c_int {
2844    // Convert action_t enum to corresponding action string.
2845    let action = match Action::try_from(action) {
2846        Ok(action) => action,
2847        Err(_) => return -EINVAL,
2848    };
2849
2850    // Call magic function with add operator.
2851    esyd(format!("{action}/mkcdev"), glob, b'+')
2852}
2853
2854/// Removes the first instance from the end of the given actionlist of
2855/// mkcdev sandboxing.
2856///
2857/// Returns 0 on success, negated errno on failure.
2858#[no_mangle]
2859pub extern "C" fn syd_mkcdev_del(action: action_t, glob: *const c_char) -> c_int {
2860    // Convert action_t enum to corresponding action string.
2861    let action = match Action::try_from(action) {
2862        Ok(action) => action,
2863        Err(_) => return -EINVAL,
2864    };
2865
2866    // Call magic function with del operator.
2867    esyd(format!("{action}/mkcdev"), glob, b'-')
2868}
2869
2870/// Removes all matching patterns from the given actionlist of mkcdev sandboxing.
2871///
2872/// Returns 0 on success, negated errno on failure.
2873#[no_mangle]
2874pub extern "C" fn syd_mkcdev_rem(action: action_t, glob: *const c_char) -> c_int {
2875    // Convert action_t enum to corresponding action string.
2876    let action = match Action::try_from(action) {
2877        Ok(action) => action,
2878        Err(_) => return -EINVAL,
2879    };
2880
2881    // Call magic function with rem operator.
2882    esyd(format!("{action}/mkcdev"), glob, b'^')
2883}
2884
2885/// Adds to the given actionlist of mkfifo sandboxing.
2886///
2887/// Returns 0 on success, negated errno on failure.
2888#[no_mangle]
2889pub extern "C" fn syd_mkfifo_add(action: action_t, glob: *const c_char) -> c_int {
2890    // Convert action_t enum to corresponding action string.
2891    let action = match Action::try_from(action) {
2892        Ok(action) => action,
2893        Err(_) => return -EINVAL,
2894    };
2895
2896    // Call magic function with add operator.
2897    esyd(format!("{action}/mkfifo"), glob, b'+')
2898}
2899
2900/// Removes the first instance from the end of the given actionlist of
2901/// mkfifo sandboxing.
2902///
2903/// Returns 0 on success, negated errno on failure.
2904#[no_mangle]
2905pub extern "C" fn syd_mkfifo_del(action: action_t, glob: *const c_char) -> c_int {
2906    // Convert action_t enum to corresponding action string.
2907    let action = match Action::try_from(action) {
2908        Ok(action) => action,
2909        Err(_) => return -EINVAL,
2910    };
2911
2912    // Call magic function with del operator.
2913    esyd(format!("{action}/mkfifo"), glob, b'-')
2914}
2915
2916/// Removes all matching patterns from the given actionlist of mkfifo sandboxing.
2917///
2918/// Returns 0 on success, negated errno on failure.
2919#[no_mangle]
2920pub extern "C" fn syd_mkfifo_rem(action: action_t, glob: *const c_char) -> c_int {
2921    // Convert action_t enum to corresponding action string.
2922    let action = match Action::try_from(action) {
2923        Ok(action) => action,
2924        Err(_) => return -EINVAL,
2925    };
2926
2927    // Call magic function with rem operator.
2928    esyd(format!("{action}/mkfifo"), glob, b'^')
2929}
2930
2931/// Adds to the given actionlist of mktemp sandboxing.
2932///
2933/// Returns 0 on success, negated errno on failure.
2934#[no_mangle]
2935pub extern "C" fn syd_mktemp_add(action: action_t, glob: *const c_char) -> c_int {
2936    // Convert action_t enum to corresponding action string.
2937    let action = match Action::try_from(action) {
2938        Ok(action) => action,
2939        Err(_) => return -EINVAL,
2940    };
2941
2942    // Call magic function with add operator.
2943    esyd(format!("{action}/mktemp"), glob, b'+')
2944}
2945
2946/// Removes the first instance from the end of the given actionlist of
2947/// mktemp sandboxing.
2948///
2949/// Returns 0 on success, negated errno on failure.
2950#[no_mangle]
2951pub extern "C" fn syd_mktemp_del(action: action_t, glob: *const c_char) -> c_int {
2952    // Convert action_t enum to corresponding action string.
2953    let action = match Action::try_from(action) {
2954        Ok(action) => action,
2955        Err(_) => return -EINVAL,
2956    };
2957
2958    // Call magic function with del operator.
2959    esyd(format!("{action}/mktemp"), glob, b'-')
2960}
2961
2962/// Removes all matching patterns from the given actionlist of mktemp sandboxing.
2963///
2964/// Returns 0 on success, negated errno on failure.
2965#[no_mangle]
2966pub extern "C" fn syd_mktemp_rem(action: action_t, glob: *const c_char) -> c_int {
2967    // Convert action_t enum to corresponding action string.
2968    let action = match Action::try_from(action) {
2969        Ok(action) => action,
2970        Err(_) => return -EINVAL,
2971    };
2972
2973    // Call magic function with rem operator.
2974    esyd(format!("{action}/mktemp"), glob, b'^')
2975}
2976
2977/// Adds to the given actionlist of net/bind sandboxing.
2978///
2979/// Returns 0 on success, negated errno on failure.
2980#[no_mangle]
2981pub extern "C" fn syd_net_bind_add(action: action_t, glob: *const c_char) -> c_int {
2982    // Convert action_t enum to corresponding action string.
2983    let action = match Action::try_from(action) {
2984        Ok(action) => action,
2985        Err(_) => return -EINVAL,
2986    };
2987
2988    // Call magic function with add operator.
2989    esyd(format!("{action}/net/bind"), glob, b'+')
2990}
2991
2992/// Removes the first instance from the end of the given actionlist of
2993/// net/bind sandboxing.
2994///
2995/// Returns 0 on success, negated errno on failure.
2996#[no_mangle]
2997pub extern "C" fn syd_net_bind_del(action: action_t, glob: *const c_char) -> c_int {
2998    // Convert action_t enum to corresponding action string.
2999    let action = match Action::try_from(action) {
3000        Ok(action) => action,
3001        Err(_) => return -EINVAL,
3002    };
3003
3004    // Call magic function with del operator.
3005    esyd(format!("{action}/net/bind"), glob, b'-')
3006}
3007
3008/// Removes all matching patterns from the given actionlist of net/bind sandboxing.
3009///
3010/// Returns 0 on success, negated errno on failure.
3011#[no_mangle]
3012pub extern "C" fn syd_net_bind_rem(action: action_t, glob: *const c_char) -> c_int {
3013    // Convert action_t enum to corresponding action string.
3014    let action = match Action::try_from(action) {
3015        Ok(action) => action,
3016        Err(_) => return -EINVAL,
3017    };
3018
3019    // Call magic function with rem operator.
3020    esyd(format!("{action}/net/bind"), glob, b'^')
3021}
3022
3023/// Adds to the given actionlist of net/connect sandboxing.
3024///
3025/// Returns 0 on success, negated errno on failure.
3026#[no_mangle]
3027pub extern "C" fn syd_net_connect_add(action: action_t, glob: *const c_char) -> c_int {
3028    // Convert action_t enum to corresponding action string.
3029    let action = match Action::try_from(action) {
3030        Ok(action) => action,
3031        Err(_) => return -EINVAL,
3032    };
3033
3034    // Call magic function with add operator.
3035    esyd(format!("{action}/net/connect"), glob, b'+')
3036}
3037
3038/// Removes the first instance from the end of the given actionlist of
3039/// net/connect sandboxing.
3040///
3041/// Returns 0 on success, negated errno on failure.
3042#[no_mangle]
3043pub extern "C" fn syd_net_connect_del(action: action_t, glob: *const c_char) -> c_int {
3044    // Convert action_t enum to corresponding action string.
3045    let action = match Action::try_from(action) {
3046        Ok(action) => action,
3047        Err(_) => return -EINVAL,
3048    };
3049
3050    // Call magic function with del operator.
3051    esyd(format!("{action}/net/connect"), glob, b'-')
3052}
3053
3054/// Removes all matching patterns from the given actionlist of net/connect sandboxing.
3055///
3056/// Returns 0 on success, negated errno on failure.
3057#[no_mangle]
3058pub extern "C" fn syd_net_connect_rem(action: action_t, glob: *const c_char) -> c_int {
3059    // Convert action_t enum to corresponding action string.
3060    let action = match Action::try_from(action) {
3061        Ok(action) => action,
3062        Err(_) => return -EINVAL,
3063    };
3064
3065    // Call magic function with rem operator.
3066    esyd(format!("{action}/net/connect"), glob, b'^')
3067}
3068
3069/// Adds to the given actionlist of net/sendfd sandboxing.
3070///
3071/// Returns 0 on success, negated errno on failure.
3072#[no_mangle]
3073pub extern "C" fn syd_net_sendfd_add(action: action_t, glob: *const c_char) -> c_int {
3074    // Convert action_t enum to corresponding action string.
3075    let action = match Action::try_from(action) {
3076        Ok(action) => action,
3077        Err(_) => return -EINVAL,
3078    };
3079
3080    // Call magic function with add operator.
3081    esyd(format!("{action}/net/sendfd"), glob, b'+')
3082}
3083
3084/// Removes the first instance from the end of the given actionlist of
3085/// net/sendfd sandboxing.
3086///
3087/// Returns 0 on success, negated errno on failure.
3088#[no_mangle]
3089pub extern "C" fn syd_net_sendfd_del(action: action_t, glob: *const c_char) -> c_int {
3090    // Convert action_t enum to corresponding action string.
3091    let action = match Action::try_from(action) {
3092        Ok(action) => action,
3093        Err(_) => return -EINVAL,
3094    };
3095
3096    // Call magic function with del operator.
3097    esyd(format!("{action}/net/sendfd"), glob, b'-')
3098}
3099
3100/// Removes all matching patterns from the given actionlist of net/sendfd sandboxing.
3101///
3102/// Returns 0 on success, negated errno on failure.
3103#[no_mangle]
3104pub extern "C" fn syd_net_sendfd_rem(action: action_t, glob: *const c_char) -> c_int {
3105    // Convert action_t enum to corresponding action string.
3106    let action = match Action::try_from(action) {
3107        Ok(action) => action,
3108        Err(_) => return -EINVAL,
3109    };
3110
3111    // Call magic function with rem operator.
3112    esyd(format!("{action}/net/sendfd"), glob, b'^')
3113}
3114
3115/// Adds to the given actionlist of net/link sandboxing.
3116///
3117/// Returns 0 on success, negated errno on failure.
3118#[no_mangle]
3119pub extern "C" fn syd_net_link_add(action: action_t, family: *const c_char) -> c_int {
3120    // Convert action_t enum to corresponding action string.
3121    let action = match Action::try_from(action) {
3122        Ok(action) => action,
3123        Err(_) => return -EINVAL,
3124    };
3125
3126    // Call magic function with add operator.
3127    esyd(format!("{action}/net/link"), family, b'+')
3128}
3129
3130/// Removes the first instance from the end of the given actionlist of
3131/// net/link sandboxing.
3132///
3133/// Returns 0 on success, negated errno on failure.
3134#[no_mangle]
3135pub extern "C" fn syd_net_link_del(action: action_t, family: *const c_char) -> c_int {
3136    // Convert action_t enum to corresponding action string.
3137    let action = match Action::try_from(action) {
3138        Ok(action) => action,
3139        Err(_) => return -EINVAL,
3140    };
3141
3142    // Call magic function with del operator.
3143    esyd(format!("{action}/net/link"), family, b'-')
3144}
3145
3146/// Removes all matching patterns from the given actionlist of net/link sandboxing.
3147///
3148/// Returns 0 on success, negated errno on failure.
3149#[no_mangle]
3150pub extern "C" fn syd_net_link_rem(action: action_t, family: *const c_char) -> c_int {
3151    // Convert action_t enum to corresponding action string.
3152    let action = match Action::try_from(action) {
3153        Ok(action) => action,
3154        Err(_) => return -EINVAL,
3155    };
3156
3157    // Call magic function with rem operator.
3158    esyd(format!("{action}/net/link"), family, b'^')
3159}
3160
3161/// Set syd maximum per-process memory usage limit for memory sandboxing.
3162///
3163/// parse-size crate is used to parse the value so formatted strings are OK.
3164///
3165/// Returns 0 on success, negated errno on failure.
3166#[no_mangle]
3167pub extern "C" fn syd_mem_max(size: *const c_char) -> c_int {
3168    esyd("mem/max", size, b':')
3169}
3170
3171/// Set syd maximum per-process virtual memory usage limit for memory sandboxing.
3172///
3173/// parse-size crate is used to parse the value so formatted strings are OK.
3174///
3175/// Returns 0 on success, negated errno on failure.
3176#[no_mangle]
3177pub extern "C" fn syd_mem_vm_max(size: *const c_char) -> c_int {
3178    esyd("mem/vm_max", size, b':')
3179}
3180
3181/// Set syd maximum process id limit for PID sandboxing
3182///
3183/// Returns 0 on success, negated errno on failure.
3184#[no_mangle]
3185pub extern "C" fn syd_pid_max(size: usize) -> c_int {
3186    stat(format!("/dev/syd/pid/max:{size}"))
3187}
3188
3189/// Specify `SegvGuard` entry expiry timeout in seconds.
3190/// Setting this timeout to 0 effectively disables `SegvGuard`.
3191///
3192/// Returns 0 on success, negated errno on failure.
3193#[no_mangle]
3194pub extern "C" fn syd_segvguard_expiry(timeout: u64) -> c_int {
3195    stat(format!("/dev/syd/segvguard/expiry:{timeout}"))
3196}
3197
3198/// Specify `SegvGuard` entry suspension timeout in seconds.
3199///
3200/// Returns 0 on success, negated errno on failure.
3201#[no_mangle]
3202pub extern "C" fn syd_segvguard_suspension(timeout: u64) -> c_int {
3203    stat(format!("/dev/syd/segvguard/suspension:{timeout}"))
3204}
3205
3206/// Specify `SegvGuard` max number of crashes before suspension.
3207///
3208/// Returns 0 on success, negated errno on failure.
3209#[no_mangle]
3210pub extern "C" fn syd_segvguard_maxcrashes(max: u8) -> c_int {
3211    stat(format!("/dev/syd/segvguard/maxcrashes:{max}"))
3212}
3213
3214/// Execute a command outside the sandbox without sandboxing
3215///
3216/// # Safety
3217///
3218/// This function is marked `unsafe` because it dereferences raw
3219/// pointers, which is inherently unsafe in Rust.
3220///
3221/// The caller must ensure the following conditions are met to safely
3222/// use this function:
3223///
3224/// 1. The `file` pointer must point to a valid, null-terminated C-style
3225///    string.
3226///
3227/// 2. The `argv` pointer must point to an array of pointers, where each
3228///    pointer refers to a valid, null-terminated C-style string. The
3229///    last pointer in the array must be null, indicating the end of the
3230///    array.
3231///
3232/// 3. The memory pointed to by `file` and `argv` must remain valid for
3233///    the duration of the call.
3234///
3235/// Failing to uphold these guarantees can lead to undefined behavior,
3236/// including memory corruption and data races.
3237///
3238/// Returns 0 on success, negated errno on failure.
3239#[no_mangle]
3240pub unsafe extern "C" fn syd_exec(file: *const c_char, argv: *const *const c_char) -> c_int {
3241    if file.is_null() || argv.is_null() {
3242        return -EFAULT;
3243    }
3244
3245    // SAFETY: Trust that `file` is a null-terminated string.
3246    let file = CStr::from_ptr(file);
3247    let file = OsStr::from_bytes(file.to_bytes());
3248
3249    let mut path = OsString::from("/dev/syd/cmd/exec!");
3250    path.push(file);
3251
3252    let mut idx: isize = 0;
3253    while !(*argv.offset(idx)).is_null() {
3254        // SAFETY: Trust that each `argv` element is a null-terminated string.
3255        let arg = CStr::from_ptr(*argv.offset(idx));
3256        let arg = OsStr::from_bytes(arg.to_bytes());
3257
3258        path.push(OsStr::from_bytes(b"\x1F")); // ASCII Unit Separator
3259        path.push(arg);
3260
3261        idx = idx.saturating_add(1);
3262    }
3263
3264    let path = PathBuf::from(path);
3265    stat(path)
3266}