]> granicus.if.org Git - procps-ng/commitdiff
2.5.61
authoralbert <>
Mon, 17 Feb 2003 00:57:15 +0000 (00:57 +0000)
committeralbert <>
Mon, 17 Feb 2003 00:57:15 +0000 (00:57 +0000)
NEWS
proc/module.mk
proc/procps.h
proc/readproc.c
proc/readproc.h

diff --git a/NEWS b/NEWS
index e123cf4fe6648da9a899c7d2f5cae9ec790b4c6d..5787a254bf81ffe66509098cebb56d032afa0d6c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,6 @@
 procps-3.1.5 --> procps-3.1.6
 
+handle the 2.5.61 kernel
 top: memory leak fixed
 ps: new --ppid option selects by PPID
 watch: new --no-title option     #179862
index e0f1bd7a17bee7b311d61fc9af9ba600dfaa2d12..de0399b571bfa5fe20fac5d63073b63663970f6a 100644 (file)
@@ -14,19 +14,22 @@ LIBOBJ :=  $(LIBSRC:.c=.o)
 #ALL        += proc/lib$(NAME).a
 #INSTALL    += $(usr/lib)/lib$(NAME).a # plus $(usr/include)$(NAME) gunk
 
+FPIC       := -fpic
+
 ifeq ($(SHARED),1)
 ALL        += proc/$(SONAME)
 INSTALL    += $(lib)/$(SONAME)
-FPIC       := -fpic
+LIBFLAGS   := -DSHARED=1 $(FPIC)
 LIBPROC    := proc/$(SONAME)
 else
 ALL        += proc/lib$(NAME).a
+LIBFLAGS   := -DSHARED=0
 LIBPROC    := proc/lib$(NAME).a
 endif
 
 # Separate rule for this directory, to use -fpic or -fPIC
 $(filter-out proc/version.o,$(LIBOBJ)): proc/%.o: proc/%.c
-       $(CC) -c $(CFLAGS) $(FPIC) $< -o $@
+       $(CC) -c $(CFLAGS) $(LIBFLAGS) $< -o $@
 
 LIB_X := COPYING module.mk library.map
 TARFILES += $(LIBSRC) $(LIBHDR) $(addprefix proc/,$(LIB_X))
@@ -71,4 +74,4 @@ $(lib)/$(SONAME) : proc/$(SONAME)
 
 
 proc/version.o:        proc/version.c proc/version.h
-       $(CC) $(CFLAGS) $(FPIC) -DVERSION=\"$(VERSION)\" -DSUBVERSION=\"$(SUBVERSION)\" -DMINORVERSION=\"$(MINORVERSION)\" -c -o $@ $<
+       $(CC) $(CFLAGS) $(LIBFLAGS) -DVERSION=\"$(VERSION)\" -DSUBVERSION=\"$(SUBVERSION)\" -DMINORVERSION=\"$(MINORVERSION)\" -c -o $@ $<
index 95134a6bb1ffcdaf46a5b58407f3f5d1aec55af5..5909c20aac80a3e51f7750c6ce66648dbc7022ac 100644 (file)
 #define expected(x,y)   (x)
 #endif
 
+#if SHARED==1 && (__GNUC__ > 2 || __GNUC_MINOR__ >= 96)
+#define LABEL_OFFSET
+#endif
+
+
 // marks old junk, to warn non-procps library users
 #if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
 #define OBSOLETE __attribute__((deprecated))
index f71ce16371d3e59822e7e91062705e8335c58290..941d7a83b7dabb6b4d4b06af343924377686622f 100644 (file)
 #include <fs_secure.h>
 #endif
 
+#ifdef PROF
+extern void __cyg_profile_func_enter(void*,void*);
+#define ENTER(x) __cyg_profile_func_enter((void*)x,(void*)x)
+#define LEAVE(x) __cyg_profile_func_exit((void*)x,(void*)x)
+#else
+#define ENTER(x)
+#define LEAVE(x)
+#endif
+
 /* initiate a process table scan
  */
 PROCTAB* openproc(int flags, ...) {
@@ -77,103 +86,237 @@ void freeproc(proc_t* p) {
 }
 
 
-// 2.5.xx looks like:
-//
-// "State:\t%s\n"
-// "Tgid:\t%d\n"
-// "Pid:\t%d\n"
-// "PPid:\t%d\n"
-// "TracerPid:\t%d\n"
-
-static void status2proc(const char *S, proc_t *restrict P){
-    char* tmp;
-    unsigned 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(tmp)) P->state = tmp[7];
-    else fprintf(stderr, "Internal error!\n");
-
-    tmp = strstr (S,"PPid:");
-    if(likely(tmp)) sscanf (tmp,
-        "PPid:\t%d\n",
-        &P->ppid
-    );
-    else fprintf(stderr, "Internal error!\n");
-
-    tmp = strstr (S,"Uid:");
-    if(likely(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(likely(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(likely(tmp)) sscanf (tmp,
-        "VmSize: %lu kB\n"
-        "VmLck: %lu kB\n"
-        "VmRSS: %lu kB\n"
-        "VmData: %lu kB\n"
-        "VmStk: %lu kB\n"
-        "VmExe: %lu kB\n"
-        "VmLib: %lu kB\n",
-        &P->vm_size, &P->vm_lock, &P->vm_rss, &P->vm_data,
-        &P->vm_stack, &P->vm_exe, &P->vm_lib
-    );
-    else /* looks like an annoying kernel thread */
-    {
-        P->vm_size  = 0;
-        P->vm_lock  = 0;
-        P->vm_rss   = 0;
-        P->vm_data  = 0;
-        P->vm_stack = 0;
-        P->vm_exe   = 0;
-        P->vm_lib   = 0;
-    }
+typedef struct status_table_struct {
+    unsigned char name[6];        // /proc/*/status field name
+    short len;                    // name length
+#ifdef LABEL_OFFSET
+    long offset;                  // jump address offset
+#else
+    void *addr;
+#endif
+} status_table_struct;
 
-    // 2.1   SigPnd SigBlk SigIgn SigCat  ("SigCat")
-    // other SigPnd SigBlk SigIgn SigCgt
-    // 2.5+  SigPnd ShdPnd SigBlk SigIgn SigCgt
+#ifdef LABEL_OFFSET
+#define F(x) {#x, sizeof(#x)-1, (int)(&&case_##x-&&base)},
+#else
+#define F(x) {#x, sizeof(#x)-1, &&case_##x},
+#endif
+#define NUL  {"", 0, 0},
+
+// Derived from:
+// gperf -7 --language=ANSI-C --key-positions=1,3,4 -C -n -c sml.gperf
+
+static void status2proc(char *S, proc_t *restrict P){
+    static const unsigned char asso[] = {
+        56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+        56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+        56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+        56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 15, 56, 56, 56, 56, 56,
+        56, 56, 25, 30, 15,  3, 56,  5, 56,  3, 56, 56,  3, 56, 10, 56,
+        18, 56, 13,  0, 30, 25,  0, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+        56, 30, 56,  8,  0,  0, 56, 25, 56,  5, 56, 56, 56,  0, 56, 56,
+        56, 56, 56, 56,  0, 56, 56, 56,  0, 56, 56, 56, 56, 56, 56, 56
+    };
+    static const status_table_struct table[] = {
+        F(VmStk)
+        NUL
+        NUL
+        F(VmExe)
+        NUL
+        F(VmSize)
+        NUL
+        NUL
+        F(VmLib)
+        NUL
+        F(Name)
+        F(VmLck)
+        NUL
+        F(VmRSS)
+        NUL
+        NUL
+        NUL
+        NUL
+        F(ShdPnd)
+        NUL
+        F(Gid)
+        NUL
+        NUL
+        F(PPid)
+        NUL
+        NUL
+        NUL
+        NUL
+        F(SigIgn)
+        NUL
+        F(State)
+        NUL
+        NUL
+        F(Pid)
+        NUL
+        F(Tgid)
+        NUL
+        NUL
+        NUL
+        NUL
+        F(Uid)
+        NUL
+        NUL
+        F(SigPnd)
+        NUL
+        F(VmData)
+        NUL
+        NUL
+        NUL
+        NUL
+        F(SigBlk)
+        NUL
+        NUL
+        NUL
+        NUL
+        F(SigCgt)
+        NUL
+        NUL
+        NUL
+        NUL
+        NUL
+        NUL
+        NUL
+        NUL
+    };
+
+#undef F
+#undef NUL
+
+ENTER(0x220);
+
+    P->vm_size = 0;
+    P->vm_lock = 0;
+    P->vm_rss  = 0;
+    P->vm_data = 0;
+    P->vm_stack= 0;
+    P->vm_exe  = 0;
+    P->vm_lib  = 0;
+
+    goto base;
 
-    tmp = strstr (S,"SigPnd:");
-    if(likely(tmp)) sscanf (tmp,
-#ifdef SIGNAL_STRING
-        "SigPnd: %s SigBlk: %s SigIgn: %s %*s %s",
-        P->signal, P->blocked, P->sigignore, P->sigcatch
+    for(;;){
+        char *colon;
+        status_table_struct entry;
+
+        // advance to next line
+        S = strchr(S, '\n');
+        if(unlikely(!S)) break;  // if no newline
+        S++;
+
+        // examine a field name (hash and compare)
+    base:
+        if(unlikely(!*S)) break;
+        entry = table[63 & (asso[S[3]] + asso[S[2]] + asso[S[0]])];
+        colon = strchr(S, ':');
+        if(unlikely(!colon)) break;
+        if(unlikely(colon[1]!='\t')) break;
+        if(unlikely(colon-S != entry.len)) continue;
+        if(unlikely(memcmp(entry.name,S,colon-S))) continue;
+
+        S = colon+2; // past the '\t'
+
+#ifdef LABEL_OFFSET
+        goto *(&&base + entry.offset);
 #else
-        "SigPnd: %Lx SigBlk: %Lx SigIgn: %Lx %*s %Lx",
-        &P->signal, &P->blocked, &P->sigignore, &P->sigcatch
+        goto *entry.addr;
 #endif
-    );
-    else fprintf(stderr, "Internal error!\n");
-}
 
+    case_Gid:
+        P->rgid = strtol(S,&S,10);
+        P->egid = strtol(S,&S,10);
+        P->sgid = strtol(S,&S,10);
+        P->fgid = strtol(S,&S,10);
+        continue;
+    case_Name:{
+        int 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';
+        continue;
+    }
+    case_PPid:
+        P->ppid = strtol(S,&S,10);
+        continue;
+    case_Pid:
+        P->pid = strtol(S,&S,10);
+        continue;
+
+    case_ShdPnd:
+        memcpy(P->signal, S, 16);
+        P->signal[16] = '\0';
+        continue;
+    case_SigBlk:
+        memcpy(P->blocked, S, 16);
+        P->blocked[16] = '\0';
+        continue;
+    case_SigCgt:
+        memcpy(P->sigcatch, S, 16);
+        P->sigcatch[16] = '\0';
+        continue;
+    case_SigIgn:
+        memcpy(P->sigignore, S, 16);
+        P->sigignore[16] = '\0';
+        continue;
+    case_SigPnd:
+        memcpy(P->signal, S, 16);
+        P->signal[16] = '\0';
+        continue;
+
+    case_State:
+        P->state = *S;
+        continue;
+    case_Tgid:
+        P->tgid = strtol(S,&S,10);
+        continue;
+    case_Uid:
+        P->ruid = strtol(S,&S,10);
+        P->euid = strtol(S,&S,10);
+        P->suid = strtol(S,&S,10);
+        P->fuid = strtol(S,&S,10);
+        continue;
+    case_VmData:
+        P->vm_data = strtol(S,&S,10);
+        continue;
+    case_VmExe:
+        P->vm_exe = strtol(S,&S,10);
+        continue;
+    case_VmLck:
+        P->vm_lock = strtol(S,&S,10);
+        continue;
+    case_VmLib:
+        P->vm_lib = strtol(S,&S,10);
+        continue;
+    case_VmRSS:
+        P->vm_rss = strtol(S,&S,10);
+        continue;
+    case_VmSize:
+        P->vm_size = strtol(S,&S,10);
+        continue;
+    case_VmStk:
+        P->vm_stack = strtol(S,&S,10);
+        continue;
+    }
+LEAVE(0x220);
+}
 
+///////////////////////////////////////////////////////////////////////
 
 // Reads /proc/*/stat files, being careful not to trip over processes with
 // names like ":-) 1 2 3 4 5 6".
@@ -181,6 +324,8 @@ static void stat2proc(const char* S, proc_t *restrict P) {
     unsigned num;
     char* tmp;
 
+ENTER(0x160);
+
     /* fill in default values for older kernels */
     P->exit_signal = SIGCHLD;
     P->processor = 0;
@@ -225,8 +370,11 @@ 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 */
     );
+LEAVE(0x160);
 }
 
+/////////////////////////////////////////////////////////////////////////
+
 static void statm2proc(const char* s, proc_t *restrict P) {
     int num;
     num = sscanf(s, "%ld %ld %ld %ld %ld %ld %ld",
@@ -243,9 +391,9 @@ static int file2str(const char *directory, const char *what, char *ret, int cap)
     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);
+    if(unlikely(num_read<=0)) return -1;
+    ret[num_read] = '\0';
     return num_read;
 }
 
@@ -329,8 +477,8 @@ int read_cmdline(char *restrict const dst, unsigned sz, unsigned pid){
         dst[n] = '\0';
         i=n;
         while(i--){
-          int c = dst[i];
-          if(c<' ' || c>'~') dst[i]=' ';
+            int c = dst[i];
+            if(c<' ' || c>'~') dst[i]=' ';
         }
     }
     return n;
index 88fe77569812847e5d211b3f5e96979d84529911..2ac033b5f28bf48273ce390e51c60ce8981d4358 100644 (file)
@@ -133,6 +133,7 @@ typedef struct proc_t {
        session,        /* session id */
        tty,            /* full device number of controlling terminal */
        tpgid,          /* terminal process group id */
+       tgid,           /* thread group ID */
        exit_signal,    /* might not be SIGCHLD */
        processor;      /* current (or most recent?) CPU */
 #ifdef FLASK_LINUX