daemonize/
error.rs

1pub type Errno = libc::c_int;
2
3/// This error type for `Daemonize` `start` method.
4#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
5pub struct Error {
6    kind: ErrorKind,
7}
8
9/// This error type for `Daemonize` `start` method.
10#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
11pub enum ErrorKind {
12    Fork(Errno),
13    Wait(Errno),
14    DetachSession(Errno),
15    GroupNotFound,
16    GroupContainsNul,
17    SetGroup(Errno),
18    UserNotFound,
19    UserContainsNul,
20    SetUser(Errno),
21    ChangeDirectory(Errno),
22    PathContainsNul,
23    OpenPidfile(Errno),
24    GetPidfileFlags(Errno),
25    SetPidfileFlags(Errno),
26    LockPidfile(Errno),
27    ChownPidfile(Errno),
28    OpenDevnull(Errno),
29    RedirectStreams(Errno),
30    CloseDevnull(Errno),
31    TruncatePidfile(Errno),
32    WritePid(Errno),
33    WritePidUnspecifiedError,
34    Chroot(Errno),
35}
36
37impl ErrorKind {
38    fn description(&self) -> &str {
39        match self {
40            ErrorKind::Fork(_) => "unable to fork",
41            ErrorKind::Wait(_) => "wait failed",
42            ErrorKind::DetachSession(_) => "unable to create new session",
43            ErrorKind::GroupNotFound => "unable to resolve group name to group id",
44            ErrorKind::GroupContainsNul => "group option contains NUL",
45            ErrorKind::SetGroup(_) => "unable to set group",
46            ErrorKind::UserNotFound => "unable to resolve user name to user id",
47            ErrorKind::UserContainsNul => "user option contains NUL",
48            ErrorKind::SetUser(_) => "unable to set user",
49            ErrorKind::ChangeDirectory(_) => "unable to change directory",
50            ErrorKind::PathContainsNul => "pid_file option contains NUL",
51            ErrorKind::OpenPidfile(_) => "unable to open pid file",
52            ErrorKind::GetPidfileFlags(_) => "unable get pid file flags",
53            ErrorKind::SetPidfileFlags(_) => "unable set pid file flags",
54            ErrorKind::LockPidfile(_) => "unable to lock pid file",
55            ErrorKind::ChownPidfile(_) => "unable to chown pid file",
56            ErrorKind::OpenDevnull(_) => "unable to open /dev/null",
57            ErrorKind::RedirectStreams(_) => "unable to redirect standard streams to /dev/null",
58            ErrorKind::CloseDevnull(_) => "unable to close /dev/null",
59            ErrorKind::TruncatePidfile(_) => "unable to truncate pid file",
60            ErrorKind::WritePid(_) => "unable to write self pid to pid file",
61            ErrorKind::WritePidUnspecifiedError => {
62                "unable to write self pid to pid file due to unknown reason"
63            }
64            ErrorKind::Chroot(_) => "unable to chroot into directory",
65        }
66    }
67
68    fn errno(&self) -> Option<Errno> {
69        match self {
70            ErrorKind::Fork(errno) => Some(*errno),
71            ErrorKind::Wait(errno) => Some(*errno),
72            ErrorKind::DetachSession(errno) => Some(*errno),
73            ErrorKind::GroupNotFound => None,
74            ErrorKind::GroupContainsNul => None,
75            ErrorKind::SetGroup(errno) => Some(*errno),
76            ErrorKind::UserNotFound => None,
77            ErrorKind::UserContainsNul => None,
78            ErrorKind::SetUser(errno) => Some(*errno),
79            ErrorKind::ChangeDirectory(errno) => Some(*errno),
80            ErrorKind::PathContainsNul => None,
81            ErrorKind::OpenPidfile(errno) => Some(*errno),
82            ErrorKind::GetPidfileFlags(errno) => Some(*errno),
83            ErrorKind::SetPidfileFlags(errno) => Some(*errno),
84            ErrorKind::LockPidfile(errno) => Some(*errno),
85            ErrorKind::ChownPidfile(errno) => Some(*errno),
86            ErrorKind::OpenDevnull(errno) => Some(*errno),
87            ErrorKind::RedirectStreams(errno) => Some(*errno),
88            ErrorKind::CloseDevnull(errno) => Some(*errno),
89            ErrorKind::TruncatePidfile(errno) => Some(*errno),
90            ErrorKind::WritePid(errno) => Some(*errno),
91            ErrorKind::WritePidUnspecifiedError => None,
92            ErrorKind::Chroot(errno) => Some(*errno),
93        }
94    }
95}
96
97impl std::fmt::Display for ErrorKind {
98    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99        f.write_str(self.description())?;
100        if let Some(errno) = self.errno() {
101            write!(f, ", errno {}", errno)?
102        }
103        Ok(())
104    }
105}
106
107impl std::error::Error for ErrorKind {}
108
109impl std::fmt::Display for Error {
110    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111        write!(f, "{}", self.kind)
112    }
113}
114
115impl std::error::Error for Error {}
116
117impl From<ErrorKind> for Error {
118    fn from(kind: ErrorKind) -> Self {
119        Self { kind }
120    }
121}
122
123pub trait Num {
124    fn is_err(&self) -> bool;
125}
126
127impl Num for i8 {
128    fn is_err(&self) -> bool {
129        *self == -1
130    }
131}
132
133impl Num for i16 {
134    fn is_err(&self) -> bool {
135        *self == -1
136    }
137}
138
139impl Num for i32 {
140    fn is_err(&self) -> bool {
141        *self == -1
142    }
143}
144
145impl Num for i64 {
146    fn is_err(&self) -> bool {
147        *self == -1
148    }
149}
150
151impl Num for isize {
152    fn is_err(&self) -> bool {
153        *self == -1
154    }
155}
156
157pub fn check_err<N: Num, F: FnOnce(Errno) -> ErrorKind>(ret: N, f: F) -> Result<N, ErrorKind> {
158    if ret.is_err() {
159        Err(f(errno()))
160    } else {
161        Ok(ret)
162    }
163}
164
165pub fn errno() -> Errno {
166    std::io::Error::last_os_error()
167        .raw_os_error()
168        .expect("errno")
169}