initctl: use _cleanup_ and run()

This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-07-02 14:50:29 +02:00
parent e9d9d50cef
commit cc090ca7fe
1 changed files with 46 additions and 87 deletions

View File

@ -14,12 +14,14 @@
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
#include "daemon-util.h"
#include "def.h"
#include "fd-util.h"
#include "format-util.h"
#include "initreq.h"
#include "list.h"
#include "log.h"
#include "main-func.h"
#include "memory-util.h"
#include "process-util.h"
#include "special.h"
@ -226,6 +228,7 @@ static void fifo_free(Fifo *f) {
free(f);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(Fifo*, fifo_free);
static void server_done(Server *s) {
assert(s);
@ -240,77 +243,48 @@ static void server_done(Server *s) {
static int server_init(Server *s, unsigned n_sockets) {
int r;
/* This function will leave s partially initialized on failure. Caller needs to clean up. */
assert(s);
assert(n_sockets > 0);
*s = (struct Server) {
.epoll_fd = epoll_create1(EPOLL_CLOEXEC),
};
if (s->epoll_fd < 0) {
r = log_error_errno(errno,
"Failed to create epoll object: %m");
goto fail;
}
s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (s->epoll_fd < 0)
return log_error_errno(errno, "Failed to create epoll object: %m");
for (unsigned i = 0; i < n_sockets; i++) {
Fifo *f;
int fd;
fd = SD_LISTEN_FDS_START+i;
_cleanup_(fifo_freep) Fifo *f = NULL;
int fd = SD_LISTEN_FDS_START + i;
r = sd_is_fifo(fd, NULL);
if (r < 0) {
log_error_errno(r, "Failed to determine file descriptor type: %m");
goto fail;
}
if (!r) {
log_error("Wrong file descriptor type.");
r = -EINVAL;
goto fail;
}
if (r < 0)
return log_error_errno(r, "Failed to determine file descriptor type: %m");
if (!r)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Wrong file descriptor type.");
f = new0(Fifo, 1);
if (!f) {
r = -ENOMEM;
log_error_errno(errno, "Failed to create fifo object: %m");
goto fail;
}
f->fd = -1;
if (!f)
return log_oom();
struct epoll_event ev = {
.events = EPOLLIN,
.data.ptr = f,
};
if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
r = -errno;
fifo_free(f);
log_error_errno(errno, "Failed to add fifo fd to epoll object: %m");
goto fail;
}
if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
return log_error_errno(errno, "Failed to add fifo fd to epoll object: %m");
f->fd = fd;
LIST_PREPEND(fifo, s->fifos, f);
f->server = s;
LIST_PREPEND(fifo, s->fifos, TAKE_PTR(f));
s->n_fifos++;
}
r = bus_connect_system_systemd(&s->bus);
if (r < 0) {
log_error_errno(r, "Failed to get D-Bus connection: %m");
r = -EIO;
goto fail;
}
if (r < 0)
return log_error_errno(r, "Failed to get D-Bus connection: %m");
return 0;
fail:
server_done(s);
return r;
}
static int process_event(Server *s, struct epoll_event *ev) {
@ -334,38 +308,33 @@ static int process_event(Server *s, struct epoll_event *ev) {
return 0;
}
int main(int argc, char *argv[]) {
Server server;
int r = EXIT_FAILURE, n;
static int run(int argc, char *argv[]) {
_cleanup_(server_done) Server server = { .epoll_fd = -1 };
_cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
int r, n;
if (argc > 1) {
log_error("This program does not take arguments.");
return EXIT_FAILURE;
}
if (argc > 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This program does not take arguments.");
log_setup_service();
umask(0022);
n = sd_listen_fds(true);
if (n < 0) {
log_error_errno(r, "Failed to read listening file descriptors from environment: %m");
return EXIT_FAILURE;
}
if (n < 0)
return log_error_errno(errno,
"Failed to read listening file descriptors from environment: %m");
if (n <= 0 || n > SERVER_FD_MAX) {
log_error("No or too many file descriptors passed.");
return EXIT_FAILURE;
}
if (n <= 0 || n > SERVER_FD_MAX)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"No or too many file descriptors passed.");
if (server_init(&server, (unsigned) n) < 0)
return EXIT_FAILURE;
r = server_init(&server, (unsigned) n);
if (r < 0)
return r;
log_debug("systemd-initctl running as pid "PID_FMT, getpid_cached());
sd_notify(false,
"READY=1\n"
"STATUS=Processing requests...");
notify_stop = notify_start(NOTIFY_READY, NOTIFY_STOPPING);
while (!server.quit) {
struct epoll_event event;
@ -375,27 +344,17 @@ int main(int argc, char *argv[]) {
if (k < 0) {
if (errno == EINTR)
continue;
log_error_errno(errno, "epoll_wait() failed: %m");
goto fail;
return log_error_errno(errno, "epoll_wait() failed: %m");
}
if (k <= 0)
if (k == 0)
break;
if (process_event(&server, &event) < 0)
goto fail;
r = process_event(&server, &event);
if (r < 0)
return r;
}
r = EXIT_SUCCESS;
log_debug("systemd-initctl stopped as pid "PID_FMT, getpid_cached());
fail:
sd_notify(false,
"STOPPING=1\n"
"STATUS=Shutting down...");
server_done(&server);
return r;
return 0;
}
DEFINE_MAIN_FUNCTION(run);