chiark / gitweb /
shared: add formats-util.h
[elogind.git] / src / shared / exit-status.c
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
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
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
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <stdlib.h>
23
24 #include "exit-status.h"
25 #include "set.h"
26 #include "macro.h"
27
28 const 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
115                 case EXIT_PAM:
116                         return "PAM";
117
118                 case EXIT_NETWORK:
119                         return "NETWORK";
120
121                 case EXIT_NAMESPACE:
122                         return "NAMESPACE";
123
124                 case EXIT_NO_NEW_PRIVILEGES:
125                         return "NO_NEW_PRIVILEGES";
126
127                 case EXIT_SECCOMP:
128                         return "SECCOMP";
129
130                 case EXIT_SELINUX_CONTEXT:
131                         return "SELINUX_CONTEXT";
132
133                 case EXIT_PERSONALITY:
134                         return "PERSONALITY";
135
136                 case EXIT_APPARMOR_PROFILE:
137                         return "APPARMOR";
138
139                 case EXIT_ADDRESS_FAMILIES:
140                         return "ADDRESS_FAMILIES";
141
142                 case EXIT_RUNTIME_DIRECTORY:
143                         return "RUNTIME_DIRECTORY";
144
145                 case EXIT_CHOWN:
146                         return "CHOWN";
147
148                 case EXIT_MAKE_STARTER:
149                         return "MAKE_STARTER";
150
151                 case EXIT_BUS_ENDPOINT:
152                         return "BUS_ENDPOINT";
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:
169                         return "NOTINSSTALLED";
170
171                 case EXIT_NOTCONFIGURED:
172                         return "NOTCONFIGURED";
173
174                 case EXIT_NOTRUNNING:
175                         return "NOTRUNNING";
176                 }
177         }
178
179         return NULL;
180 }
181
182
183 bool is_clean_exit(int code, int status, ExitStatusSet *success_status) {
184
185         if (code == CLD_EXITED)
186                 return status == 0 ||
187                        (success_status &&
188                        set_contains(success_status->status, INT_TO_PTR(status)));
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 ||
197                         status == SIGPIPE ||
198                         (success_status &&
199                         set_contains(success_status->signal, INT_TO_PTR(status)));
200
201         return false;
202 }
203
204 bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status) {
205
206         if (is_clean_exit(code, status, success_status))
207                 return true;
208
209         return
210                 code == CLD_EXITED &&
211                 (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED);
212 }
213
214 void exit_status_set_free(ExitStatusSet *x) {
215         assert(x);
216
217         set_free(x->status);
218         set_free(x->signal);
219         x->status = x->signal = NULL;
220 }
221
222 bool 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 }