activate.c revision 175a3d25d0e8596d4ba0759aea3f89ee228e7d6d
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/***
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering This file is part of systemd.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Copyright 2013 Zbigniew Jędrzejewski-Szmek
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (at your option) any later version.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is distributed in the hope that it will be useful, but
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Lesser General Public License for more details.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering***/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#include <unistd.h>
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#include <fcntl.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <sys/epoll.h>
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include <sys/prctl.h>
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include <sys/socket.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <sys/wait.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <getopt.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
3c70e3bb022f0de3317f3600c9366a2f4597339eLennart Poettering#include <systemd/sd-daemon.h>
3c70e3bb022f0de3317f3600c9366a2f4597339eLennart Poettering
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include "socket-util.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "build.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "log.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "strv.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "macro.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic char** arg_listen = NULL;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mackstatic bool arg_accept = false;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic char** arg_args = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic char** arg_environ = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int add_epoll(int epoll_fd, int fd) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct epoll_event ev = {EPOLLIN};
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering ev.data.fd = fd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(epoll_fd >= 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(fd >= 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error("Failed to add event on epoll fd:%d for fd:%d: %s",
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering epoll_fd, fd, strerror(-r));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering
4f10118016f9b2fd7e1d26c9ef7d91eb33fba694Lennart Poetteringstatic int print_socket(const char* desc, int fd) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering SocketAddress addr = {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering .size = sizeof(union sockaddr_union),
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering .type = SOCK_STREAM,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering };
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int family;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = getsockname(fd, &addr.sockaddr.sa, &addr.size);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_warning("Failed to query socket on fd:%d: %m", fd);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering family = socket_address_family(&addr);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering switch(family) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case AF_INET:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case AF_INET6: {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char* _cleanup_free_ a = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = socket_address_print(&addr, &a);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_warning("socket_address_print(): %s", strerror(-r));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering else
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_info("%s %s address %s",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering desc,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering family == AF_INET ? "IP" : "IPv6",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering a);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering default:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_warning("Connection with unknown family %d", family);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int make_socket_fd(const char* address, int flags) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *p = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering SocketAddress a;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int fd, r;
a1e58e8ee1c84b633d6d6d651d5328d4dd4eba5bLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = socket_address_parse(&a, address);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_error("Failed to parse socket: %s", strerror(-r));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fd = socket_address_listen(&a, flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT, NULL, false, false, 0755, 0644, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (fd < 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_error("Failed to listen: %s", strerror(-r));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return fd;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = socket_address_print(&a, &p);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_error("socket_address_print(): %s", strerror(-r));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering close_nointr_nofail(fd);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_info("Listening on %s", p);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return fd;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int open_sockets(int *epoll_fd, bool accept) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int n, fd, r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int count = 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char **address;
920b52e4909d9dc812817fd8b82f83ca23a11c91Thomas Hindoe Paaboel Andersen
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n = sd_listen_fds(true);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (n < 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_error("Failed to read listening file descriptors from environment: %s",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering strerror(-n));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return n;
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen }
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen log_info("Received %d descriptors", n);
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen log_debug("Received descriptor fd:%d", fd);
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen print_socket("Listening on", fd);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = fd_cloexec(fd, arg_accept);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering count ++;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /** Note: we leak some fd's on error here. I doesn't matter
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * much, since the program will exit immediately anyway, but
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * would be a pain to fix.
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering STRV_FOREACH(address, arg_listen) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_info("Opening address %s", *address);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fd = make_socket_fd(*address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (fd < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error("Failed to open '%s': %s", *address, strerror(-fd));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return fd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(fd == SD_LISTEN_FDS_START + count);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering count ++;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *epoll_fd = epoll_create1(EPOLL_CLOEXEC);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering if (*epoll_fd < 0) {
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering log_error("Failed to create epoll object: %m");
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + count; fd++) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = add_epoll(*epoll_fd, fd);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return count;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mackstatic int launch(char* name, char **argv, char **env, int fds) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack unsigned n_env = 0, length;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack _cleanup_strv_free_ char **envp = NULL;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack char **s;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack static const char* tocopy[] = {"TERM=", "PATH=", "USER=", "HOME="};
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack _cleanup_free_ char *tmp = NULL;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack unsigned i;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering length = strv_length(arg_environ);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* PATH, TERM, HOME, USER, LISTEN_FDS, LISTEN_PID, NULL */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering envp = new(char *, length + 7);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering STRV_FOREACH(s, arg_environ) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (strchr(*s, '='))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering envp[n_env++] = *s;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering else {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *p = strappend(*s, "=");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!p)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return log_oom();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering envp[n_env] = strv_find_prefix(env, p);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (envp[n_env])
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering n_env ++;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering for (i = 0; i < ELEMENTSOF(tocopy); i++) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering envp[n_env] = strv_find_prefix(env, tocopy[i]);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (envp[n_env])
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering n_env ++;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if ((asprintf((char**)(envp + n_env++), "LISTEN_FDS=%d", fds) < 0) ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (asprintf((char**)(envp + n_env++), "LISTEN_PID=%d", getpid()) < 0))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return log_oom();
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering tmp = strv_join(argv, " ");
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering if (!tmp)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return log_oom();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_info("Execing %s (%s)", name, tmp);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering execvpe(name, argv, envp);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error("Failed to execp %s (%s): %m", name, tmp);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int launch1(const char* child, char** argv, char **env, int fd) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering pid_t parent_pid, child_pid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *tmp = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering tmp = strv_join(argv, " ");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!tmp)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return log_oom();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering parent_pid = getpid();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering child_pid = fork();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (child_pid < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error("Failed to fork: %m");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* In the child */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (child_pid == 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dup2(fd, STDIN_FILENO);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error("Failed to dup connection to stdin: %m");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _exit(EXIT_FAILURE);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dup2(fd, STDOUT_FILENO);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error("Failed to dup connection to stdout: %m");
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering _exit(EXIT_FAILURE);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack }
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = close(fd);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0) {
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering log_error("Failed to close dupped connection: %m");
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack _exit(EXIT_FAILURE);
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Make sure the child goes away when the parent dies */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _exit(EXIT_FAILURE);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Check whether our parent died before we were able
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * to set the death signal */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (getppid() != parent_pid)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _exit(EXIT_SUCCESS);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering execvp(child, argv);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error("Failed to exec child %s: %m", child);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _exit(EXIT_FAILURE);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_info("Spawned %s (%s) as PID %d", child, tmp, child_pid);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int do_accept(const char* name, char **argv, char **envp, int fd) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering SocketAddress addr = {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering .size = sizeof(union sockaddr_union),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering .type = SOCK_STREAM,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering };
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int fd2, r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fd2 = accept(fd, &addr.sockaddr.sa, &addr.size);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering if (fd2 < 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_error("Failed to accept connection on fd:%d: %m", fd);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering return fd2;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering }
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering print_socket("Connection from", fd2);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering r = launch1(name, argv, envp, fd2);
cfa9677bd164574600d29a9bf99f9d1f28a7a170Mantas MikulÄ—nas return r;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/* SIGCHLD handler. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void sigchld_hdl(int sig, siginfo_t *t, void *data) {
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering log_info("Child %d died with code %d", t->si_pid, t->si_status);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering /* Wait for a dead child. */
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering waitpid(t->si_pid, NULL, 0);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering}
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int install_chld_handler(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct sigaction act;
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek zero(act);
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek act.sa_flags = SA_SIGINFO;
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek act.sa_sigaction = sigchld_hdl;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sigaction(SIGCHLD, &act, 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error("Failed to install SIGCHLD handler: %m");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering}
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidtstatic int help(void) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering printf("%s [OPTIONS...]\n\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "Listen on sockets and launch child on connection.\n\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "Options:\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering " -l --listen=ADDR Listen for raw connections at ADDR\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering " -a --accept Spawn separate child for each connection\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering " -h --help Show this help and exit\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering " --version Print version string and exit\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "Note: file descriptors from sd_listen_fds() will be passed through.\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering , program_invocation_short_name
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering );
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering enum {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering ARG_VERSION = 0x100,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering };
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering static const struct option options[] = {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering { "help", no_argument, NULL, 'h' },
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering { "version", no_argument, NULL, ARG_VERSION },
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering { "listen", required_argument, NULL, 'l' },
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering { "accept", no_argument, NULL, 'a' },
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering { "environment", required_argument, NULL, 'E' },
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering {}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering };
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
be847e82cf95bf8eb589778df2aa2b3d1d7ae99eLennart Poettering int c;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(argc >= 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(argv);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering while ((c = getopt_long(argc, argv, "+hl:saE:", options, NULL)) >= 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering switch(c) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case 'h':
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return help();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case ARG_VERSION:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering puts(PACKAGE_STRING);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering puts(SYSTEMD_FEATURES);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0 /* done */;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case 'l': {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r = strv_extend(&arg_listen, optarg);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case 'a':
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering arg_accept = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case 'E': {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r = strv_extend(&arg_environ, optarg);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case '?':
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -EINVAL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering default:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert_not_reached("Unhandled option");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (optind == argc) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_error("Usage: %s [OPTION...] PROGRAM [OPTION...]",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering program_invocation_short_name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -EINVAL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering arg_args = argv + optind;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 1 /* work to do */;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringint main(int argc, char **argv, char **envp) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r, n;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int epoll_fd = -1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_parse_environment();
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_open();
ce30c8dcb41dfe9264f79f30c7f51c0e74576638Lennart Poettering
ce30c8dcb41dfe9264f79f30c7f51c0e74576638Lennart Poettering r = parse_argv(argc, argv);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r <= 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = install_chld_handler();
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return EXIT_FAILURE;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n = open_sockets(&epoll_fd, arg_accept);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (n < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return EXIT_FAILURE;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering for (;;) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt struct epoll_event event;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = epoll_wait(epoll_fd, &event, 1, -1);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (errno == EINTR)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering continue;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_error("epoll_wait() failed: %m");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return EXIT_FAILURE;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_info("Communication attempt on fd:%d", event.data.fd);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (arg_accept) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = do_accept(argv[optind], argv + optind, envp,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering event.data.fd);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return EXIT_FAILURE;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering launch(argv[optind], argv + optind, envp, n);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return EXIT_SUCCESS;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering