activate.c revision 8dd4c05b5495c7ffe0f12ace87e71abe17bd0a0e
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering This file is part of systemd.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering Copyright 2013 Zbigniew Jędrzejewski-Szmek
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering systemd is free software; you can redistribute it and/or modify it
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering under the terms of the GNU Lesser General Public License as published by
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering (at your option) any later version.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering systemd is distributed in the hope that it will be useful, but
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering Lesser General Public License for more details.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering You should have received a copy of the GNU Lesser General Public License
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic bool arg_accept = false;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic int add_epoll(int epoll_fd, int fd) {
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev);
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering return log_error_errno(errno, "Failed to add event on epoll fd:%d for fd:%d: %m", epoll_fd, fd);
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic int open_sockets(int *epoll_fd, bool accept) {
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering return log_error_errno(n, "Failed to read listening file descriptors from environment: %m");
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering log_info("Received %i descriptors via the environment.", n);
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering /* Close logging and all other descriptors */
765afd5c4dbc71940d6dd6007ecc3eaa5a0b2aa1Lennart Poettering for (fd = 0; fd < SD_LISTEN_FDS_START + n; fd++)
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering /** Note: we leak some fd's on error here. I doesn't matter
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering * much, since the program will exit immediately anyway, but
765afd5c4dbc71940d6dd6007ecc3eaa5a0b2aa1Lennart Poettering * would be a pain to fix.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering fd = make_socket_fd(LOG_DEBUG, *address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC));
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering return log_error_errno(fd, "Failed to open '%s': %m", *address);
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering assert(fd == SD_LISTEN_FDS_START + count);
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering *epoll_fd = epoll_create1(EPOLL_CLOEXEC);
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering return log_error_errno(errno, "Failed to create epoll object: %m");
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + count; fd++) {
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering log_info("Listening on %s as %i.", strna(name), fd);
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic int launch(char* name, char **argv, char **env, int fds) {
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering static const char* tocopy[] = {"TERM=", "PATH=", "USER=", "HOME="};
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering /* PATH, TERM, HOME, USER, LISTEN_FDS, LISTEN_PID, LISTEN_FDNAMES, NULL */
n_env ++;
n_env ++;
return log_oom();
if (arg_fdname) {
return log_oom();
free(e);
return log_oom();
free(e);
if (!tmp)
return log_oom();
if (!tmp)
return log_oom();
if (child_pid < 0)
if (child_pid == 0) {
(void) reset_all_signal_handlers();
(void) reset_signal_mask();
if (fd2 < 0) {
return fd2;
static int install_chld_handler(void) {
static void help(void) {
help();
case ARG_VERSION:
return version();
return log_oom();
arg_accept = true;
return log_oom();
case ARG_FDNAME:
return -EINVAL;
return -EINVAL;
log_open();
r = install_chld_handler();
return EXIT_FAILURE;
return EXIT_FAILURE;
return EXIT_FAILURE;
return EXIT_FAILURE;
if (arg_accept) {
return EXIT_FAILURE;
return EXIT_SUCCESS;