chiark / gitweb /
execute: inherit from original input, not the fixed up
[elogind.git] / src / execute.c
index 0c2526b33e1423b35a834db1553d49be468aa0b3..6b6c2855b48739c04febe6878c37d6370f3e3b11 100644 (file)
@@ -171,7 +171,7 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons
         sa.sa.sa_family = AF_UNIX;
         strncpy(sa.un.sun_path+1, LOGGER_SOCKET, sizeof(sa.un.sun_path)-1);
 
-        if (connect(fd, &sa.sa, sizeof(sa)) < 0) {
+        if (connect(fd, &sa.sa, sizeof(sa_family_t) + 1 + sizeof(LOGGER_SOCKET) - 1) < 0) {
                 close_nointr_nofail(fd);
                 return -errno;
         }
@@ -308,6 +308,10 @@ static int setup_output(const ExecContext *context, int socket_fd, const char *i
 
         case EXEC_OUTPUT_INHERIT:
 
+                /* If input got downgraded, inherit the original value */
+                if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
+                        return open_terminal_as(tty_path(context), O_WRONLY, STDOUT_FILENO);
+
                 /* If the input is connected to anything that's not a /dev/null, inherit that... */
                 if (i != EXEC_INPUT_NULL)
                         return dup2(STDIN_FILENO, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO;
@@ -360,10 +364,11 @@ static int setup_error(const ExecContext *context, int socket_fd, const char *id
         if (e == EXEC_OUTPUT_INHERIT &&
             o == EXEC_OUTPUT_INHERIT &&
             i == EXEC_INPUT_NULL &&
+            !is_terminal_input(context->std_input) &&
             getppid () != 1)
                 return STDERR_FILENO;
 
-        /* Duplicate form stdout if possible */
+        /* Duplicate from stdout if possible */
         if (e == o || e == EXEC_OUTPUT_INHERIT)
                 return dup2(STDOUT_FILENO, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO;
 
@@ -968,6 +973,14 @@ int exec_spawn(ExecCommand *command,
                         goto fail;
                 }
 
+                /* Close sockets very early to make sure we don't
+                 * block init reexecution because it cannot bind its
+                 * sockets */
+                if (close_all_fds(fds, n_fds) < 0) {
+                        r = EXIT_FDS;
+                        goto fail;
+                }
+
                 if (!context->same_pgrp)
                         if (setsid() < 0) {
                                 r = EXIT_SETSID;
@@ -1111,16 +1124,6 @@ int exec_spawn(ExecCommand *command,
 
 #ifdef HAVE_PAM
                 if (context->pam_name && username) {
-                        /* Make sure no fds leak into the PAM
-                         * supervisor process. We will call this later
-                         * on again to make sure that any fds leaked
-                         * by the PAM modules get closed before our
-                         * exec(). */
-                        if (close_all_fds(fds, n_fds) < 0) {
-                                r = EXIT_FDS;
-                                goto fail;
-                        }
-
                         if (setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds) < 0) {
                                 r = EXIT_PAM;
                                 goto fail;
@@ -1180,6 +1183,8 @@ int exec_spawn(ExecCommand *command,
                         free(d);
                 }
 
+                /* We repeat the fd closing here, to make sure that
+                 * nothing is leaked from the PAM modules */
                 if (close_all_fds(fds, n_fds) < 0 ||
                     shift_fds(fds, n_fds) < 0 ||
                     flags_fds(fds, n_fds, context->non_blocking) < 0) {