• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

olukowski / celer / 24930550262

25 Apr 2026 12:08PM UTC coverage: 99.871% (-0.1%) from 100.0%
24930550262

Pull #10

github

web-flow
Merge ac535c552 into ea5776c23
Pull Request #10: feat(syscalls): thin wrappers around raw syscalls

9 of 10 branches covered (90.0%)

Branch coverage included in aggregate %.

1552 of 1554 new or added lines in 108 files covered. (99.87%)

2310 of 2312 relevant lines covered (99.91%)

11.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.89
/system/linux/syscalls/src/syslog.rs
1
use core::mem::MaybeUninit;
2

3
use celer_system_linux_ctypes::{Char, Int};
4

5
use crate::errno::Errno;
6
use crate::helpers::result_from_ret;
7
use crate::sys;
8

9
/// Errors returned by [`syslog`].
10
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
11
pub enum SyslogError {
12
    Eperm,
13
    Einval,
14
    Efault,
15
    Eintr,
16
    Enomem,
17
    Other(Errno),
18
}
19

20
impl SyslogError {
21
    fn from_errno(errno: Errno) -> Self {
21✔
22
        match errno {
21✔
23
            Errno::Eperm => Self::Eperm,
6✔
24
            Errno::Einval => Self::Einval,
3✔
25
            Errno::Efault => Self::Efault,
3✔
26
            Errno::Eintr => Self::Eintr,
3✔
27
            Errno::Enomem => Self::Enomem,
3✔
28
            errno => Self::Other(errno),
3✔
29
        }
30
    }
21✔
31
}
32

33
/// Read from or control the kernel log buffer.
34
///
35
/// This safe wrapper keeps the raw multiplexed `type_` command and `len`
36
/// integer, replaces the raw output pointer with an optional initialized
37
/// capacity `buf`, and maps the raw return into `Result<Int, SyslogError>`.
38
///
39
/// When `buf` is `Some`, `len` must be nonnegative and no larger than the
40
/// slice length. When `buf` is `None`, the raw syscall receives a null pointer.
41
///
42
/// On success, returns the raw command result: `0` for control commands, a
43
/// byte count for read commands, or a size/count value for query commands.
44
///
45
/// See [`sys::syslog`] for command semantics, required privileges, reachable
46
/// errors, and source references.
47
///
48
/// # Errors
49
/// - [`SyslogError::Eperm`]: the selected command requires permission.
50
/// - [`SyslogError::Einval`]: the command or length is invalid, or `len`
51
///   exceeds the provided buffer.
52
/// - [`SyslogError::Efault`]: the kernel could not write the buffer.
53
/// - [`SyslogError::Eintr`]: a blocking read was interrupted.
54
/// - [`SyslogError::Enomem`]: temporary log-copy allocation failed.
55
/// - [`SyslogError::Other`]: delegated security-policy error.
56
pub fn syslog(
6✔
57
    type_: Int,
6✔
58
    buf: Option<&mut [MaybeUninit<u8>]>,
6✔
59
    len: Int,
6✔
60
) -> Result<Int, SyslogError> {
6✔
61
    let ptr = match buf {
6✔
62
        Some(buf) => {
3✔
63
            let len = usize::try_from(len).map_err(|_| SyslogError::Einval)?;
3✔
64
            if len > buf.len() {
3!
65
                return Err(SyslogError::Einval);
3✔
NEW
66
            }
×
NEW
67
            buf.as_mut_ptr().cast::<Char>()
×
68
        }
69
        None => core::ptr::null_mut(),
3✔
70
    };
71

72
    // SAFETY: a non-null pointer is backed by `buf` for at least `len` bytes;
73
    // null is passed only when `buf` is `None`.
74
    let ret = unsafe { sys::syslog(type_, ptr, len) };
3✔
75
    result_from_ret(ret as isize, |ret| ret as Int, SyslogError::from_errno)
3✔
76
}
6✔
77

78
#[cfg(test)]
79
#[cfg_attr(coverage_nightly, coverage(off))]
80
mod tests {
81
    use core::mem::MaybeUninit;
82

83
    use crate::Errno;
84

85
    use super::{SyslogError, syslog};
86

87
    #[test]
88
    fn test_syslog_rejects_len_larger_than_buffer() {
89
        let mut buf = [MaybeUninit::uninit(); 4];
90

91
        assert_eq!(syslog(3, Some(&mut buf), 5), Err(SyslogError::Einval));
92
    }
93

94
    #[test]
95
    fn test_syslog_invalid_type_is_permission_or_invalid() {
96
        let err = syslog(11, None, 0).unwrap_err();
97
        assert!(matches!(err, SyslogError::Eperm | SyslogError::Einval));
98
    }
99

100
    #[test]
101
    fn test_syslog_error_mapping() {
102
        assert_eq!(SyslogError::from_errno(Errno::Eperm), SyslogError::Eperm);
103
        assert_eq!(SyslogError::from_errno(Errno::Einval), SyslogError::Einval);
104
        assert_eq!(SyslogError::from_errno(Errno::Efault), SyslogError::Efault);
105
        assert_eq!(SyslogError::from_errno(Errno::Eintr), SyslogError::Eintr);
106
        assert_eq!(SyslogError::from_errno(Errno::Enomem), SyslogError::Enomem);
107
        assert_eq!(
108
            SyslogError::from_errno(Errno::Eacces),
109
            SyslogError::Other(Errno::Eacces)
110
        );
111
    }
112
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc