File procps-3.2.8-pmap-smaps-rml-2.patch of Package procps

--- pmap.1
+++ pmap.1	2009-05-11 10:14:59.377902682 +0000
@@ -1,39 +1,60 @@
-'\" 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.
+.\" pmap.1 - manpage for the pmap(1) utility, part of procps
 .\"
-.TH PMAP 1 "October 26, 2002" "Linux" "Linux User's Manual"
+.\" Copyright (C) 2005 Robert Love
+.\" Licensed under the terms of the GNU General Public License, v2
+.TH PMAP 1 "12 Oct 2005" "Linux" "Linux User's Manual"
 .SH NAME
-pmap \- report memory map of a process
+pmap \- display information about process memory mappings
 
 .SH SYNOPSIS
-.nf
-pmap [ -x | -d ] [ -q ] pids...
-pmap -V
-.fi
+.BI "pmap [ \-d | \-q | \-h | \-V | \-A\ low,high ] " pid 
 
 .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.
--d	device	Show the device format.
--q	quiet	Do not display some header/footer lines.
--V	show version	Displays version of program.
-.TE
+.BR pmap (1)
+displays information about a process's memory mappings, such as its stack,
+data segment, mapped files, and so on.
+.P
+The
+.BR pmap (1)
+utility will show, for each mapping of a given process, the starting byte
+address in the process's address space, the size, the RSS (size of the mapping
+in physical memory), the amount of dirty pages, the permission, the device node,
+the offset, and the file backing the mapping, if any.
+.P
+As the last line of output, the
+.BR pmap (1)
+utility will tally up the total size of all mappings as well as show the
+total size of writable/private mappings and of shared mappings.
+
+.SH OPTIONS
+.TP
+.B\-d, \-\^\-device
+Display major and minor device numbers.
+.TP
+.B\-A, \-\-limit=low,high
+Limit results to the given range.
+.TP
+.B\-q, \-\^\-quiet
+Hide header and memory statistics.
+.TP
+.B\-h, \-\^\-help
+Show pmap usage.
+.TP
+.B\-V, \-\^\-version
+Display version information.
+
+.SH FILES
+.IR /proc/pid/maps " and
+.IR /proc/pid/smaps " \-\- memory mapping information"
 
 .SH "SEE ALSO"
-ps(1) pgrep(1)
+.BR ps (1),
+.BR top (1),
+.BR free (1),
+.BR vmstat (1)
 
-.SH STANDARDS
-No standards apply, but pmap looks an awful lot like a SunOS command.
+.SH AUTHORS
+Written by Chris Rivera.
 
-.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>.
+The procps package is maintained by Albert Calahan.  Please send
+bug reports to <albert@users.sf.net>.
--- pmap.c
+++ pmap.c	2010-12-03 16:55:52.268426585 +0000
@@ -1,372 +1,428 @@
 /*
- * Copyright 2002 by Albert Cahalan; all rights reserved.
- * This file may be used subject to the terms and conditions of the
- * GNU Library General Public License Version 2, or any later version
- * at your option, as published by the Free Software Foundation.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
+ * pmap - print the address space map of a process
+ *
+ * Chris Rivera		<chrismrivera@gmail.com>
+ * Robert Love		<rml@novell.com>
+ * Werner Fink		<werner@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, v2, as
+ * published by the Free Software Foundation
+ *
+ * Copyright (C) 2003, 2005 Chris Rivera
+ * Copyright (C) 2009 Werner Fink
  */
 
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
 #include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <sys/utsname.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){
-  fprintf(stderr,
-    "Usage: pmap [-x | -d] [-q] [-A low,high] pid...\n"
-    "-x  show details\n"
-    "-d  show offset and device number\n"
-    "-q  quiet; less header/footer info\n"
-    "-V  show the version number\n"
-    "-A  limit results to the given range\n"
-  );
-  exit(1);
-}
-
-
-static unsigned KLONG range_low;
-static unsigned KLONG range_high = ~0ull;
 
-static int V_option;
-static int r_option;  // ignored -- for SunOS compatibility
-static int x_option;
-static int d_option;
-static int q_option;
-
-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;
-
-  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;
-    }
-  }
+#define BUFFERSIZE	4096
+#define OBJECTSIZE	1024
 
-  if(shmdt(addr)) perror("shmdt");
+struct smap {
+	unsigned long size;
+	unsigned long rss;
+	unsigned long pss;
+	unsigned long shared_clean;
+	unsigned long shared_dirty;
+	unsigned long private_clean;
+	unsigned long private_dirty;
+	unsigned long referenced;
+	unsigned long swap;
+	unsigned long kernelpagesize;
+	unsigned long mmupagesize;
+};
+
+static unsigned long long range_low;
+static unsigned long long range_high = ~0ULL;
+static unsigned long mapped;
+static unsigned long shared;
+static unsigned long private;
+static unsigned long rss;
+static unsigned long pss;
+static unsigned long dirty;
+static unsigned long referenced;
+static unsigned long swap;
+static FILE *smaps_fp;
+static int maj, min, patch, dopss, noref, doswap, dopage;
+static long lbits;
+#define BLK	((lbits==64)?"        ":"")
+#define WDT	((lbits==64)?16:8)
+
+static void usage(const char *cmd)
+{
+	fprintf(stderr, "usage: %s [options] pid\n", cmd);
+	fprintf(stderr, "  -d, --device         "
+			"display offset and device numbers\n");
+	fprintf(stderr, "  -q, --quiet          "
+			"hide header and memory statistics\n");
+	fprintf(stderr, "  -A, --limit=low,high "
+			"limit results to the given range\n");
+	fprintf(stderr, "  -V, --version        "
+			"display version information\n");
+	fprintf(stderr, "  -h, --help           "
+			"display this help\n");
+}
 
-out_destroy:
-  if(shmctl(shmid, IPC_RMID, NULL)) perror("IPC_RMID");
+static int get_smap_data(struct smap *smap)
+{
+	unsigned long long data;
+	int assigned;
+	char buff[BUFFERSIZE];
+
+	/* get main line */
+	if (!fgets(buff, BUFFERSIZE - 1, smaps_fp))
+		return 1;
+
+	assigned = sscanf(buff, "%llx-", &data);
+	if (assigned != 1)
+		return 1;
+
+	/* get size */
+	if (!fgets(buff, BUFFERSIZE, smaps_fp))
+		return 1;
+
+	assigned = sscanf(buff, "Size: %lld", &data);
+	if (assigned != 1)
+		return 1;
+	smap->size = data;
+
+	/* get rss */
+	if (!fgets(buff, BUFFERSIZE, smaps_fp))
+		return 1;
+
+	assigned = sscanf(buff, "Rss: %lld", &data);
+	if (assigned != 1)
+		return 1;
+	smap->rss = data;
+	rss += data;
+
+	if (dopss) {
+		/* get pss */
+		if (!fgets(buff, BUFFERSIZE, smaps_fp))
+			return 1;
+
+		assigned = sscanf(buff, "Pss: %lld", &data);
+		if (assigned != 1)
+			return 1;
+		smap->pss = data;
+		pss += data;
+	}
+
+	/* get shared clean */
+	if (!fgets(buff, BUFFERSIZE, smaps_fp))
+		return 1;
+
+	assigned = sscanf(buff, "Shared_Clean: %lld", &data);
+	if (assigned != 1)
+		return 1;
+	smap->shared_clean = data;
+
+	/* get shared dirty */
+	if (!fgets(buff, BUFFERSIZE, smaps_fp))
+		return 1;
+
+	assigned = sscanf(buff, "Shared_Dirty: %lld", &data);
+	if (assigned != 1)
+		return 1;
+	smap->shared_dirty = data;
+	dirty += data;
+	
+	/* get private clean */
+	if (!fgets(buff, BUFFERSIZE, smaps_fp))
+		return 1;
+
+	assigned = sscanf(buff, "Private_Clean: %lld", &data);
+	if (assigned != 1)
+		return 1;
+	smap->private_clean = data;
+
+	/* get private dirty */
+	if (!fgets(buff, BUFFERSIZE, smaps_fp))
+		return 1;
+
+	assigned = sscanf(buff, "Private_Dirty: %lld", &data);
+	if (assigned != 1)
+		return 1;
+	smap->private_dirty = data;
+	dirty += data;
+
+	if (noref)
+		goto out;
+
+	/* get referenced */
+	if (!fgets(buff, BUFFERSIZE, smaps_fp))
+		return 1;
+
+	assigned = sscanf(buff, "Referenced: %lld", &data);
+	if (assigned != 1)
+		return 1;
+	smap->referenced = data;
+	referenced += data;
+
+	if (!doswap)
+		goto out;
+
+	/* get and ignore anonymous */
+	if (!fgets(buff, BUFFERSIZE, smaps_fp))
+		return 1;
+
+	assigned = sscanf(buff, "Anonymous: %lld", &data);
+
+	/* get swap */
+	if (assigned == 1)
+		if(!fgets(buff, BUFFERSIZE, smaps_fp))
+			return 1;
+
+	assigned = sscanf(buff, "Swap: %lld", &data);
+	if (assigned != 1)
+		return 1;
+	smap->swap = data;
+	swap += data;
+
+	if (!dopage)
+		goto out;
+
+	/* get kernel page size */
+	if (!fgets(buff, BUFFERSIZE, smaps_fp))
+		return 1;
+ 
+	assigned = sscanf(buff, "KernelPageSize: %lld", &data);
+	if (assigned != 1)
+		return 1;
+	smap->kernelpagesize = data;
+ 
+	/* get MMU page size */
+	if (!fgets(buff, BUFFERSIZE, smaps_fp))
+		return 1;
+ 
+	assigned = sscanf(buff, "MMUPageSize: %lld", &data);
+	if (assigned != 1)
+		return 1;
+	smap->mmupagesize = data;
 
-  return;
+out:
+	return 0;
 }
 
+static void parse_line(pid_t pid, const char *line, int show_devices)
+{
+	unsigned long long low, high, size, offset;
+	unsigned long major, minor;
+	struct smap smap = { .rss = 0, .pss = 0 };
+	int assigned;
+	char read_perm, write_perm, exec_perm, access_type;
+	char obj_buff[OBJECTSIZE] = "[anon]";
+
+	assigned = sscanf(line, "%llx-%llx %c%c%c%c %llx %lx:%lx %*u %" 
+		   STRINGIFY(OBJECTSIZE) "s", &low, &high, &read_perm,
+		   &write_perm, &exec_perm, &access_type, &offset, &major,
+		   &minor, obj_buff);
+
+	if (assigned < 9) {
+		fprintf(stderr, "failed to parse /proc/%d/maps\n", pid);
+		exit(EXIT_FAILURE);
+	}
+
+	size = high - low;
+	size /= 1024;
+	mapped += size;
+
+	if (smaps_fp && get_smap_data(&smap)) {
+		fprintf(stderr, "failed to parse /proc/%d/smaps\n", pid);
+		exit(1);
+	}
+
+	if (access_type == 's')
+		shared += size;
+	else if (access_type == 'p' && write_perm == 'w')
+		private += size;
+
+	if(low > range_high)
+		return;
+	if(high < range_low)
+		return;
+
+	printf("%0*llx %6lluK ", WDT, low, size);
+
+	if (smaps_fp) {
+		printf("%6luK ", smap.rss);
+		if (dopss)
+			printf("%6luK ", smap.pss);
+		printf("%6luK ", smap.private_dirty + smap.shared_dirty);
+		if (doswap)
+			printf("%6luK ", smap.swap);
+	}
 
-static const char *mapping_name(proc_t *p, unsigned KLONG addr, unsigned KLONG len, const char *mapbuf, unsigned showpath, 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(showpath) return strchr(mapbuf,'/');
-    return cp[1] ? cp+1 : cp;
-  }
-
-  cp = strchr(mapbuf,'/');
-  if(cp){
-    if(showpath) return cp;
-    return strrchr(cp,'/') + 1;  // it WILL succeed
-  }
-
-  cp = "  [ anon ]";
-  if( (p->start_stack >= addr) && (p->start_stack <= addr+len) )  cp = "  [ stack ]";
-  return cp;
-}
+	printf("%c%c%c%c ", read_perm, write_perm, exec_perm, access_type);
 
-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;
-
-  // Overkill, but who knows what is proper? The "w" prog
-  // uses the tty width to determine this.
-  int maxcmd = 0xfffff;
-
-  sprintf(buf,"/proc/%u/maps",p->tgid);
-  if(!freopen(buf, "r", stdin)) return 1;
-
-  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, 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);
-
-    if(start > range_high)
-      break;
-    if(end < range_low)
-      continue;
-
-    tmp = strchr(mapbuf,'\n');
-    if(tmp) *tmp='\0';
-    tmp = mapbuf;
-    while(*tmp){
-      if(!isprint(*tmp)) *tmp='?';
-      tmp++;
-    }
-    
-    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+
-    // an 'R' if swap not reserved (MAP_NORESERVE, SysV ISM shared mem, etc.)
-    flags[4] = '-';
-    flags[5] = '\0';
-
-    if(x_option){
-      const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode);
-      printf(
-        (sizeof(KLONG)==8)
-          ? "%016"KLF"x %7lu       -       -       - %s  %s\n"
-          :      "%08lx %7lu       -       -       - %s  %s\n",
-        start,
-        (unsigned long)(diff>>10),
-        flags,
-        cp
-      );
-    }
-    if(d_option){
-      const char *cp = mapping_name(p, start, diff, mapbuf, 0, 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",
-        start,
-        (unsigned long)(diff>>10),
-        flags,
-        file_offset,
-        dev_major, dev_minor,
-        cp
-      );
-    }
-    if(!x_option && !d_option){
-      const char *cp = mapping_name(p, start, diff, mapbuf, 1, dev_major, dev_minor, inode);
-      printf(
-        (sizeof(KLONG)==8)
-          ? "%016"KLF"x %6luK %s  %s\n"
-          :      "%08lx %6luK %s  %s\n",
-        start,
-        (unsigned long)(diff>>10),
-        flags,
-        cp
-      );
-    }
-    
-  }
-
-
-
-
-  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 (show_devices)
+		printf("%0*llx %02lx:%02lx  ", WDT, offset, major, minor);
 
-  return 0;
+	printf("%s\n", obj_buff);
 }
 
+int main(int argc, char *argv[])
+{
+	proc_t proc;
+	FILE *fp;
+	char path[PATH_MAX];
+	char buff[BUFFERSIZE];
+	int o, show_devices = 0, quiet = 0;
+	struct utsname uts;
+	pid_t pid;
+
+	if (uname(&uts) < 0) {
+		fprintf(stderr, "error getting information about current kernel: %m\n");
+		exit(EXIT_FAILURE);
+	}
+	sscanf(uts.release, "%d.%d.%d", &maj, &min, &patch);
+
+	if ((maj > 2) || ((maj == 2) && ((min > 6) || ((min == 6) && (patch >= 30)))))
+		dopage++;
+	if ((maj > 2) || ((maj == 2) && ((min > 6) || ((min == 6) && (patch >= 27)))))
+		doswap++;
+	if ((maj > 2) || ((maj == 2) && ((min > 6) || ((min == 6) && (patch >= 25)))))
+		dopss++;
+	if ((maj < 2) || ((maj == 2) && ((min < 6) || ((min == 6) && (patch < 22)))))
+		noref++;
+
+	if ((lbits = sysconf(_SC_LONG_BIT)) < 0) {
+		fprintf(stderr, "error getting information about current kernel: %m\n");
+		exit(EXIT_FAILURE);
+	}
+
+	struct option longopts[] = {
+		{ "help", 	0, NULL, 'h' },
+		{ "version", 	0, NULL, 'V' },
+		{ "quiet", 	0, NULL, 'q' },
+		{ "device", 	0, NULL, 'd' },
+		{ "limit", 	0, NULL, 'A' },
+		{  NULL,	0, NULL, 0 }
+	};
+
+	while ((o = getopt_long(argc, argv, "hqdA:V", longopts, NULL)) != -1) {
+		switch (o) {
+		case 'V':
+			display_version();
+			return 0;
+		case 'q':
+			quiet = 1;
+			break;
+		case 'd':
+			show_devices = 1;
+			break;
+		case 'A':
+			if (!optarg || *optarg == 0) {
+				usage(argv[0]);
+				return 1;
+			} else {
+				char *low = optarg;
+				char *high = strchr(low, ',');
+				if (high) {
+					*high = '\0';
+					high++;
+				}
+				if (low)
+					range_low = strtoull(low, &low, 16);
+				if (high)
+					range_high = strtoull(high, &high, 16);
+				if (*low || *high) {
+					usage(argv[0]);
+					return 1;
+				}
+			}
+			break;
+		case 'h':
+			usage(argv[0]);
+			return 0;
+		default:
+			usage(argv[0]);
+			return 1;
+		}
+	}
+
+	if (argc - optind > 0) {
+		errno = 0;
+		pid = strtoul(argv[optind], NULL, 10);
+		if (errno) {
+			perror("strtoul");
+			exit(EXIT_FAILURE);
+		}
+	} else {
+		usage(argv[0]);
+		exit(EXIT_FAILURE);
+	}
+
+	if (!get_proc_stats(pid, &proc)) {
+		fprintf(stderr, "error getting process information for pid "
+				"%d from /proc/%d\n", pid, pid);
+		exit(EXIT_FAILURE);
+	}
+
+	printf("%d: %s\n", pid, proc.cmd);
+
+	snprintf(path, PATH_MAX, "/proc/%d/maps", pid);
+	fp = fopen(path, "r");
+	if (!fp) {
+		perror("fopen");
+		exit(EXIT_FAILURE);
+	}
+
+	snprintf(path, PATH_MAX, "/proc/%d/smaps", pid);
+	smaps_fp = fopen(path, "r");
+
+	if (!quiet) {
+		printf("START%s       SIZE ", BLK);
+
+		if (smaps_fp) {
+			printf("    RSS ");
+			if (dopss)
+				printf("    PSS ");
+			printf("  DIRTY ");
+			if (doswap)
+				printf("   SWAP ");
+		}
+
+		if (show_devices)
+			printf("PERM OFFSET   DEVICE MAPPING\n");
+		else
+			printf("PERM MAPPING\n");
+	}
+
+	while (fgets(buff, BUFFERSIZE - 1, fp))
+		parse_line(pid, buff, show_devices);
+
+	if (!quiet) {
+		if (smaps_fp) {
+			printf("Total:%s  ", BLK);
+			printf(" %6luK", mapped);
+			printf(" %6luK", rss);
+			if (dopss)
+				printf(" %6luK", pss);
+			printf(" %6luK", dirty);
+			if (doswap)
+				printf(" %6luK", swap);
+			printf("\n\n");
+		} else 
+			printf("mapped: %luK    ", mapped);
+
+		if (noref)
+			printf("%luK writable-private, %luK readonly-private, and %luK shared\n",
+				private, mapped - private - shared, shared);
+		else
+			printf("%luK writable-private, %luK readonly-private, %luK shared, and %luK referenced\n",
+				private, mapped - private - shared, shared, referenced);
+	}
 
-int main(int argc, char *argv[]){
-  unsigned *pidlist;
-  unsigned count = 0;
-  PROCTAB* PT;
-  proc_t p;
-  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;
-        case 'd':
-          d_option++;
-          break;
-        case 'q':
-          q_option++;
-          break;
-        case 'A':{
-            char *arg1;
-            if(walk[1]){
-              arg1 = walk+1;
-              walk += strlen(walk)-1;
-            }else{
-              arg1 = *++argv;
-              if(!arg1)
-                usage();
-            }
-            char *arg2 = strchr(arg1,',');
-            if(arg2)
-              *arg2 = '\0';
-            arg2 = arg2 ? arg2++ : arg1;
-            
-            if(*arg1)
-              range_low = STRTOUKL(arg1,&arg1,16);
-            if(*arg2)
-              range_high = STRTOUKL(arg2,&arg2,16);
-            if(*arg1 || *arg2)
-            	usage();
-          }
-          break;
-        case 'a': // Sun prints anon/swap reservations
-        case 'F': // Sun forces hostile ptrace-like grab
-        case 'l': // Sun shows unresolved dynamic names
-        case 'L': // Sun shows lgroup info
-        case 's': // Sun shows page sizes
-        case 'S': // Sun shows swap reservations
-        default:
-          usage();
-        }
-      }
-    }else{
-      char *walk = *argv;
-      char *endp;
-      unsigned long pid;
-      if(!strncmp("/proc/",walk,6)){
-        walk += 6;
-        // user allowed to do: pmap /proc/*
-        if(*walk<'0' || *walk>'9') continue;
-      }
-      if(*walk<'0' || *walk>'9') usage();
-      pid = strtoul(walk, &endp, 0);
-      if(pid<1ul || pid>0x7ffffffful || *endp) usage();
-      pidlist[count++] = pid;
-    }
-  }
-
-  if( (x_option|V_option|r_option|d_option|q_option) >> 1 ) usage(); // dupes
-  if(V_option){
-    if(count|x_option|r_option|d_option|q_option) usage();
-    fprintf(stdout, "pmap (%s)\n", procps_version);
-    return 0;
-  }
-  if(count<1) usage();   // no processes
-  if(d_option && x_option) usage();
-
-  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;
+	return 0;
 }
openSUSE Build Service is sponsored by