]> granicus.if.org Git - procps-ng/commitdiff
pmap
authoralbert <>
Sun, 27 Oct 2002 10:35:13 +0000 (10:35 +0000)
committeralbert <>
Sun, 27 Oct 2002 10:35:13 +0000 (10:35 +0000)
Makefile
NEWS
pmap.1 [new file with mode: 0644]
pmap.c
vmstat.c

index ed079d23ac50b392df4f5b4f113bcc78088e50d2..065c4239277410097fc2939fee38f8aac2f8d673 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -47,12 +47,12 @@ usr/include              := $(DESTDIR)/usr/include/
 
 BINFILES := $(usr/bin)uptime $(usr/bin)tload $(usr/bin)free $(usr/bin)w \
             $(usr/bin)top $(usr/bin)vmstat $(usr/bin)watch $(usr/bin)skill \
-            $(usr/bin)snice $(bin)kill $(sbin)sysctl \
+            $(usr/bin)snice $(bin)kill $(sbin)sysctl $(usr/bin)pmap \
             $(usr/proc/bin)pgrep $(usr/proc/bin)pkill
 
 MANFILES := $(man1)uptime.1 $(man1)tload.1 $(man1)free.1 $(man1)w.1 \
             $(man1)top.1 $(man1)watch.1 $(man1)skill.1 $(man1)kill.1 \
-            $(man1)snice.1 $(man1)pgrep.1 $(man1)pkill.1 \
+            $(man1)snice.1 $(man1)pgrep.1 $(man1)pkill.1 $(man1)pmap.1 \
             $(man5)sysctl.conf.5 $(man8)vmstat.8 $(man8)sysctl.8
 
 TARFILES := AUTHORS BUGS NEWS README TODO COPYING COPYING.LIB ChangeLog \
@@ -146,7 +146,7 @@ w.o:    w.c
 
 ############ prog.o --> prog
 
-w uptime tload free vmstat utmp pgrep skill: % : %.o $(LIBPROC)
+pmap w uptime tload free vmstat utmp pgrep skill: % : %.o $(LIBPROC)
        $(CC) $(LDFLAGS) -o $@ $^
 
 top:   % : %.o $(LIBPROC)
diff --git a/NEWS b/NEWS
index a215e892ac979c813995c3eae0629720385e21ed..dba3d7ad488fc0e64a1d2ed9bcc05b918c463201 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+procps-3.0.5 --> procps-3.0.6
+
+can build w/o shared library (set SHARED=0)
+when IO-wait hidden, count as idle, not as sys
+pmap command added (like Sun has)
+
 procps-3.0.4 --> procps-3.0.5
 
 top tolerates super-wide displays
diff --git a/pmap.1 b/pmap.1
new file mode 100644 (file)
index 0000000..930fd6b
--- /dev/null
+++ b/pmap.1
@@ -0,0 +1,36 @@
+'\" t
+.\" (The preceding line is a note to broken versions of man to tell
+.\" them to pre-process this man page with tbl)
+.\" Man page for pmap.
+.\" Licensed under version 2 of the GNU General Public License.
+.\" Written by Albert Cahalan.
+.\"
+.TH PMAP 1 "October 26, 2002" "Linux" "Linux User's Manual"
+.SH NAME
+pmap \- report memory map of a process
+
+.SH SYNOPSIS
+.nf
+pmap [-x] [-V] pids...
+.fi
+
+.SH DESCRIPTION
+The pmap command reports the memory map of a process or processes.
+
+.SH "GENERAL OPTIONS"
+.TS
+l l l.
+-x     extended        Show the extended format.
+-V     show version    Displays version of program.
+.TE
+
+.SH "SEE ALSO"
+ps(1) pgrep(1)
+
+.SH STANDARDS
+No standards apply, but pmap looks an awful lot like a SunOS command.
+
+.SH AUTHOR
+Albert Cahalan <albert@users.sf.net> wrote pmap in 2002, and is the current
+maintainer of the procps collection. Please send bug reports
+to <procps-feedback@lists.sf.net>.
diff --git a/pmap.c b/pmap.c
index ad01e1ecd7c2554aaca36aa8c98b8139611eb1e8..db8c3678d109768046d4510891440a72b62dd8b5 100644 (file)
--- a/pmap.c
+++ b/pmap.c
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include "proc/version.h"  // FIXME: we need to link the lib for this :-(
 
-void usage(void){
+static void usage(void){
   fprintf(stderr,
     "Usage: pmap [-r] [-x] pid...\n"
-    "-r  ignored (compatibility option)\n"
     "-x  show details\n"
   );
   exit(1);
 }
 
-int one_proc(unsigned pid){
-  char cmdbuf[64];
+
+static int V_option;
+static int r_option;  // ignored -- for SunOS compatibility
+static int x_option;
+
+
+static const char *get_args(unsigned pid){
+  static char cmdbuf[64];
   char buf[32];
   int fd;
-  sprintf(buf,"/proc/%u/cmdline",pid);
-  if( ((fd=open(buf)) == -1) return 1;
-  count = read(fd, cmdbuf, sizeof(cmdbuf)-1);
-  if(count<1) return 1;
-  cmdbuf[count] = '\0';
-  while(count--) if(!isprint(cmdbuf[count])) cmdbuf[count]=' ';
-  close(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);
+
+  return "[]";  // as good as anything
+}
+
+
+static int one_proc(unsigned pid){
+  char buf[32];
+  char mapbuf[9600];
+  unsigned long total_shared = 0ul;
+  unsigned long total_private = 0ul;
+
   sprintf(buf,"/proc/%u/maps",pid);
-  if( ((fd=open(buf)) == -1) return 1;
-  printf("%u:   %s\n", pid, cmdbuf);
+  if(!freopen(buf, "r", stdin)) return 1;
+  printf("%u:   %s\n", pid, get_args(pid));
   if(x_option)
-    printf("Address   kB     Resident Shared Private Permissions       Name\n");
-@@@ FIXME FIXME FIXME @@@  
+    printf("Address       kB Resident Shared Private Permissions       Name\n");
+  while(fgets(mapbuf,sizeof mapbuf,stdin)){
+    char flags[32];
+    const char *perms;
+    char *tmp; // to clean up unprintables
+    unsigned long start, end, diff;
+    unsigned long long pgoff;
+    sscanf(mapbuf,"%lx-%lx %s %Lx", &start, &end, flags, &pgoff);
+    tmp = strchr(mapbuf,'\n');
+    if(tmp) *tmp='\0';
+    tmp = mapbuf;
+    while(*tmp){
+      if(!isprint(*tmp)) *tmp='?';
+      tmp++;
+    }
+    
+    if(flags[0]=='r'){
+      if(flags[1]=='w'){
+        if(flags[2]=='x') perms = "read/write/exec";
+        else              perms = "read/write     ";
+      }else{
+        if(flags[2]=='x') perms = "read/exec      ";
+        else              perms = "read           ";
+      }
+    }else{
+      if(flags[1]=='w'){
+        if(flags[2]=='x') perms = "write/exec     ";
+        else              perms = "write          ";
+      }else{
+        if(flags[2]=='x') perms = "exec           ";
+        else              perms = "none           ";
+      }
+    }
+    diff = end-start;
+    if(flags[3]=='s') total_shared  += diff;
+    if(flags[3]=='p') total_private += diff;
+    if(x_option){
+      const char *cp = strrchr(mapbuf,'/');
+      if(cp && cp[1]) cp++;
+      if(!cp) cp = " [ anon ]";    // yeah, 1 space
+      printf(
+        (sizeof(long)==8)
+          ? "%016lx %7ld       - %7ld %7ld %s   %s\n"
+          : "%08lx %7ld       - %7ld %7ld %s   %s\n",
+        start,
+        diff>>10,
+        (flags[3]=='s') ? diff>>10 : 0,
+        (flags[3]=='p') ? diff>>10 : 0,
+        perms,
+        cp
+      );
+    }else{
+      const char *cp = strchr(mapbuf,'/');
+      if(!cp) cp = "  [ anon ]";   // yeah, 2 spaces
+      printf(
+        (sizeof(long)==8)
+          ? "%016lx %6ldK %s   %s\n"
+          : "%08lx %6ldK %s   %s\n",
+        start,
+        diff>>10,
+        perms,
+        cp
+      );
+    }
+    
+  }
+  if(x_option){
+    if(sizeof(long)==8){
+      printf("----------------  ------  ------  ------  ------\n");
+      printf(
+        "total kB %15ld       - %7ld %7ld\n",
+        (total_shared + total_private) >> 10,
+        total_shared >> 10,
+        total_private >> 10
+      );
+    }else{
+      printf("--------  ------  ------  ------  ------\n");
+      printf(
+        "total kB %7ld       - %7ld %7ld\n",
+        (total_shared + total_private) >> 10,
+        total_shared >> 10,
+        total_private >> 10
+      );
+    }
+  }else{
+    if(sizeof(long)==8) printf(" total %16ldK\n", (total_shared + total_private) >> 10);
+    else                printf(" total %8ldK\n", (total_shared + total_private) >> 10);
+  }
+  return 0;
 }
 
+
 int main(int argc, char *argv[]){
+  unsigned *pidlist;
+  unsigned count = 0;
+  unsigned u;
+  int ret = 0;
+
+  if(argc<2) usage();
+  pidlist = malloc(sizeof(unsigned)*argc);  // a bit more than needed perhaps
+
+  while(*++argv){
+    if(!strcmp("--version",*argv)){
+      V_option++;
+      continue;
+    }
+    if(**argv=='-'){
+      char *walk = *argv;
+      if(!walk[1]) usage();
+      while(*++walk){
+        switch(*walk){
+        case 'V':
+          V_option++;
+          break;
+        case 'x':
+          x_option++;
+          break;
+        case 'r':
+          r_option++;
+          break;
+        default:
+          usage();
+        }
+      }
+    }else{
+      char *walk = *argv;
+      char *endp;
+      unsigned long pid;
+      if(!strncmp("/proc/",walk,6)) walk += 6;
+      if(*walk<'0' || *walk>'9') usage();
+      pid = strtoul(walk, &endp, 0);
+      if(pid<1ul || pid>0x7ffffffful || *endp) usage();
+      pidlist[count++] = pid;
+    }
+  }
+
+  if(x_option>1 || V_option>1 || r_option>1) usage();  // dupes
+  if(V_option){
+    if(count|x_option|r_option) usage();
+    fprintf(stdout, "pmap (%s)\n", procps_version);
+    return 0;
+  }
+  if(count<1) usage();   // no processes
+
+  u=0;
+  while(u<count) ret |= one_proc(pidlist[u++]);
+
+  return ret;
 }
index ec1a1be2d7393a4297d0a29929e5736c810b78a6..d7f94f2f3775e20bc602128b241d5dd4b55a8edb 100644 (file)
--- a/vmstat.c
+++ b/vmstat.c
@@ -191,7 +191,8 @@ int main(int argc, char *argv[]) {
 #endif
   unsigned int moreheaders=TRUE;
   unsigned int tog=0; /* toggle switch for cleaner code */
-  unsigned int i,hz;
+  unsigned int i;
+  unsigned int hz = Hertz;
   unsigned int running,blocked,swapped;
   jiff cpu_use[2], cpu_nic[2], cpu_sys[2], cpu_idl[2], cpu_iow[2];
   jiff duse,dsys,didl,Div,divo2;
@@ -257,7 +258,6 @@ int main(int argc, char *argv[]) {
   dsys= *cpu_sys;
   didl= *cpu_idl + *cpu_iow;
   Div= duse+dsys+didl;
-  hz=Hertz; /* get ticks/s from libproc */
   divo2= Div/2UL;
   printf(format,
         running,blocked,swapped,