]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/exit-status.c
Merge pull request #269 from teg/udev-docs-1
[thirdparty/systemd.git] / src / basic / exit-status.c
CommitLineData
1afbdcb0
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
1afbdcb0
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
1afbdcb0 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
1afbdcb0
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdlib.h>
23
24#include "exit-status.h"
96342de6
LN
25#include "set.h"
26#include "macro.h"
1afbdcb0
LP
27
28const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
29
30 /* We cast to int here, so that -Wenum doesn't complain that
31 * EXIT_SUCCESS/EXIT_FAILURE aren't in the enum */
32
33 switch ((int) status) {
34
35 case EXIT_SUCCESS:
36 return "SUCCESS";
37
38 case EXIT_FAILURE:
39 return "FAILURE";
40 }
41
42
43 if (level == EXIT_STATUS_SYSTEMD || level == EXIT_STATUS_LSB) {
44 switch ((int) status) {
45
46 case EXIT_CHDIR:
47 return "CHDIR";
48
49 case EXIT_NICE:
50 return "NICE";
51
52 case EXIT_FDS:
53 return "FDS";
54
55 case EXIT_EXEC:
56 return "EXEC";
57
58 case EXIT_MEMORY:
59 return "MEMORY";
60
61 case EXIT_LIMITS:
62 return "LIMITS";
63
64 case EXIT_OOM_ADJUST:
65 return "OOM_ADJUST";
66
67 case EXIT_SIGNAL_MASK:
68 return "SIGNAL_MASK";
69
70 case EXIT_STDIN:
71 return "STDIN";
72
73 case EXIT_STDOUT:
74 return "STDOUT";
75
76 case EXIT_CHROOT:
77 return "CHROOT";
78
79 case EXIT_IOPRIO:
80 return "IOPRIO";
81
82 case EXIT_TIMERSLACK:
83 return "TIMERSLACK";
84
85 case EXIT_SECUREBITS:
86 return "SECUREBITS";
87
88 case EXIT_SETSCHEDULER:
89 return "SETSCHEDULER";
90
91 case EXIT_CPUAFFINITY:
92 return "CPUAFFINITY";
93
94 case EXIT_GROUP:
95 return "GROUP";
96
97 case EXIT_USER:
98 return "USER";
99
100 case EXIT_CAPABILITIES:
101 return "CAPABILITIES";
102
103 case EXIT_CGROUP:
104 return "CGROUP";
105
106 case EXIT_SETSID:
107 return "SETSID";
108
109 case EXIT_CONFIRM:
110 return "CONFIRM";
111
112 case EXIT_STDERR:
113 return "STDERR";
114
1afbdcb0
LP
115 case EXIT_PAM:
116 return "PAM";
ff01d048
LP
117
118 case EXIT_NETWORK:
119 return "NETWORK";
4c2630eb
MS
120
121 case EXIT_NAMESPACE:
122 return "NAMESPACE";
8351ceae
LP
123
124 case EXIT_NO_NEW_PRIVILEGES:
125 return "NO_NEW_PRIVILEGES";
126
127 case EXIT_SECCOMP:
128 return "SECCOMP";
7b52a628
MS
129
130 case EXIT_SELINUX_CONTEXT:
131 return "SELINUX_CONTEXT";
ac45f971
LP
132
133 case EXIT_PERSONALITY:
134 return "PERSONALITY";
eef65bf3
MS
135
136 case EXIT_APPARMOR_PROFILE:
137 return "APPARMOR";
4298d0b5
LP
138
139 case EXIT_ADDRESS_FAMILIES:
140 return "ADDRESS_FAMILIES";
e66cf1a3
LP
141
142 case EXIT_RUNTIME_DIRECTORY:
143 return "RUNTIME_DIRECTORY";
3900e5fd
LP
144
145 case EXIT_CHOWN:
146 return "CHOWN";
a4152e3f
LP
147
148 case EXIT_MAKE_STARTER:
149 return "MAKE_STARTER";
060e088e
DM
150
151 case EXIT_BUS_ENDPOINT:
ffb6c43e 152 return "BUS_ENDPOINT";
1afbdcb0
LP
153 }
154 }
155
156 if (level == EXIT_STATUS_LSB) {
157 switch ((int) status) {
158
159 case EXIT_INVALIDARGUMENT:
160 return "INVALIDARGUMENT";
161
162 case EXIT_NOTIMPLEMENTED:
163 return "NOTIMPLEMENTED";
164
165 case EXIT_NOPERMISSION:
166 return "NOPERMISSION";
167
168 case EXIT_NOTINSTALLED:
9f8f87e3 169 return "NOTINSTALLED";
1afbdcb0
LP
170
171 case EXIT_NOTCONFIGURED:
172 return "NOTCONFIGURED";
173
174 case EXIT_NOTRUNNING:
175 return "NOTRUNNING";
176 }
177 }
178
179 return NULL;
180}
9a57c629
LP
181
182
96342de6 183bool is_clean_exit(int code, int status, ExitStatusSet *success_status) {
9a57c629
LP
184
185 if (code == CLD_EXITED)
96342de6
LN
186 return status == 0 ||
187 (success_status &&
3e2d435b 188 set_contains(success_status->status, INT_TO_PTR(status)));
9a57c629
LP
189
190 /* If a daemon does not implement handlers for some of the
191 * signals that's not considered an unclean shutdown */
192 if (code == CLD_KILLED)
193 return
194 status == SIGHUP ||
195 status == SIGINT ||
196 status == SIGTERM ||
96342de6
LN
197 status == SIGPIPE ||
198 (success_status &&
199 set_contains(success_status->signal, INT_TO_PTR(status)));
9a57c629
LP
200
201 return false;
202}
203
96342de6 204bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status) {
9a57c629 205
96342de6 206 if (is_clean_exit(code, status, success_status))
9a57c629
LP
207 return true;
208
209 return
210 code == CLD_EXITED &&
211 (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED);
212}
37520c1b
LP
213
214void exit_status_set_free(ExitStatusSet *x) {
215 assert(x);
216
3e2d435b 217 set_free(x->status);
37520c1b 218 set_free(x->signal);
3e2d435b 219 x->status = x->signal = NULL;
37520c1b 220}
55ebf98c
LP
221
222bool exit_status_set_is_empty(ExitStatusSet *x) {
223 if (!x)
224 return true;
225
226 return set_isempty(x->status) && set_isempty(x->signal);
227}
597466f4
LP
228
229bool exit_status_set_test(ExitStatusSet *x, int code, int status) {
230
231 if (exit_status_set_is_empty(x))
232 return false;
233
234 if (code == CLD_EXITED && set_contains(x->status, INT_TO_PTR(status)))
235 return true;
236
237 if (IN_SET(code, CLD_KILLED, CLD_DUMPED) && set_contains(x->signal, INT_TO_PTR(status)))
238 return true;
239
240 return false;
241}