#!/usr/bin/python
import re, os, sys, pwd, getopt

def pids():
    '''get a list of processes'''
    return [int(e) for e in os.listdir("/proc") if e.isdigit()]

def pidmaps(pid):
    maps = {}
    start = None
    for l in file('/proc/%s/smaps' % pid):
    	f = l.split()
	if f[-1] == 'kB':
            maps[start][f[0][:-1].lower()] = int(f[1])
        else:
            start, end = f[0].split('-')
            start = int(start, 16)
            name = ""
            if len(f) > 5:
                name = f[5]
            maps[start] = dict(end=int(end, 16), mode=f[1],
                               offset=int(f[2], 16),
                               device=f[3], inode=f[4], name=name)

    return maps

def pidtotals(pid):
    maps = pidmaps(pid)
    t = dict(size=0, rss=0, pss=0, shared_clean=0, shared_dirty=0,
             private_clean=0, private_dirty=0, referenced=0, swap=0)
    for m in maps.iterkeys():
        for k in t:
            t[k] += maps[m].get(k, 0)
    t['maps'] = len(maps)
    return t

def processtotals(pids):
    totals = {}
    for pid in pids:
        try:
            totals[pid] = pidtotals(pid)
        except:
            continue
    return totals

def maptotals():
    t = dict(size=0, rss=0, pss=0, shared_clean=0, shared_dirty=0,
             private_clean=0, private_dirty=0, referenced=0, swap=0)

def sortmaps(totals, key):
    l = []
    for pid in totals:
        l.append((totals[pid][key], pid))
    l.sort()
    return [pid for pid,key in l]

def pidname(pid):
    l = file('/proc/%d/stat' % pid).read()
    return l[l.find('(') + 1: l.find(')')]

def pidcmd(pid):
    return file('/proc/%d/cmdline').read()

def piduser(pid):
    return os.stat('/proc/%d/cmdline' % pid).st_uid

def pidgroup(pid):
    return os.stat('/proc/%d/cmdline' % pid).st_gid

def memory():
    t = {}
    for l in file('/proc/meminfo'):
        m = _fieldpat.match(l)
        if m:
            t[m.group(1).lower()] = int(m.group(2))
    return t

def showpids():
    p = pids()
    pt = processtotals(p)

    fields = dict(
        pid=('PID', lambda n: n, '% 6s', lambda: len(pids)),
        user=('User', piduser, '%-8s', None),
        name=('Command', pidname, '%-30s', None),
        rss=('RSS', lambda n: pt[n]['rss'], '% 8s', None),
        pss=('PSS', lambda n: pt[n]['pss'], '% 8s', None),
        )
    columns = 'pid user name pss rss'.split()

    header = ""
    format = ""
    for n in columns:
        f = fields[n][2]
        format += f + " "
        header += f % fields[n][0] + " "

    print header
    for n in p:
        print format % tuple([fields[f][1](n) for f in columns])

showpids()
