Rewrite findtty() in bootlogd to recursively search /dev/ for the
authorPetter Reinholdtsen <pere@hungry.com>
Sun, 22 Nov 2009 22:21:02 +0000 (22:21 +0000)
committerPetter Reinholdtsen <pere@hungry.com>
Sun, 22 Nov 2009 22:21:02 +0000 (22:21 +0000)
correct device, to handle terminal devices for example in /dev/pty/.
Patch from Debian.

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

doc/Changelog
src/bootlogd.c

index 18cd20becf85468790a9f188f8b29f6caa44de26..fc507c346bf77b2f8b224b0ed2ce0a2f569165cf 100644 (file)
@@ -19,6 +19,9 @@ sysvinit (2.88dsf) UNRELEASED; urgency=low
     Frysinger and Gentoo.
   * Fix race condition in utmp writing.  Patch from Gil Kloepfer via
     Mike Frysinger and Gentoo.
+  * Rewrite findtty() in bootlogd to recursively search /dev/ for the
+    correct device, to handle terminal devices for example in /dev/pty/.
+    Patch from Debian.
 
  -- Petter Reinholdtsen <pere@hungry.com>  Sun, 12 Jul 2009 19:58:10 +0200
 
index 25bc49f7b06ea6225cb08595d6d53bfbf12b757b..924f50292669f5ac43f9a157e94cf2d9c7ea2a10 100644 (file)
@@ -107,41 +107,60 @@ void handler(int sig)
 
 /*
  *     Scan /dev and find the device name.
- *     Side-effect: directory is changed to /dev
- *
- *     FIXME: scan subdirectories for devfs support ?
  */
-int findtty(char *res, int rlen, dev_t dev)
+static int findtty(char *res, int rlen, dev_t dev)
 {
        DIR             *dir;
        struct dirent   *ent;
        struct stat     st;
-       int             r = 0;
-
-       if (chdir("/dev") < 0 || (dir = opendir(".")) == NULL) {
-               perror("bootlogd: /dev");
+       int             r = -1;
+       char *olddir = getcwd(NULL, 0);
+
+       if (chdir(startdir) < 0 || (dir = opendir(".")) == NULL) {
+               int msglen = strlen(startdir) + 11;
+               char *msg = malloc(msglen);
+               snprintf(msg, msglen, "bootlogd: %s", startdir);
+               perror(msg);
+               free(msg);
+               chdir(olddir);
                return -1;
        }
        while ((ent = readdir(dir)) != NULL) {
                if (lstat(ent->d_name, &st) != 0)
                        continue;
+               if (S_ISDIR(st.st_mode)
+                   && 0 != strcmp(".", ent->d_name)
+                   && 0 != strcmp("..", ent->d_name)) {
+                       char *path = malloc(rlen);
+                       snprintf(path, rlen, "%s/%s", startdir, ent->d_name);
+                       r = findtty(res, path, rlen, dev);
+                       free(path);
+                       if (0 == r) { /* device found, return */
+                               closedir(dir);
+                               chdir(olddir);
+                               return 0;
+                       }
+                       continue;
+               }
                if (!S_ISCHR(st.st_mode))
                        continue;
                if (st.st_rdev == dev) {
-                       break;
+                       if (strlen(ent->d_name) + strlen(startdir) + 1 >= rlen) {
+                               fprintf(stderr, "bootlogd: console device name too long\n");
+                               closedir(dir);
+                               chdir(olddir);
+                               return -1;
+                       } else {
+                               snprintf(res, rlen, "%s/%s", startdir, ent->d_name);
+                               closedir(dir);
+                               chdir(olddir);
+                               return 0;
+                       }
                }
        }
-       if (ent == NULL) {
-               fprintf(stderr, "bootlogd: cannot find console device "
-                       "%d:%d in /dev\n", major(dev), minor(dev));
-               r = -1;
-       } else if ((int)strlen(ent->d_name) + 5 >= rlen) {
-               fprintf(stderr, "bootlogd: console device name too long\n");
-               r = -1;
-       } else
-               snprintf(res, rlen, "/dev/%s", ent->d_name);
        closedir(dir);
 
+       chdir(olddir);
        return r;
 }
 
@@ -236,12 +255,21 @@ int consolename(char *res, int rlen)
                /*
                 *      Old kernel, can find real device easily.
                 */
-               return findtty(res, rlen, st.st_rdev);
+               int r = findtty(res, "/dev", rlen, st.st_rdev);
+               if (0 != r)
+                       fprintf(stderr, "bootlogd: cannot find console device "
+                               "%d:%d under /dev\n", major(st.st_rdev), minor(st.st_rdev));
+               return r;
        }
 
 #ifdef TIOCGDEV
-       if (ioctl(0, TIOCGDEV, &kdev) == 0)
-               return findtty(res, rlen, (dev_t)kdev);
+       if (ioctl(0, TIOCGDEV, &kdev) == 0) {
+               int r = findtty(res, "/dev", rlen, (dev_t)kdev);
+               if (0 != r)
+                       fprintf(stderr, "bootlogd: cannot find console device "
+                               "%d:%d under /dev\n", major(kdev), minor(kdev));
+               return r;
+       }
        if (errno != ENOIOCTLCMD) return -1;
 #endif