diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2013-12-10 21:52:11 -0500 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2013-12-10 21:52:57 -0500 |
commit | c099716487df4a4f5394e57e7ca14da1d358166a (patch) | |
tree | b5d73d9a543fc4f7767a46edb3268147aa689157 /src | |
parent | 8be12848423218c034cfa7e3078774c9d4732281 (diff) |
activate: clean up inherited descriptors
> [simon@troela server]$ /usr/lib/systemd/systemd-activate -l 9000 main.js
> Assertion 'fd == 3 + count' failed at src/activate/activate.c:115,
> function open_sockets(). Aborting.
> Aborted (core dumped)
> after a bit debuging i found the problem:
> slim appears to leak an fd into all of its children:
> stat /proc/14004/fd/3 (14004 is the pid a random process in my session)
> File: '/proc/14004/fd/3' -> '/var/log/slim.log'
systemd-activate should be robust against the shell (or anything else) leaking
descriptors. Now everything except stdin/stdout/stderr and received sockets
will be closed.
Diffstat (limited to 'src')
-rw-r--r-- | src/activate/activate.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/activate/activate.c b/src/activate/activate.c index 5263969fcf..d73c16e8ab 100644 --- a/src/activate/activate.c +++ b/src/activate/activate.c @@ -99,6 +99,17 @@ static int open_sockets(int *epoll_fd, bool accept) { } } + /* Close logging and all other descriptors */ + if (arg_listen) { + int except[3 + n]; + + for (fd = 0; fd < SD_LISTEN_FDS_START + n; fd++) + except[fd] = fd; + + log_close(); + close_all_fds(except, 3 + n); + } + /** Note: we leak some fd's on error here. I doesn't matter * much, since the program will exit immediately anyway, but * would be a pain to fix. @@ -108,6 +119,7 @@ static int open_sockets(int *epoll_fd, bool accept) { fd = make_socket_fd(*address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC)); if (fd < 0) { + log_open(); log_error("Failed to open '%s': %s", *address, strerror(-fd)); return fd; } @@ -116,6 +128,9 @@ static int open_sockets(int *epoll_fd, bool accept) { count ++; } + if (arg_listen) + log_open(); + *epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (*epoll_fd < 0) { log_error("Failed to create epoll object: %m"); @@ -270,10 +285,10 @@ static void sigchld_hdl(int sig, siginfo_t *t, void *data) { static int install_chld_handler(void) { int r; - struct sigaction act; - zero(act); - act.sa_flags = SA_SIGINFO; - act.sa_sigaction = sigchld_hdl; + struct sigaction act = { + .sa_flags = SA_SIGINFO, + .sa_sigaction = sigchld_hdl, + }; r = sigaction(SIGCHLD, &act, 0); if (r < 0) |