OSDN Git Service

Cleanup pass: inline find_tty_name(), bounds check fscanf(), use libc
authorRob Landley <rob@landley.net>
Tue, 10 Nov 2015 00:22:33 +0000 (18:22 -0600)
committerRob Landley <rob@landley.net>
Tue, 10 Nov 2015 00:22:33 +0000 (18:22 -0600)
functions to read major()/minor(), fix printf format warnings in error msg.

toys/posix/ps.c

index bc3060c..e42e7ec 100644 (file)
@@ -181,32 +181,6 @@ static int match_process(long long *slot)
   return 1;
 }
 
-static void find_tty_name(char *out, int rdev) {
-  int major = (rdev>>8)&0xfff, minor = ((rdev>>12)&0xfff00)|(rdev&0xff);
-  FILE *fp = fopen("/proc/tty/drivers", "r");
-
-  if (fp) {
-    int tty_major;
-
-    while (fscanf(fp, "%*s %s %d %*s %*s", out, &tty_major) == 2) {
-      // TODO: we could parse the minor range too.
-      if (tty_major == major) {
-        struct stat st;
-
-        sprintf(out + strlen(out), "%d", minor);
-        if (!stat(out, &st) && S_ISCHR(st.st_mode) && st.st_rdev == rdev) {
-          fclose(fp);
-          return;
-        }
-      }
-    }
-    fclose(fp);
-  }
-
-  // Really couldn't find it, so just show major:minor.
-  sprintf(out, "%d:%d", major, minor);
-}
-
 // dirtree callback.
 // toybuf used as: 1024 /proc/$PID/stat, 1024 slot[], 2048 /proc/$PID/cmdline
 static int do_ps(struct dirtree *new)
@@ -342,14 +316,13 @@ static int do_ps(struct dirtree *new)
     // TTY
     } else if (i==12) {
       int rdev = slot[4];
+      struct stat st;
 
-      // The common case is no tty, and we call that "?" rather than "0:0".
-      if (rdev == 0) strcpy(out, "?");
+      // Call no tty "?" rather than "0:0".
+      if (!rdev) strcpy(out, "?");
       else {
         // Can we readlink() our way to a name?
         for (i=0; i<3; i++) {
-          struct stat st;
-
           sprintf(scratch, "%lld/fd/%i", *slot, i);
           fd = dirtree_parentfd(new);
           if (!fstatat(fd, scratch, &st, 0) && S_ISCHR(st.st_mode)
@@ -362,9 +335,28 @@ static int do_ps(struct dirtree *new)
         }
 
         // Couldn't find it, try all the tty drivers.
-        if (i == 3) find_tty_name(out, rdev);
+        if (i == 3) {
+          FILE *fp = fopen("/proc/tty/drivers", "r");
+          int tty_major = 0, maj = major(rdev), min = minor(rdev);
+
+          if (fp) {
+            while (fscanf(fp, "%*s %256s %d %*s %*s", out, &tty_major) == 2) {
+              // TODO: we could parse the minor range too.
+              if (tty_major == maj) {
+                sprintf(out + strlen(out), "%d", min);
+                if (!stat(out, &st) && S_ISCHR(st.st_mode) && st.st_rdev==rdev)
+                  break;
+              }
+              tty_major = 0;
+            }
+            fclose(fp);
+          }
+
+          // Really couldn't find it, so just show major:minor.
+          if (!tty_major) sprintf(out, "%d:%d", maj, min);
+        }
 
-        if (!strncmp(out, "/dev/", 5)) out += 5;
+        strstart(&out, "/dev/");
       }
 
     // TIME ELAPSED
@@ -446,9 +438,8 @@ void comma_args(struct arg_list *al, char *err,
     arg = al->arg;
     while ((next = comma_iterate(&arg, &len)))
       if ((next = callback(next, len)))
-        perror_exit("%s '%s'\n% *c", err, al->arg,
-                    strlen(toys.which->name) + 2 +
-                    strlen(err) + 2 + 1+next-al->arg, '^');
+        perror_exit("%s '%s'\n%*c", err, al->arg,
+          (int)(5+strlen(toys.which->name)+strlen(err)+next-al->arg), '^');
     al = al->next;
   }
 }