Sulogin: enforce reconnection of stdin/stdout/stderr if a device
authorDr. Werner Fink <werner@suse.de>
Tue, 26 Jul 2011 10:21:13 +0000 (10:21 +0000)
committerDr. Werner Fink <werner@suse.de>
Tue, 26 Jul 2011 10:21:13 +0000 (10:21 +0000)
was specified.

git-svn-id: svn://svn.sv.gnu.org/sysvinit/sysvinit/trunk@107 456724a4-4300-0410-8514-c89748c515a2

doc/Changelog
src/consoles.c
src/consoles.h
src/sulogin.c

index 1116bd96f5d6bc7198e655094390811677e5ecf8..dc99219899ce0970f1d711b4a4578ffd5d1e51c0 100644 (file)
@@ -28,6 +28,8 @@ sysvinit (2.89dsf) UNRELEASED; urgency=low
     otherwise initialize SELinux and load the policy. Patch from
     Petter Reinholdtsen.
   * Make quotes visible in example of the manual page of fstab-decode
+  * Sulogin: enforce reconnection of stdin/stdout/stderr if a device
+    was specified.
 
   [ Petter Reinholdtsen ]
   * Next release will be 2.89dsf.
index d3e6c008fa005a7a0d9de80f4c4488435f6bd8a7..7b3be9b141100d5875f8d95d8377509e65cf625e 100644 (file)
@@ -225,17 +225,23 @@ void consalloc(char * name)
  * /dev/console if but only if /dev/console is used.  On Linux
  * this can be more than one device, e.g. a serial line as well
  * as a virtual console as well as a simple printer.
+ *
+ * Returns 1 if stdout and stderr should be reconnected and 0
+ * otherwise.
  */
-void detect_consoles(const char *device, int fallback)
+int detect_consoles(const char *device, int fallback)
 {
-       int fd;
+       int fd, ret = 0;
 #ifdef __linux__
        char *attrib, *cmdline;
        FILE *fc;
 #endif
        if (!device || *device == '\0')
                fd = dup(fallback);
-       else    fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC);
+       else {
+               fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC);
+               ret = 1;
+       }
 
        if (fd >= 0) {
                DIR *dir;
@@ -250,6 +256,9 @@ void detect_consoles(const char *device, int fallback)
                        goto fallback;
                }
                comparedev = st.st_rdev;
+
+               if (ret && (fstat(fallback, &st) < 0 || comparedev != st.st_rdev))
+                       dup2(fd, fallback);
 #ifdef __linux__
                /*
                 * Check if the device detection for Linux system console should be used.
@@ -294,7 +303,7 @@ void detect_consoles(const char *device, int fallback)
                closedir(dir);
                if (!consoles)
                        goto fallback;
-               return;
+               return ret;
        }
 #ifdef __linux__
 console:
@@ -325,7 +334,7 @@ console:
                }
                closedir(dir);
                fclose(fc);
-               return;
+               return ret;
        }
        /*
         * Detection of devices used for Linux system console using
@@ -363,7 +372,7 @@ console:
                free(attrib);
                if (!consoles)
                        goto fallback;
-               return;
+               return ret;
 
        }
        /*
@@ -471,12 +480,12 @@ console:
                        if (consoles) {
                                if (!device || *device == '\0')
                                        consoles->fd = fallback;
-                               return;
+                               return ret;
                        }
 #endif
                        goto fallback;
                }
-               return;
+               return ret;
        }
 #endif /* __linux __ */
 fallback:
@@ -494,4 +503,5 @@ fallback:
                if (consoles)
                        consoles->fd = fallback;
        }
+       return ret;
 }
index 024a12a8411f72f0dd76cf81c1b66c749a467984..c669eb2a73cad703d8c2f504769e2d9402fcd248 100644 (file)
@@ -45,4 +45,4 @@ struct console {
        struct console *next;
 };
 extern struct console *consoles;
-extern void detect_consoles(const char *, int);
+extern int detect_consoles(const char *, int);
index 99451c2ea9dc54f91e38fce5079974bf8db2aa19..b1bd75aac907fdbf09d5cc06cbdf8f1348a605da 100644 (file)
@@ -841,6 +841,7 @@ int main(int argc, char **argv)
        char *tty = NULL;
        struct passwd *pwd;
        int c, status = 0;
+       int reconnect = 0;
        int opt_e = 0;
        struct console *con;
        pid_t pid;
@@ -854,7 +855,7 @@ int main(int argc, char **argv)
        }
 
        /*
-        *      See if we have a timeout flag.
+        * See if we have a timeout flag.
         */
        opterr = 0;
        while((c = getopt(argc, argv, "ept:")) != EOF) switch(c) {
@@ -884,7 +885,7 @@ int main(int argc, char **argv)
        saved_sighup  = signal(SIGHUP,  SIG_IGN);
 
        /*
-        *      See if we need to open an other tty device.
+        * See if we need to open an other tty device.
         */
        if (optind < argc)
                tty = argv[optind];
@@ -892,9 +893,10 @@ int main(int argc, char **argv)
                tty = getenv("CONSOLE");
 
        /*
-        *      Detect possible consoles, use stdin as fallback.
+        * Detect possible consoles, use stdin as fallback.
+        * If an optional tty is given, reconnect it to stdin.
         */
-       detect_consoles(tty, 0);
+       reconnect = detect_consoles(tty, 0);
 
        /*
         * Should not happen
@@ -906,6 +908,17 @@ int main(int argc, char **argv)
                exit(1);
        }
 
+       /*
+        * If previous stdin was not the speified tty and therefore reconnected
+        * to the specified tty also reconnect stdout and stderr.
+        */
+       if (reconnect) {
+               if (isatty(1) == 0)
+                       dup2(0, 1);
+               if (isatty(2) == 0)
+                       dup2(0, 2);
+       }
+
        /*
         *      Get the root password.
         */
@@ -967,6 +980,7 @@ int main(int argc, char **argv)
                                        break;
                                }
                                fprintf(stderr, "Login incorrect.\n\r");
+                               sleep(3);
                        }
                        if (alarm_rised) {
                                tcfinal(con);