tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

ttyname(3) behaviour when /var/run/dev.db is out of date



If you rename a tty device after running dev_mkdb(8) to create
/var/run/dev.db, then ttyname(3) will return the old (no longer valid)
name.  The appended patch makes it verify the result using stat(2), and
fall back to the old method of walking the /dev directory if the result
appears to be incorrect.  Is this OK?

--apb (Alan Barrett)

Index: lib/libc/gen/ttyname.3
--- lib/libc/gen/ttyname.3      30 Jan 2008 19:24:59 -0000      1.20
+++ lib/libc/gen/ttyname.3      30 Jan 2008 19:38:22 -0000
@@ -109,9 +109,7 @@
 As an optimisation, these functions attempt to obtain information about
 all devices from the
 .Pa /var/run/dev.db
-database, if it exists.
-If the database exists but is out of date, then these functions
-may produce incorrect results.
+database, if it exists and appears to be up to date.
 The database should be updated using the
 .Xr dev_mkdb 8
 command.
Index: lib/libc/gen/ttyname.c
--- lib/libc/gen/ttyname.c      22 Mar 2006 00:05:01 -0000      1.23
+++ lib/libc/gen/ttyname.c      30 Jan 2008 19:38:22 -0000
@@ -64,7 +64,7 @@
 int
 ttyname_r(int fd, char *buf, size_t len)
 {
-       struct stat sb;
+       struct stat sb, sb2;
        struct termios ttyb;
        DB *db;
        DBT data, key;
@@ -98,6 +98,11 @@
        if (fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
                return -1;
 
+       /*
+        * Look it up in the _PATH_DEVDB.db database, if possible.  Fall
+        * back to reading the _DEV directory if database open fails or
+        * database appears to be out of date.
+        */
        (void)memcpy(buf, _PATH_DEV, DEVSZ);
        if ((db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL)) != NULL) {
                (void)memset(&bkey, 0, sizeof(bkey));
@@ -110,9 +115,12 @@
                                errno = ERANGE;
                                return -1;
                        }
-                       (void)memcpy(buf + DEVSZ, data.data, data.size);
-                       (void)(db->close)(db);
-                       return 0;
+                       if (stat(data.data, &sb2) == 0
+                           && sb2.st_rdev == sb.st_rdev) {
+                               (void)memcpy(buf + DEVSZ, data.data, data.size);
+                               (void)(db->close)(db);
+                               return 0;
+                       }
                }
                (void)(db->close)(db);
        }



Home | Main Index | Thread Index | Old Index