| 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 | } |