]> granicus.if.org Git - procps-ng/commitdiff
present for Jim
authoralbert <>
Tue, 3 Dec 2002 09:07:59 +0000 (09:07 +0000)
committeralbert <>
Tue, 3 Dec 2002 09:07:59 +0000 (09:07 +0000)
pgrep.c
proc/devname.c
proc/readproc.c
proc/readproc.h
ps/parser.c
ps/ps.1
ps/select.c
skill.c

diff --git a/pgrep.c b/pgrep.c
index cb4573c3fb0138a9613e12c3871915788d0c310a..098bf3878d32f06994256a8313ba16065196b4d0 100644 (file)
--- a/pgrep.c
+++ b/pgrep.c
@@ -386,7 +386,7 @@ select_procs (void)
                else if (opt_sid && ! match_numlist (task.session, opt_sid))
                        match = 0;
                else if (opt_term) {
-                       if (task.tty == -1) {
+                       if (task.tty == 0) {
                                match = 0;
                        } else {
                                char tty[256];
index 541d78b5d42b3a5d3b873f332b76329ab911ac29..95b387b8d2553bfe10f24e6300aed029677c41bd 100644 (file)
@@ -195,7 +195,7 @@ unsigned dev_to_tty(char *restrict ret, unsigned chop, int dev, int pid, unsigne
   char *restrict tmp = buf;
   unsigned i = 0;
   int c;
-  if((short)dev == (short)-1) goto fail;
+  if((short)dev == (short)0) goto no_tty;
   if(linux_version_code > LINUX_VERSION(2, 5, 0)){ /* didn't get done yet */
     if(link_name(tmp, major(dev), minor(dev), pid, "tty"   )) goto abbrev;
   }
@@ -203,7 +203,8 @@ unsigned dev_to_tty(char *restrict ret, unsigned chop, int dev, int pid, unsigne
   if(  link_name(tmp, major(dev), minor(dev), pid, "fd/2"  )) goto abbrev;
   if( guess_name(tmp, major(dev), minor(dev)               )) goto abbrev;
   if(  link_name(tmp, major(dev), minor(dev), pid, "fd/255")) goto abbrev;
-fail:
+  // fall through if unable to find a device file
+no_tty:
   strcpy(ret, "?");
   return 1;
 abbrev:
@@ -232,7 +233,7 @@ abbrev:
 int tty_to_dev(const char *restrict const name) {
   struct stat sbuf;
   static char buf[32];
-  if(stat(name, &sbuf) >= 0) return sbuf.st_rdev;
+  if(name[0]=='/' && stat(name, &sbuf) >= 0) return sbuf.st_rdev;
   snprintf(buf,32,"/dev/%s",name);
   if(stat(buf, &sbuf) >= 0) return sbuf.st_rdev;
   snprintf(buf,32,"/dev/tty%s",name);
index ad08ed8d222643f1a3301089144eb3a8aaf5e623..4347b7ff1fbc6777974df1ff4869478026d2747c 100644 (file)
@@ -14,6 +14,7 @@
 #include "procps.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 #include <stdarg.h>
 #include <string.h>
 #include <unistd.h>
@@ -74,19 +75,35 @@ void freeproc(proc_t* p) {
 
 
 
-static void status2proc(const char *S, proc_t *restrict P, int fill){
+static void status2proc(const char *S, proc_t *restrict P){
     char* tmp;
-    if (fill == 1) {
-        memset(P->cmd, 0, sizeof P->cmd);
-        sscanf (S, "Name:\t%15c", P->cmd);
-        tmp = strchr(P->cmd,'\n');
-        *tmp='\0';
-        tmp = strstr (S,"State");
-        sscanf (tmp, "State:\t%c", &P->state);
+    int i;
+
+    // The cmd is escaped, with \\ and \n for backslash and newline.
+    // It certainly may contain "VmSize:" and similar crap.
+    if(unlikely(strncmp("Name:\t",S,6))) fprintf(stderr, "Internal error!\n");
+    S += 6;
+    i = 0;
+    while(i < sizeof P->cmd - 1){
+      int c = *S++;
+      if(unlikely(c=='\n')) break;
+      if(unlikely(c=='\0')) return; // should never happen
+      if(unlikely(c=='\\')){
+        c = *S++;
+        if(c=='\n') break; // should never happen
+        if(!c) break; // should never happen
+        if(c=='n') c='\n'; // else we assume it is '\\'
+      }
+      P->cmd[i++] = c;
     }
+    P->cmd[i] = '\0';
+
+    tmp = strstr (S,"State:\t");
+    if(likely((long)tmp)) P->state = tmp[7];
+    else fprintf(stderr, "Internal error!\n");
 
     tmp = strstr (S,"Pid:");
-    if(tmp) sscanf (tmp,
+    if(likely((long)tmp)) sscanf (tmp,
         "Pid:\t%d\n"
         "PPid:\t%d\n",
         &P->pid,
@@ -95,21 +112,21 @@ static void status2proc(const char *S, proc_t *restrict P, int fill){
     else fprintf(stderr, "Internal error!\n");
 
     tmp = strstr (S,"Uid:");
-    if(tmp) sscanf (tmp,
+    if(likely((long)tmp)) sscanf (tmp,
         "Uid:\t%d\t%d\t%d\t%d",
         &P->ruid, &P->euid, &P->suid, &P->fuid
     );
     else fprintf(stderr, "Internal error!\n");
 
     tmp = strstr (S,"Gid:");
-    if(tmp) sscanf (tmp,
+    if(likely((long)tmp)) sscanf (tmp,
         "Gid:\t%d\t%d\t%d\t%d",
         &P->rgid, &P->egid, &P->sgid, &P->fgid
     );
     else fprintf(stderr, "Internal error!\n");
 
     tmp = strstr (S,"VmSize:");
-    if(tmp) sscanf (tmp,
+    if(likely((long)tmp)) sscanf (tmp,
         "VmSize: %lu kB\n"
         "VmLck: %lu kB\n"
         "VmRSS: %lu kB\n"
@@ -132,7 +149,7 @@ static void status2proc(const char *S, proc_t *restrict P, int fill){
     }
 
     tmp = strstr (S,"SigPnd:");
-    if(tmp) sscanf (tmp,
+    if(likely((long)tmp)) sscanf (tmp,
 #ifdef SIGNAL_STRING
         "SigPnd: %s SigBlk: %s SigIgn: %s %*s %s",
         P->signal, P->blocked, P->sigignore, P->sigcatch
@@ -153,17 +170,25 @@ static void status2proc(const char *S, proc_t *restrict P, int fill){
  */
 static void stat2proc(const char* S, proc_t *restrict P) {
     int num;
-    char* tmp = strrchr(S, ')');       /* split into "PID (cmd" and "<rest>" */
-    *tmp = '\0';                       /* replace trailing ')' with NUL */
+    char* tmp;
+
     /* fill in default values for older kernels */
     P->exit_signal = SIGCHLD;
     P->processor = 0;
     P->rtprio = -1;
     P->sched = -1;
-    /* parse these two strings separately, skipping the leading "(". */
-    memset(P->cmd, 0, sizeof P->cmd);  /* clear even though *P xcalloc'd ?! */
-    sscanf(S, "%d (%15c", &P->pid, P->cmd);   /* comm[16] in kernel */
-    num = sscanf(tmp + 2,                      /* skip space after ')' too */
+
+    P->pid = strtol(S, &tmp, 10);
+    S = tmp + 2;
+    tmp = strrchr(S, ')');      // split into "PID (cmd" and "<rest>"
+    num = tmp - S;
+    if(unlikely(num > sizeof P->cmd)) num = sizeof P->cmd; // 1 too big
+    num--;                       // ditch the ')' character
+    memcpy(P->cmd, S, num);
+    P->cmd[num] = '\0';
+    S = tmp + 2;                 // skip ") "
+
+    num = sscanf(S,
        "%c "
        "%d %d %d %d %d "
        "%lu %lu %lu %lu %lu "
@@ -193,10 +218,6 @@ static void stat2proc(const char* S, proc_t *restrict P) {
 /* -- Linux 2.2.8 to 2.5.17 end here -- */
        &P->rtprio, &P->sched  /* both added to 2.5.18 */
     );
-    
-    /* fprintf(stderr, "stat2proc converted %d fields.\n",num); */
-    if (P->tty == 0)
-       P->tty = -1;  /* the old notty val, update elsewhere bef. moving to 0 */
 }
 
 static void statm2proc(const char* s, proc_t *restrict P) {
@@ -212,8 +233,10 @@ static int file2str(const char *directory, const char *what, char *ret, int cap)
     int fd, num_read;
 
     sprintf(filename, "%s/%s", directory, what);
-    if ( (fd       = open(filename, O_RDONLY, 0)) == -1 ) return -1;
-    if ( (num_read = read(fd, ret, cap - 1))      <= 0 ) num_read = -1;
+    fd = open(filename, O_RDONLY, 0);
+    if(unlikely(fd==-1)) return -1;
+    num_read = read(fd, ret, cap - 1);
+    if(unlikely(num_read<=0)) num_read = -1;
     else ret[num_read] = 0;
     close(fd);
     return num_read;
@@ -226,7 +249,8 @@ static char** file2strvec(const char* directory, const char* what) {
     int align;
 
     sprintf(buf, "%s/%s", directory, what);
-    if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return NULL;
+    fd = open(buf, O_RDONLY, 0);
+    if(fd==-1) return NULL;
 
     /* read whole file into a memory buffer, allocating as we go */
     while ((n = read(fd, buf, sizeof buf - 1)) > 0) {
@@ -272,6 +296,37 @@ static char** file2strvec(const char* directory, const char* what) {
     return ret;
 }
 
+// warning: interface may change
+int read_cmdline(char *restrict const dst, unsigned sz, unsigned pid){
+    char name[32];
+    int fd;
+    int n = 0;
+    snprintf(name, sizeof name, "/proc/%u/cmdline", pid);
+    fd = open(name, O_RDONLY);
+    if(fd==-1) return NULL;
+    dst[0] = '\0';
+    for(;;){
+        ssize_t r = read(fd,dst+n,sz-n);
+        if(r==-1){
+            if(errno==EINTR) continue;
+            break;
+        }
+        n += r;
+        if(n==sz) break; // filled the buffer
+        if(r==0) break;  // EOF
+    }
+    if(n){
+        int i;
+        if(n==sz) n--;
+        dst[n] = '\0';
+        i=n;
+        while(i--){
+          int c = dst[i];
+          if(c<' ' || c>'~') dst[i]=' ';
+        }
+    }
+    return n;
+}
 
 /* These are some nice GNU C expression subscope "inline" functions.
  * The can be used with arbitrary types and evaluate their arguments
@@ -361,7 +416,7 @@ next_proc:                          /* get next PID for consideration */
 
     if (flags & PROC_FILLSTATUS) {         /* read, parse /proc/#/status */
        if ((file2str(path, "status", sbuf, sizeof sbuf)) != -1 ){
-           status2proc(sbuf, p, 0 /*FIXME*/);
+           status2proc(sbuf, p);
        }
     }
 
@@ -459,7 +514,7 @@ next_proc:                          /* get next PID for consideration */
 
   /*  if (flags & PROC_FILLSTATUS) { */        /* read, parse /proc/#/status */
        if ((file2str(path, "status", sbuf, sizeof sbuf)) != -1 ){
-           status2proc(sbuf, p, 0 /*FIXME*/);
+           status2proc(sbuf, p);
        }
 /*    }*/
 
@@ -509,7 +564,7 @@ void look_up_our_self(proc_t *p) {
     file2str(path, "statm", sbuf, sizeof sbuf);
     statm2proc(sbuf, p);               /* ignore statm errors here */
     file2str(path, "status", sbuf, sizeof sbuf);
-    status2proc(sbuf, p, 0 /*FIXME*/);
+    status2proc(sbuf, p);
 }
 
 
index f43a9422c9ad24503f79e69e81bbfa04275667da..9c6a0743efefa01bd1f6d112b0d1614b75521cc5 100644 (file)
@@ -9,6 +9,7 @@
  * in the file COPYING
  */
 
+#include "procps.h"
 
 #define SIGNAL_STRING
 
@@ -174,6 +175,9 @@ extern void closeproc(PROCTAB* PT);
 extern proc_t* readproc(PROCTAB* PT, proc_t* return_buf);
 extern proc_t* ps_readproc(PROCTAB* PT, proc_t* return_buf);
 
+// warning: interface may change
+extern int read_cmdline(char *restrict const dst, unsigned sz, unsigned pid);
+
 extern void look_up_our_self(proc_t *p);
 
 /* deallocate space allocated by readproc
index 645601869d41e99bfbb3e5db3b62c684c0223f41..b00f769fe88129e7888f29c701ea9cb4d6e3ad1b 100644 (file)
@@ -144,15 +144,15 @@ static const char *parse_tty(char *str, sel_union *ret){
   lookup("/dev/pty%s");
   lookup("/dev/%snsole"); /* "co" means "console", maybe do all VCs too? */
   if(!strcmp(str,"-")){   /* "-" means no tty (from AIX) */
-    ret->tty = -1;  /* processes w/o tty */
+    ret->tty = 0;  /* processes w/o tty */
     return 0;
   }
   if(!strcmp(str,"?")){   /* "?" means no tty, which bash eats (Reno BSD?) */
-    ret->tty = -1;  /* processes w/o tty */
+    ret->tty = 0;  /* processes w/o tty */
     return 0;
   }
   if(!*(str+1) && (stat(str,&sbuf)>=0)){  /* Kludge! Assume bash ate '?'. */
-    ret->tty = -1;  /* processes w/o tty */
+    ret->tty = 0;  /* processes w/o tty */
     return 0;
   }
 #undef lookup
diff --git a/ps/ps.1 b/ps/ps.1
index 488c8a403ffb8388a9cd134e3402f58d57f0ef6f..c139a0288eb965db888a67394d99f9c9b8700135 100644 (file)
--- a/ps/ps.1
+++ b/ps/ps.1
@@ -239,6 +239,8 @@ D uninterruptible sleep (usually IO)
 R runnable (on run queue)
 S sleeping
 T traced or stopped
+W paging
+X dead
 Z a defunct ("zombie") process
 
 For BSD formats and when the "stat" keyword is used, additional
index e6bf8c7ff4a641d16fe0ff6d98f9057a920cd80d..57ab59c9d723841a89f94273390e6dc40b50dbea 100644 (file)
@@ -19,7 +19,7 @@
 
 #define session_leader(p)       ((p)->session == (p)->pid)
 #define process_group_leader(p) ((p)->pgid    == (p)->pid)
-#define without_a_tty(p)        ((unsigned short)((p)->tty) == (unsigned short)-1)
+#define without_a_tty(p)        ((unsigned short)((p)->tty) == (unsigned short)0)
 #define some_other_user(p)      ((p)->euid    != cached_euid)
 #define running(p)              (((p)->state=='R')||((p)->state=='D'))
 #define has_our_euid(p)         ((unsigned short)((p)->euid) == (unsigned short)cached_euid)
diff --git a/skill.c b/skill.c
index 18ebbd1b87587a7d897097e568bbce53b468b34f..6d6ed278800bbfe0537b184e73c3434caec5fabe 100644 (file)
--- a/skill.c
+++ b/skill.c
@@ -468,7 +468,7 @@ selection_collection:
           case '-':
           case '?':
             num_found++;
-            ENLIST(tty,-1);
+            ENLIST(tty,0);
             if(!NEXTARG) break;
           }
         }