]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/activate/activate.c
tree-wide: port users over to use new ERRNO_IS_ACCEPT_AGAIN() call
[thirdparty/systemd.git] / src / activate / activate.c
index 45386a38f4c4d4440a13a707c4d5347badeefb30..473366fb2022824f96291945a6875c4b9f4c24e2 100644 (file)
 #include "sd-daemon.h"
 
 #include "alloc-util.h"
+#include "errno-util.h"
 #include "escape.h"
 #include "fd-util.h"
 #include "log.h"
 #include "macro.h"
+#include "pretty-print.h"
 #include "process-util.h"
 #include "signal-util.h"
 #include "socket-util.h"
 #include "string-util.h"
 #include "strv.h"
+#include "terminal-util.h"
+#include "util.h"
 
 static char** arg_listen = NULL;
 static bool arg_accept = false;
@@ -71,7 +75,9 @@ static int open_sockets(int *epoll_fd, bool accept) {
                         except[fd] = fd;
 
                 log_close();
-                close_all_fds(except, 3 + n);
+                r = close_all_fds(except, 3 + n);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to close all file descriptors: %m");
         }
 
         /** Note: we leak some fd's on error here. I doesn't matter
@@ -120,10 +126,9 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd,
         char **s;
         int r;
 
-        if (arg_inetd && n_fds != 1) {
-                log_error("--inetd only supported for single file descriptors.");
-                return -EINVAL;
-        }
+        if (arg_inetd && n_fds != 1)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "--inetd only supported for single file descriptors.");
 
         length = strv_length(arg_setenv);
 
@@ -248,7 +253,7 @@ static int fork_and_exec_process(const char* child, char** argv, char **env, int
         if (!joined)
                 return log_oom();
 
-        r = safe_fork("(activate)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &child_pid);
+        r = safe_fork("(activate)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &child_pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -266,11 +271,15 @@ static int do_accept(const char* name, char **argv, char **envp, int fd) {
         _cleanup_close_ int fd_accepted = -1;
 
         fd_accepted = accept4(fd, NULL, NULL, 0);
-        if (fd_accepted < 0)
+        if (fd_accepted < 0) {
+                if (ERRNO_IS_ACCEPT_AGAIN(errno))
+                        return 0;
+
                 return log_error_errno(errno, "Failed to accept connection on fd:%d: %m", fd);
+        }
 
-        getsockname_pretty(fd_accepted, &local);
-        getpeername_pretty(fd_accepted, true, &peer);
+        (void) getsockname_pretty(fd_accepted, &local);
+        (void) getpeername_pretty(fd_accepted, true, &peer);
         log_info("Connection from %s to %s", strna(peer), strna(local));
 
         return fork_and_exec_process(name, argv, envp, fd_accepted);
@@ -310,7 +319,14 @@ static int install_chld_handler(void) {
         return 0;
 }
 
-static void help(void) {
+static int help(void) {
+        _cleanup_free_ char *link = NULL;
+        int r;
+
+        r = terminal_urlify_man("systemd-socket-activate", "1", &link);
+        if (r < 0)
+                return log_oom();
+
         printf("%s [OPTIONS...]\n\n"
                "Listen on sockets and launch child on connection.\n\n"
                "Options:\n"
@@ -323,9 +339,13 @@ static void help(void) {
                "  -E --setenv=NAME[=VALUE]   Pass an environment variable to children\n"
                "     --fdname=NAME[:NAME...] Specify names for file descriptors\n"
                "     --inetd                 Enable inetd file descriptor passing protocol\n"
-               "\n"
-               "Note: file descriptors from sd_listen_fds() will be passed through.\n"
-               , program_invocation_short_name);
+               "\nNote: file descriptors from sd_listen_fds() will be passed through.\n"
+               "\nSee the %s for details.\n"
+               , program_invocation_short_name
+               , link
+        );
+
+        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -358,8 +378,7 @@ static int parse_argv(int argc, char *argv[]) {
         while ((c = getopt_long(argc, argv, "+hl:aE:d", options, NULL)) >= 0)
                 switch(c) {
                 case 'h':
-                        help();
-                        return 0;
+                        return help();
 
                 case ARG_VERSION:
                         return version();
@@ -372,19 +391,17 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'd':
-                        if (arg_socket_type == SOCK_SEQPACKET) {
-                                log_error("--datagram may not be combined with --seqpacket.");
-                                return -EINVAL;
-                        }
+                        if (arg_socket_type == SOCK_SEQPACKET)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "--datagram may not be combined with --seqpacket.");
 
                         arg_socket_type = SOCK_DGRAM;
                         break;
 
                 case ARG_SEQPACKET:
-                        if (arg_socket_type == SOCK_DGRAM) {
-                                log_error("--seqpacket may not be combined with --datagram.");
-                                return -EINVAL;
-                        }
+                        if (arg_socket_type == SOCK_DGRAM)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "--seqpacket may not be combined with --datagram.");
 
                         arg_socket_type = SOCK_SEQPACKET;
                         break;
@@ -436,17 +453,15 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached("Unhandled option");
                 }
 
-        if (optind == argc) {
-                log_error("%s: command to execute is missing.",
-                          program_invocation_short_name);
-                return -EINVAL;
-        }
+        if (optind == argc)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "%s: command to execute is missing.",
+                                       program_invocation_short_name);
 
-        if (arg_socket_type == SOCK_DGRAM && arg_accept) {
-                log_error("Datagram sockets do not accept connections. "
-                          "The --datagram and --accept options may not be combined.");
-                return -EINVAL;
-        }
+        if (arg_socket_type == SOCK_DGRAM && arg_accept)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "Datagram sockets do not accept connections. "
+                                       "The --datagram and --accept options may not be combined.");
 
         arg_args = argv + optind;