]> granicus.if.org Git - procps-ng/commitdiff
check_gcc for -m64, pmap shows shmid
authoralbert <>
Thu, 29 Jan 2004 22:28:13 +0000 (22:28 +0000)
committeralbert <>
Thu, 29 Jan 2004 22:28:13 +0000 (22:28 +0000)
Makefile
dummy.c [new file with mode: 0644]
pmap.c
proc/module.mk

index df5001e21a99fd69a53101ecfcc9273102bf7322..c73179d5da4e5aaa60bdcd09d9b9d01292ead531 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -61,12 +61,13 @@ MANFILES := $(man1)uptime.1 $(man1)tload.1 $(man1)free.1 $(man1)w.1 \
 
 TARFILES := AUTHORS BUGS NEWS README TODO COPYING COPYING.LIB \
             Makefile procps.lsm procps.spec v t README.top \
-            minimal.c $(notdir $(MANFILES)) \
+            minimal.c $(notdir $(MANFILES)) dummy.c \
             uptime.c tload.c free.c w.c top.c vmstat.c watch.c skill.c \
             sysctl.c pgrep.c top.h pmap.c slabtop.c
 
 # Stuff (tests, temporary hacks, etc.) left out of the standard tarball
-_TARFILES :=
+# plus the top-level Makefile to make it work stand-alone.
+_TARFILES := Makefile
 
 CURSES := -I/usr/include/ncurses -lncurses
 
@@ -94,6 +95,27 @@ PKG_LDFLAGS := -Wl,-warn-common
 LDFLAGS :=
 ALL_LDFLAGS := $(PKG_LDFLAGS) $(LDFLAGS)
 
+############ Add some extra flags if gcc allows
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(MAKECMDGOALS),tar)  
+ifneq ($(MAKECMDGOALS),extratar)
+
+# Unlike the kernel one, this check_gcc goes all the way to
+# producing an executable. There might be a -m64 that works
+# until you go looking for a 64-bit curses library.
+check_gcc = $(shell if $(CC) $(ALL_CFLAGS) dummy.c $(ALL_LDFLAGS) $(1) -o /dev/null $(CURSES) > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
+
+ALL_CFLAGS += $(call check_gcc,-Wdeclaration-after-statement,)
+ALL_CFLAGS += $(call check_gcc,-Wpadded,)
+
+# Be 64-bit if at all possible.
+ALL_CFLAGS += $(call check_gcc,-m64,)
+
+endif
+endif
+endif
+
 ############ misc.
 
 # free.c pmap.c sysctl.c uptime.c vmstat.c watch.c pgrep.c skill.c tload.c top.c w.c
@@ -179,13 +201,13 @@ w.o:    w.c
 ############ prog.o --> prog
 
 pmap w uptime tload free sysctl vmstat utmp pgrep skill: % : %.o $(LIBPROC)
-       $(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $^
+       $(CC) $(ALL_CFLAGS) $^ $(ALL_LDFLAGS) -o $@
 
 slabtop top: % : %.o $(LIBPROC)
-       $(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $^ $(CURSES)
+       $(CC) $(ALL_CFLAGS) $^ $(ALL_LDFLAGS) -o $@ $(CURSES)
 
 watch: % : %.o
-       $(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $^ $(CURSES)
+       $(CC) $(ALL_CFLAGS) $^ $(ALL_LDFLAGS) -o $@ $(CURSES)
 
 ############ progX --> progY
 
diff --git a/dummy.c b/dummy.c
new file mode 100644 (file)
index 0000000..95e7824
--- /dev/null
+++ b/dummy.c
@@ -0,0 +1,31 @@
+// This is to test the compiler.
+
+#include <sys/ioctl.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <curses.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// Foul POS defines all sorts of stuff...
+#include <term.h>
+#undef tab
+
+#include <termios.h>
+#include <time.h>
+#include <unistd.h>
+#include <values.h>
+
+int main(int argc, char *argv[]){
+  (void)argc;
+  (void)argv;
+  return 0;
+}
diff --git a/pmap.c b/pmap.c
index a2075ac1455b4c5f96e51a14595a236212d140a6..003db4fccb5bd22c83324eadf571bd766ad807cd 100644 (file)
--- a/pmap.c
+++ b/pmap.c
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
 #include "proc/readproc.h"
 #include "proc/version.h"
+#include "proc/escape.h"
 
 static void usage(void) NORETURN;
 static void usage(void){
@@ -40,81 +45,111 @@ static int d_option;
 static int q_option;
 
 
-static const char *get_args(unsigned pid){
-  static char cmdbuf[64];
-  char buf[32];
-  int fd;
-  ssize_t count;
-
-  do{
-    sprintf(buf,"/proc/%u/cmdline",pid);
-    if( (( fd=open(buf,O_RDONLY) )) == -1) break;
-    count = read(fd, cmdbuf, sizeof(cmdbuf)-1);
-    close(fd);
-    if(count<1) break;
-    cmdbuf[count] = '\0';
-    if(!isprint(cmdbuf[0])) break;
-    while(count--) if(!isprint(cmdbuf[count])) cmdbuf[count]=' ';
-    return cmdbuf;
-  }while(0);
-
-  do{
-    char *cp;
-    sprintf(buf,"/proc/%u/stat",pid);
-    if( (( fd=open(buf,O_RDONLY) )) == -1) break;
-    count = read(fd, cmdbuf, sizeof(cmdbuf)-1);
-    close(fd);
-    if(count<1) break;
-    cmdbuf[count] = '\0';
-    while(count--) if(!isprint(cmdbuf[count])) cmdbuf[count]=' ';
-    cp = strrchr(cmdbuf,')');
-    if(!cp) break;
-    cp[0] = ']';
-    cp[1] = '\0';
-    cp = strchr(cmdbuf,'(');
-    if(!cp) break;
-    if(!isprint(cp[1])) break;
-    cp[0] = '[';
-    return cp;
-  }while(0);
+static unsigned shm_minor = ~0u;
+
+static void discover_shm_minor(void){
+  void *addr;
+  int shmid;
+  char mapbuf[256];
+
+  if(!freopen("/proc/self/maps", "r", stdin)) return;
+
+  // create
+  shmid = shmget(IPC_PRIVATE, 42, IPC_CREAT | 0666);
+  if(shmid==-1) return; // failed; oh well
+  // attach
+  addr = shmat(shmid, NULL, SHM_RDONLY);
+  if(addr==(void*)-1) goto out_destroy;
 
-  return "[]";  // as good as anything
+  while(fgets(mapbuf, sizeof mapbuf, stdin)){
+    char flags[32];
+    char *tmp; // to clean up unprintables
+    unsigned KLONG start, end;
+    unsigned long long file_offset, inode;
+    unsigned dev_major, dev_minor;
+    sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx %x:%x %Lu", &start, &end, flags, &file_offset, &dev_major, &dev_minor, &inode);
+    tmp = strchr(mapbuf,'\n');
+    if(tmp) *tmp='\0';
+    tmp = mapbuf;
+    while(*tmp){
+      if(!isprint(*tmp)) *tmp='?';
+      tmp++;
+    }
+    if(start > (unsigned long)addr) continue;
+    if(dev_major) continue;
+    if(flags[3] != 's') continue;
+    if(strstr(mapbuf,"/SYSV")){
+      shm_minor = dev_minor;
+      break;
+    }
+  }
+
+  if(shmdt(addr)) perror("shmdt");
+
+out_destroy:
+  if(shmctl(shmid, IPC_RMID, NULL)) perror("IPC_RMID");
+
+  return;
 }
 
-static const char *anon_name(int pid, unsigned KLONG addr, unsigned KLONG len){
-  const char *cp = "  [ anon ]";
-  proc_t proc;
-  static int oldpid = -1;
-  if (pid==oldpid || get_proc_stats(pid, &proc)){
-    oldpid = pid;
-    if( (proc.start_stack >= addr) && (proc.start_stack <= addr+len) )  cp = "  [ stack ]";
+
+static const char *mapping_name(proc_t *p, unsigned KLONG addr, unsigned KLONG len, const char *mapbuf, unsigned advance, unsigned dev_major, unsigned dev_minor, unsigned long long inode){
+  const char *cp;
+
+  if(!dev_major && dev_minor==shm_minor && strstr(mapbuf,"/SYSV")){
+    static char shmbuf[64];
+    snprintf(shmbuf, sizeof shmbuf, "  [ shmid=0x%Lx ]", inode);
+    return shmbuf;
+  }
+
+  cp = strrchr(mapbuf,'/');
+  if(cp){
+    if(cp[1]) cp += advance;
+    return cp;
   }
+
+  cp = "  [ anon ]";
+  if( (p->start_stack >= addr) && (p->start_stack <= addr+len) )  cp = "  [ stack ]";
   return cp;
 }
 
-static int one_proc(unsigned pid){
+
+// Overkill, but who knows what is proper? The "w" prog
+// uses the tty width to determine this.
+#define maxcmd 0xfffff
+
+static int one_proc(proc_t *p){
   char buf[32];
   char mapbuf[9600];
+  char cmdbuf[512];
   unsigned long total_shared = 0ul;
   unsigned long total_private_readonly = 0ul;
   unsigned long total_private_writeable = 0ul;
 
-  sprintf(buf,"/proc/%u/maps",pid);
+  sprintf(buf,"/proc/%u/maps",p->tgid);
   if(!freopen(buf, "r", stdin)) return 1;
-  printf("%u:   %s\n", pid, get_args(pid));
 
-  if(x_option && !q_option)
-    printf("Address   Kbytes     RSS    Anon  Locked Mode   Mapping\n");
-  if(d_option && !q_option)
-    printf("Address   Kbytes Mode  Offset           Device     Mapping\n");
+  escape_command(cmdbuf, p, sizeof cmdbuf, maxcmd, ESC_ARGS|ESC_BRACKETS);
+  printf("%u:   %s\n", p->tgid, cmdbuf);
+
+  if(!q_option && (x_option|d_option)){
+    if(x_option){
+      if(sizeof(KLONG)==4) printf("Address   Kbytes     RSS    Anon  Locked Mode   Mapping\n");
+      else         printf("Address           Kbytes     RSS    Anon  Locked Mode   Mapping\n");
+    }
+    if(d_option){
+      if(sizeof(KLONG)==4) printf("Address   Kbytes Mode  Offset           Device    Mapping\n");
+      else         printf("Address           Kbytes Mode  Offset           Device    Mapping\n");
+    }
+  }
 
   while(fgets(mapbuf,sizeof mapbuf,stdin)){
     char flags[32];
     char *tmp; // to clean up unprintables
     unsigned KLONG start, end, diff;
-    unsigned long long file_offset;
+    unsigned long long file_offset, inode;
     unsigned dev_major, dev_minor;
-    sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx %x:%x", &start, &end, flags, &file_offset, &dev_major, &dev_minor);
+    sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx %x:%x %Lu", &start, &end, flags, &file_offset, &dev_major, &dev_minor, &inode);
     tmp = strchr(mapbuf,'\n');
     if(tmp) *tmp='\0';
     tmp = mapbuf;
@@ -126,19 +161,18 @@ static int one_proc(unsigned pid){
     diff = end-start;
     if(flags[3]=='s') total_shared  += diff;
     if(flags[3]=='p'){
+      flags[3] = '-';
       if(flags[1]=='w') total_private_writeable += diff;
       else              total_private_readonly  += diff;
     }
 
     // format used by Solaris 9 and procps-3.2.0+
-    if(flags[3] == 'p') flags[3] = '-';
-    flags[4] = '-';  // an 'R' if swap not reserved (MAP_NORESERVE, SysV ISM shared mem, etc.)
+    // an 'R' if swap not reserved (MAP_NORESERVE, SysV ISM shared mem, etc.)
+    flags[4] = '-';
     flags[5] = '\0';
 
     if(x_option){
-      const char *cp = strrchr(mapbuf,'/');
-      if(cp && cp[1]) cp++;
-      if(!cp) cp = anon_name(pid, start, diff);
+      const char *cp = mapping_name(p, start, diff, mapbuf, 1, dev_major, dev_minor, inode);
       printf(
         (sizeof(KLONG)==8)
           ? "%016"KLF"x %7lu       -       -       - %s  %s\n"
@@ -150,13 +184,11 @@ static int one_proc(unsigned pid){
       );
     }
     if(d_option){
-      const char *cp = strrchr(mapbuf,'/');
-      if(cp && cp[1]) cp++;
-      if(!cp) cp = anon_name(pid, start, diff);
+      const char *cp = mapping_name(p, start, diff, mapbuf, 1, dev_major, dev_minor, inode);
       printf(
         (sizeof(KLONG)==8)
-          ? "%016"KLF"x %7lu %s %016Lx %03x:%05x  %s\n"
-          :      "%08lx %7lu %s %016Lx %03x:%05x  %s\n",
+          ? "%016"KLF"x %7lu %s %016Lx %03x:%05x %s\n"
+          :      "%08lx %7lu %s %016Lx %03x:%05x %s\n",
         start,
         (unsigned long)(diff>>10),
         flags,
@@ -166,8 +198,7 @@ static int one_proc(unsigned pid){
       );
     }
     if(!x_option && !d_option){
-      const char *cp = strchr(mapbuf,'/');
-      if(!cp) cp = anon_name(pid, start, diff);
+      const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode);
       printf(
         (sizeof(KLONG)==8)
           ? "%016"KLF"x %6luK %s  %s\n"
@@ -181,32 +212,34 @@ static int one_proc(unsigned pid){
     
   }
 
-  if(x_option && !q_option){
-    if(sizeof(KLONG)==8){
-      printf("----------------  ------  ------  ------  ------\n");
-      printf(
-        "total kB %15ld       -       -       -\n",
-        (total_shared + total_private_writeable + total_private_readonly) >> 10
-      );
-    }else{
-      printf("-------- ------- ------- ------- -------\n");
-      printf(
-        "total kB %7ld       -       -       -\n",
-        (total_shared + total_private_writeable + total_private_readonly) >> 10
-      );
+  if(!q_option){
+    if(x_option){
+      if(sizeof(KLONG)==8){
+        printf("----------------  ------  ------  ------  ------\n");
+        printf(
+          "total kB %15ld       -       -       -\n",
+          (total_shared + total_private_writeable + total_private_readonly) >> 10
+        );
+      }else{
+        printf("-------- ------- ------- ------- -------\n");
+        printf(
+          "total kB %7ld       -       -       -\n",
+          (total_shared + total_private_writeable + total_private_readonly) >> 10
+        );
+      }
+    }
+    if(d_option){
+        printf(
+          "mapped %ldK    writeable/private: %ldK    shared: %ldK\n",
+          (total_shared + total_private_writeable + total_private_readonly) >> 10,
+          total_private_writeable >> 10,
+          total_shared >> 10
+        );
+    }
+    if(!x_option && !d_option){
+      if(sizeof(KLONG)==8) printf(" total %16ldK\n", (total_shared + total_private_writeable + total_private_readonly) >> 10);
+      else                 printf(" total %8ldK\n",  (total_shared + total_private_writeable + total_private_readonly) >> 10);
     }
-  }
-  if(d_option && !q_option){
-      printf(
-        "mapped %ldK    writeable/private: %ldK    shared: %ldK\n",
-        (total_shared + total_private_writeable + total_private_readonly) >> 10,
-        total_private_writeable >> 10,
-        total_shared >> 10
-      );
-  }
-  if(!x_option && !d_option && !q_option){
-    if(sizeof(KLONG)==8) printf(" total %16ldK\n", (total_shared + total_private_writeable + total_private_readonly) >> 10);
-    else                 printf(" total %8ldK\n",  (total_shared + total_private_writeable + total_private_readonly) >> 10);
   }
 
   return 0;
@@ -216,7 +249,8 @@ static int one_proc(unsigned pid){
 int main(int argc, char *argv[]){
   unsigned *pidlist;
   unsigned count = 0;
-  unsigned u;
+  PROCTAB* PT;
+  proc_t p;
   int ret = 0;
 
   if(argc<2) usage();
@@ -276,8 +310,17 @@ int main(int argc, char *argv[]){
   if(count<1) usage();   // no processes
   if(d_option && x_option) usage();
 
-  u=0;
-  while(u<count) ret |= one_proc(pidlist[u++]);
+  discover_shm_minor();
+
+  pidlist[count] = 0;  // old libproc interface is zero-terminated
+  PT = openproc(PROC_FILLSTAT|PROC_FILLARG|PROC_PID, pidlist);
+  while(readproc(PT, &p)){
+    ret |= one_proc(&p);
+    if(p.cmdline) free((void*)*p.cmdline);
+    count--;
+  }
+  closeproc(PT);
 
+  if(count) ret |= 42;  // didn't find all processes asked for
   return ret;
 }
index 11353197494613df60a5f454c58f8bbeeb96df4e..7c9d3478a19e732cedd63a531b83ec609b362108 100644 (file)
@@ -55,9 +55,11 @@ proc/.depend: $(LIBSRC) $(LIBHDR)
 
 ifneq ($(MAKECMDGOALS),clean)
 ifneq ($(MAKECMDGOALS),tar)
+ifneq ($(MAKECMDGOALS),extratar)
 -include proc/.depend
 endif
 endif
+endif
 
 
 $(lib)/$(SONAME) : proc/$(SONAME)