File: | build-scan/../src/initctl/initctl.c |
Warning: | line 234, column 17 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | ||||
3 | #include <ctype.h> | |||
4 | #include <errno(*__errno_location ()).h> | |||
5 | #include <stdio.h> | |||
6 | #include <sys/epoll.h> | |||
7 | #include <unistd.h> | |||
8 | ||||
9 | #include "sd-bus.h" | |||
10 | #include "sd-daemon.h" | |||
11 | ||||
12 | #include "alloc-util.h" | |||
13 | #include "bus-error.h" | |||
14 | #include "bus-util.h" | |||
15 | #include "def.h" | |||
16 | #include "fd-util.h" | |||
17 | #include "format-util.h" | |||
18 | #include "initreq.h" | |||
19 | #include "list.h" | |||
20 | #include "log.h" | |||
21 | #include "special.h" | |||
22 | #include "util.h" | |||
23 | #include "process-util.h" | |||
24 | ||||
25 | #define SERVER_FD_MAX16 16 | |||
26 | #define TIMEOUT_MSEC((int) ((30*((usec_t) 1000000ULL))/((usec_t) 1000ULL))) ((int) (DEFAULT_EXIT_USEC(30*((usec_t) 1000000ULL))/USEC_PER_MSEC((usec_t) 1000ULL))) | |||
27 | ||||
28 | typedef struct Fifo Fifo; | |||
29 | ||||
30 | typedef struct Server { | |||
31 | int epoll_fd; | |||
32 | ||||
33 | LIST_HEAD(Fifo, fifos)Fifo *fifos; | |||
34 | unsigned n_fifos; | |||
35 | ||||
36 | sd_bus *bus; | |||
37 | ||||
38 | bool_Bool quit; | |||
39 | } Server; | |||
40 | ||||
41 | struct Fifo { | |||
42 | Server *server; | |||
43 | ||||
44 | int fd; | |||
45 | ||||
46 | struct init_request buffer; | |||
47 | size_t bytes_read; | |||
48 | ||||
49 | LIST_FIELDS(Fifo, fifo)Fifo *fifo_next, *fifo_prev; | |||
50 | }; | |||
51 | ||||
52 | static const char *translate_runlevel(int runlevel, bool_Bool *isolate) { | |||
53 | static const struct { | |||
54 | const int runlevel; | |||
55 | const char *special; | |||
56 | bool_Bool isolate; | |||
57 | } table[] = { | |||
58 | { '0', SPECIAL_POWEROFF_TARGET"poweroff.target", false0 }, | |||
59 | { '1', SPECIAL_RESCUE_TARGET"rescue.target", true1 }, | |||
60 | { 's', SPECIAL_RESCUE_TARGET"rescue.target", true1 }, | |||
61 | { 'S', SPECIAL_RESCUE_TARGET"rescue.target", true1 }, | |||
62 | { '2', SPECIAL_MULTI_USER_TARGET"multi-user.target", true1 }, | |||
63 | { '3', SPECIAL_MULTI_USER_TARGET"multi-user.target", true1 }, | |||
64 | { '4', SPECIAL_MULTI_USER_TARGET"multi-user.target", true1 }, | |||
65 | { '5', SPECIAL_GRAPHICAL_TARGET"graphical.target", true1 }, | |||
66 | { '6', SPECIAL_REBOOT_TARGET"reboot.target", false0 }, | |||
67 | }; | |||
68 | ||||
69 | unsigned i; | |||
70 | ||||
71 | assert(isolate)do { if ((__builtin_expect(!!(!(isolate)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("isolate"), "../src/initctl/initctl.c", 71 , __PRETTY_FUNCTION__); } while (0); | |||
72 | ||||
73 | for (i = 0; i < ELEMENTSOF(table)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(table), typeof(&*(table))), sizeof(table)/sizeof( (table)[0]), ((void)0))); i++) | |||
74 | if (table[i].runlevel == runlevel) { | |||
75 | *isolate = table[i].isolate; | |||
76 | if (runlevel == '6' && kexec_loaded()) | |||
77 | return SPECIAL_KEXEC_TARGET"kexec.target"; | |||
78 | return table[i].special; | |||
79 | } | |||
80 | ||||
81 | return NULL((void*)0); | |||
82 | } | |||
83 | ||||
84 | static void change_runlevel(Server *s, int runlevel) { | |||
85 | const char *target; | |||
86 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
87 | const char *mode; | |||
88 | bool_Bool isolate = false0; | |||
89 | int r; | |||
90 | ||||
91 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/initctl/initctl.c", 91, __PRETTY_FUNCTION__ ); } while (0); | |||
92 | ||||
93 | target = translate_runlevel(runlevel, &isolate); | |||
94 | if (!target) { | |||
95 | log_warning("Got request for unknown runlevel %c, ignoring.", runlevel)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 95, __func__, "Got request for unknown runlevel %c, ignoring." , runlevel) : -abs(_e); }); | |||
96 | return; | |||
97 | } | |||
98 | ||||
99 | if (isolate) | |||
100 | mode = "isolate"; | |||
101 | else | |||
102 | mode = "replace-irreversibly"; | |||
103 | ||||
104 | log_debug("Running request %s/start/%s", target, mode)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 104, __func__, "Running request %s/start/%s" , target, mode) : -abs(_e); }); | |||
105 | ||||
106 | r = sd_bus_call_method( | |||
107 | s->bus, | |||
108 | "org.freedesktop.systemd1", | |||
109 | "/org/freedesktop/systemd1", | |||
110 | "org.freedesktop.systemd1.Manager", | |||
111 | "StartUnit", | |||
112 | &error, | |||
113 | NULL((void*)0), | |||
114 | "ss", target, mode); | |||
115 | if (r < 0) { | |||
116 | log_error("Failed to change runlevel: %s", bus_error_message(&error, -r))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 116, __func__, "Failed to change runlevel: %s" , bus_error_message(&error, -r)) : -abs(_e); }); | |||
117 | return; | |||
118 | } | |||
119 | } | |||
120 | ||||
121 | static void request_process(Server *s, const struct init_request *req) { | |||
122 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/initctl/initctl.c", 122, __PRETTY_FUNCTION__ ); } while (0); | |||
123 | assert(req)do { if ((__builtin_expect(!!(!(req)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("req"), "../src/initctl/initctl.c", 123, __PRETTY_FUNCTION__); } while (0); | |||
124 | ||||
125 | if (req->magic != INIT_MAGIC0x03091969) { | |||
126 | log_error("Got initctl request with invalid magic. Ignoring.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 126, __func__, "Got initctl request with invalid magic. Ignoring." ) : -abs(_e); }); | |||
127 | return; | |||
128 | } | |||
129 | ||||
130 | switch (req->cmd) { | |||
131 | ||||
132 | case INIT_CMD_RUNLVL1: | |||
133 | if (!isprint(req->runlevel)((*__ctype_b_loc ())[(int) ((req->runlevel))] & (unsigned short int) _ISprint)) | |||
134 | log_error("Got invalid runlevel. Ignoring.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 134, __func__, "Got invalid runlevel. Ignoring." ) : -abs(_e); }); | |||
135 | else | |||
136 | switch (req->runlevel) { | |||
137 | ||||
138 | /* we are async anyway, so just use kill for reexec/reload */ | |||
139 | case 'u': | |||
140 | case 'U': | |||
141 | if (kill(1, SIGTERM15) < 0) | |||
142 | log_error_errno(errno, "kill() failed: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/initctl/initctl.c", 142, __func__ , "kill() failed: %m") : -abs(_e); }); | |||
143 | ||||
144 | /* The bus connection will be | |||
145 | * terminated if PID 1 is reexecuted, | |||
146 | * hence let's just exit here, and | |||
147 | * rely on that we'll be restarted on | |||
148 | * the next request */ | |||
149 | s->quit = true1; | |||
150 | break; | |||
151 | ||||
152 | case 'q': | |||
153 | case 'Q': | |||
154 | if (kill(1, SIGHUP1) < 0) | |||
155 | log_error_errno(errno, "kill() failed: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/initctl/initctl.c", 155, __func__ , "kill() failed: %m") : -abs(_e); }); | |||
156 | break; | |||
157 | ||||
158 | default: | |||
159 | change_runlevel(s, req->runlevel); | |||
160 | } | |||
161 | return; | |||
162 | ||||
163 | case INIT_CMD_POWERFAIL2: | |||
164 | case INIT_CMD_POWERFAILNOW3: | |||
165 | case INIT_CMD_POWEROK4: | |||
166 | log_warning("Received UPS/power initctl request. This is not implemented in systemd. Upgrade your UPS daemon!")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 166, __func__, "Received UPS/power initctl request. This is not implemented in systemd. Upgrade your UPS daemon!" ) : -abs(_e); }); | |||
167 | return; | |||
168 | ||||
169 | case INIT_CMD_CHANGECONS12345: | |||
170 | log_warning("Received console change initctl request. This is not implemented in systemd.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 170, __func__, "Received console change initctl request. This is not implemented in systemd." ) : -abs(_e); }); | |||
171 | return; | |||
172 | ||||
173 | case INIT_CMD_SETENV6: | |||
174 | case INIT_CMD_UNSETENV7: | |||
175 | log_warning("Received environment initctl request. This is not implemented in systemd.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 175, __func__, "Received environment initctl request. This is not implemented in systemd." ) : -abs(_e); }); | |||
176 | return; | |||
177 | ||||
178 | default: | |||
179 | log_warning("Received unknown initctl request. Ignoring.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 179, __func__, "Received unknown initctl request. Ignoring." ) : -abs(_e); }); | |||
180 | return; | |||
181 | } | |||
182 | } | |||
183 | ||||
184 | static int fifo_process(Fifo *f) { | |||
185 | ssize_t l; | |||
186 | ||||
187 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/initctl/initctl.c", 187, __PRETTY_FUNCTION__ ); } while (0); | |||
188 | ||||
189 | errno(*__errno_location ()) = EIO5; | |||
190 | l = read(f->fd, | |||
191 | ((uint8_t*) &f->buffer) + f->bytes_read, | |||
192 | sizeof(f->buffer) - f->bytes_read); | |||
193 | if (l <= 0) { | |||
194 | if (errno(*__errno_location ()) == EAGAIN11) | |||
195 | return 0; | |||
196 | ||||
197 | return log_warning_errno(errno, "Failed to read from fifo: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/initctl/initctl.c", 197, __func__ , "Failed to read from fifo: %m") : -abs(_e); }); | |||
198 | } | |||
199 | ||||
200 | f->bytes_read += l; | |||
201 | assert(f->bytes_read <= sizeof(f->buffer))do { if ((__builtin_expect(!!(!(f->bytes_read <= sizeof (f->buffer))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("f->bytes_read <= sizeof(f->buffer)"), "../src/initctl/initctl.c" , 201, __PRETTY_FUNCTION__); } while (0); | |||
202 | ||||
203 | if (f->bytes_read == sizeof(f->buffer)) { | |||
204 | request_process(f->server, &f->buffer); | |||
205 | f->bytes_read = 0; | |||
206 | } | |||
207 | ||||
208 | return 0; | |||
209 | } | |||
210 | ||||
211 | static void fifo_free(Fifo *f) { | |||
212 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/initctl/initctl.c", 212, __PRETTY_FUNCTION__ ); } while (0); | |||
213 | ||||
214 | if (f->server) { | |||
215 | assert(f->server->n_fifos > 0)do { if ((__builtin_expect(!!(!(f->server->n_fifos > 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("f->server->n_fifos > 0" ), "../src/initctl/initctl.c", 215, __PRETTY_FUNCTION__); } while (0); | |||
216 | f->server->n_fifos--; | |||
217 | LIST_REMOVE(fifo, f->server->fifos, f)do { typeof(*(f->server->fifos)) **_head = &(f-> server->fifos), *_item = (f); do { if ((__builtin_expect(! !(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ( "_item"), "../src/initctl/initctl.c", 217, __PRETTY_FUNCTION__ ); } while (0); if (_item->fifo_next) _item->fifo_next-> fifo_prev = _item->fifo_prev; if (_item->fifo_prev) _item ->fifo_prev->fifo_next = _item->fifo_next; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("*_head == _item"), "../src/initctl/initctl.c" , 217, __PRETTY_FUNCTION__); } while (0); *_head = _item-> fifo_next; } _item->fifo_next = _item->fifo_prev = ((void *)0); } while (0); | |||
218 | } | |||
219 | ||||
220 | if (f->fd >= 0) { | |||
221 | if (f->server) | |||
222 | epoll_ctl(f->server->epoll_fd, EPOLL_CTL_DEL2, f->fd, NULL((void*)0)); | |||
223 | ||||
224 | safe_close(f->fd); | |||
225 | } | |||
226 | ||||
227 | free(f); | |||
228 | } | |||
229 | ||||
230 | static void server_done(Server *s) { | |||
231 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/initctl/initctl.c", 231, __PRETTY_FUNCTION__ ); } while (0); | |||
232 | ||||
233 | while (s->fifos) | |||
234 | fifo_free(s->fifos); | |||
| ||||
235 | ||||
236 | safe_close(s->epoll_fd); | |||
237 | ||||
238 | if (s->bus) { | |||
239 | sd_bus_flush(s->bus); | |||
240 | sd_bus_unref(s->bus); | |||
241 | } | |||
242 | } | |||
243 | ||||
244 | static int server_init(Server *s, unsigned n_sockets) { | |||
245 | int r; | |||
246 | unsigned i; | |||
247 | ||||
248 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/initctl/initctl.c", 248, __PRETTY_FUNCTION__ ); } while (0); | |||
249 | assert(n_sockets > 0)do { if ((__builtin_expect(!!(!(n_sockets > 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("n_sockets > 0"), "../src/initctl/initctl.c" , 249, __PRETTY_FUNCTION__); } while (0); | |||
250 | ||||
251 | zero(*s)(({ size_t _l_ = (sizeof(*s)); void *_x_ = (&(*s)); _l_ == 0 ? _x_ : memset(_x_, 0, _l_); })); | |||
252 | ||||
253 | s->epoll_fd = epoll_create1(EPOLL_CLOEXECEPOLL_CLOEXEC); | |||
254 | if (s->epoll_fd < 0) { | |||
255 | r = log_error_errno(errno,({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/initctl/initctl.c", 256, __func__ , "Failed to create epoll object: %m") : -abs(_e); }) | |||
256 | "Failed to create epoll object: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/initctl/initctl.c", 256, __func__ , "Failed to create epoll object: %m") : -abs(_e); }); | |||
257 | goto fail; | |||
258 | } | |||
259 | ||||
260 | for (i = 0; i
| |||
261 | struct epoll_event ev; | |||
262 | Fifo *f; | |||
263 | int fd; | |||
264 | ||||
265 | fd = SD_LISTEN_FDS_START3+i; | |||
266 | ||||
267 | r = sd_is_fifo(fd, NULL((void*)0)); | |||
268 | if (r < 0) { | |||
269 | log_error_errno(r, "Failed to determine file descriptor type: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 269, __func__, "Failed to determine file descriptor type: %m" ) : -abs(_e); }); | |||
270 | goto fail; | |||
271 | } | |||
272 | ||||
273 | if (!r) { | |||
274 | log_error("Wrong file descriptor type.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 274, __func__, "Wrong file descriptor type." ) : -abs(_e); }); | |||
275 | r = -EINVAL22; | |||
276 | goto fail; | |||
277 | } | |||
278 | ||||
279 | f = new0(Fifo, 1)((Fifo*) calloc((1), sizeof(Fifo))); | |||
280 | if (!f) { | |||
281 | r = -ENOMEM12; | |||
282 | log_error_errno(errno, "Failed to create fifo object: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/initctl/initctl.c", 282, __func__ , "Failed to create fifo object: %m") : -abs(_e); }); | |||
283 | goto fail; | |||
284 | } | |||
285 | ||||
286 | f->fd = -1; | |||
287 | ||||
288 | zero(ev)(({ size_t _l_ = (sizeof(ev)); void *_x_ = (&(ev)); _l_ == 0 ? _x_ : memset(_x_, 0, _l_); })); | |||
289 | ev.events = EPOLLINEPOLLIN; | |||
290 | ev.data.ptr = f; | |||
291 | if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD1, fd, &ev) < 0) { | |||
292 | r = -errno(*__errno_location ()); | |||
293 | fifo_free(f); | |||
294 | log_error_errno(errno, "Failed to add fifo fd to epoll object: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/initctl/initctl.c", 294, __func__ , "Failed to add fifo fd to epoll object: %m") : -abs(_e); }); | |||
295 | goto fail; | |||
296 | } | |||
297 | ||||
298 | f->fd = fd; | |||
299 | LIST_PREPEND(fifo, s->fifos, f)do { typeof(*(s->fifos)) **_head = &(s->fifos), *_item = (f); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("_item"), "../src/initctl/initctl.c", 299 , __PRETTY_FUNCTION__); } while (0); if ((_item->fifo_next = *_head)) _item->fifo_next->fifo_prev = _item; _item-> fifo_prev = ((void*)0); *_head = _item; } while (0); | |||
300 | f->server = s; | |||
301 | s->n_fifos++; | |||
302 | } | |||
303 | ||||
304 | r = bus_connect_system_systemd(&s->bus); | |||
305 | if (r < 0) { | |||
306 | log_error_errno(r, "Failed to get D-Bus connection: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 306, __func__, "Failed to get D-Bus connection: %m" ) : -abs(_e); }); | |||
307 | r = -EIO5; | |||
308 | goto fail; | |||
309 | } | |||
310 | ||||
311 | return 0; | |||
312 | ||||
313 | fail: | |||
314 | server_done(s); | |||
315 | ||||
316 | return r; | |||
317 | } | |||
318 | ||||
319 | static int process_event(Server *s, struct epoll_event *ev) { | |||
320 | int r; | |||
321 | Fifo *f; | |||
322 | ||||
323 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/initctl/initctl.c", 323, __PRETTY_FUNCTION__ ); } while (0); | |||
324 | ||||
325 | if (!(ev->events & EPOLLINEPOLLIN)) { | |||
326 | log_info("Got invalid event from epoll. (3)")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 326, __func__, "Got invalid event from epoll. (3)" ) : -abs(_e); }); | |||
327 | return -EIO5; | |||
328 | } | |||
329 | ||||
330 | f = (Fifo*) ev->data.ptr; | |||
331 | r = fifo_process(f); | |||
332 | if (r < 0) { | |||
333 | log_info_errno(r, "Got error on fifo: %m")({ int _level = ((6)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 333, __func__, "Got error on fifo: %m" ) : -abs(_e); }); | |||
334 | fifo_free(f); | |||
335 | return r; | |||
336 | } | |||
337 | ||||
338 | return 0; | |||
339 | } | |||
340 | ||||
341 | int main(int argc, char *argv[]) { | |||
342 | Server server; | |||
343 | int r = EXIT_FAILURE1, n; | |||
344 | ||||
345 | if (getppid() != 1) { | |||
| ||||
346 | log_error("This program should be invoked by init only.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 346, __func__, "This program should be invoked by init only." ) : -abs(_e); }); | |||
347 | return EXIT_FAILURE1; | |||
348 | } | |||
349 | ||||
350 | if (argc > 1) { | |||
351 | log_error("This program does not take arguments.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 351, __func__, "This program does not take arguments." ) : -abs(_e); }); | |||
352 | return EXIT_FAILURE1; | |||
353 | } | |||
354 | ||||
355 | log_set_target(LOG_TARGET_AUTO); | |||
356 | log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD); | |||
357 | log_open(); | |||
358 | ||||
359 | umask(0022); | |||
360 | ||||
361 | n = sd_listen_fds(true1); | |||
362 | if (n < 0) { | |||
363 | log_error_errno(r, "Failed to read listening file descriptors from environment: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 363, __func__, "Failed to read listening file descriptors from environment: %m" ) : -abs(_e); }); | |||
364 | return EXIT_FAILURE1; | |||
365 | } | |||
366 | ||||
367 | if (n <= 0 || n > SERVER_FD_MAX16) { | |||
368 | log_error("No or too many file descriptors passed.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 368, __func__, "No or too many file descriptors passed." ) : -abs(_e); }); | |||
369 | return EXIT_FAILURE1; | |||
370 | } | |||
371 | ||||
372 | if (server_init(&server, (unsigned) n) < 0) | |||
373 | return EXIT_FAILURE1; | |||
374 | ||||
375 | log_debug("systemd-initctl running as pid "PID_FMT, getpid_cached())({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 375, __func__, "systemd-initctl running as pid " "%" "i", getpid_cached()) : -abs(_e); }); | |||
376 | ||||
377 | sd_notify(false0, | |||
378 | "READY=1\n" | |||
379 | "STATUS=Processing requests..."); | |||
380 | ||||
381 | while (!server.quit) { | |||
382 | struct epoll_event event; | |||
383 | int k; | |||
384 | ||||
385 | k = epoll_wait(server.epoll_fd, &event, 1, TIMEOUT_MSEC((int) ((30*((usec_t) 1000000ULL))/((usec_t) 1000ULL)))); | |||
386 | if (k < 0) { | |||
387 | if (errno(*__errno_location ()) == EINTR4) | |||
388 | continue; | |||
389 | log_error_errno(errno, "epoll_wait() failed: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/initctl/initctl.c", 389, __func__ , "epoll_wait() failed: %m") : -abs(_e); }); | |||
390 | goto fail; | |||
391 | } | |||
392 | ||||
393 | if (k <= 0) | |||
394 | break; | |||
395 | ||||
396 | if (process_event(&server, &event) < 0) | |||
397 | goto fail; | |||
398 | } | |||
399 | ||||
400 | r = EXIT_SUCCESS0; | |||
401 | ||||
402 | log_debug("systemd-initctl stopped as pid "PID_FMT, getpid_cached())({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/initctl/initctl.c", 402, __func__, "systemd-initctl stopped as pid " "%" "i", getpid_cached()) : -abs(_e); }); | |||
403 | ||||
404 | fail: | |||
405 | sd_notify(false0, | |||
406 | "STOPPING=1\n" | |||
407 | "STATUS=Shutting down..."); | |||
408 | ||||
409 | server_done(&server); | |||
410 | ||||
411 | return r; | |||
412 | } |