Unua versio.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static char showtitle = 1;
struct Filemap
{
char name[300];
int size;
int rss;
int shared_clean;
int shared_dirty;
int private_clean;
int private_dirty;
enum {
PRIVATE,
SHARED
} type;
char readable;
char writable;
char executable;
int inode;
struct {
unsigned char major;
unsigned char minor;
} device;
};
struct Totals
{
int size;
int rss;
int shared_clean;
int shared_dirty;
int private_clean;
int private_dirty;
char cmd[200];
};
static int readkb(const char *field, FILE *stream)
{
int kb;
int res;
char line[200];
strcpy(line, field);
strcat(line, " %i kB\n");
res = fscanf(stream, line, &kb);
if (res != 1)
return -1;
return kb;
}
static int readsize(FILE *stream)
{
return readkb("Size:", stream);
}
static int readrss(FILE *stream)
{
return readkb("Rss:", stream);
}
static int readshared_clean(FILE *stream)
{
return readkb("Shared_Clean:", stream);
}
static int readshared_dirty(FILE *stream)
{
return readkb("Shared_Dirty:", stream);
}
static int readprivate_clean(FILE *stream)
{
return readkb("Private_Clean:", stream);
}
static int readprivate_dirty(FILE *stream)
{
return readkb("Private_Dirty:", stream);
}
static int readfilemap(FILE *stream, struct Filemap *map)
{
int res;
char type;
unsigned int major;
unsigned int minor;
res = fscanf(stream, "%*x-%*x %c%c%c%c %*x %x:%x %i",
&map->readable,
&map->writable,
&map->executable,
&type,
&major,
&minor,
&map->inode);
if (res != 7)
return -1;
fgets(map->name, 300, stream);
map->device.major = major;
map->device.minor = minor;
if (type == 's')
map->type = PRIVATE;
else
map->type = SHARED;
if (map->readable == '-')
map->readable = 0;
if (map->writable == '-')
map->writable = 0;
if (map->executable == '-')
map->executable = 0;
map->size = readsize(stream);
if (map->size == -1)
return -2;
map->rss = readrss(stream);
if (map->rss == -1)
return -2;
map->shared_clean = readshared_clean(stream);
if (map->shared_clean == -1)
return -2;
map->shared_dirty = readshared_dirty(stream);
if (map->shared_dirty == -1)
return -2;
map->private_clean = readprivate_clean(stream);
if (map->private_clean == -1)
return -2;
map->private_dirty = readprivate_dirty(stream);
if (map->private_dirty == -1)
return -2;
return 0;
}
static int readsmap(const int pid, struct Totals *totals)
{
FILE *stream;
char filename[100];
snprintf(filename, 100, "/proc/%i/smaps", pid);
stream = fopen(filename, "r");
if (stream == 0)
return -1;
totals->size = 0;
totals->rss = 0;
totals->shared_clean = 0;
totals->shared_dirty = 0;
totals->private_clean = 0;
totals->private_dirty = 0;
while(!feof(stream))
{
struct Filemap map;
int res;
res = readfilemap(stream, &map);
if (res == -1)
break;
if (res == -2)
{
fprintf(stderr, "ERROR READING %s\n", filename);
break;
}
/*printf("Map: %s\n", map.name);*/
totals->size = totals->size + map.size;
totals->rss = totals->rss + map.rss;
totals->shared_clean = totals->shared_clean + map.shared_clean;
totals->shared_dirty = totals->shared_dirty + map.shared_dirty;
totals->private_clean = totals->private_clean
+ map.private_clean;
totals->private_dirty = totals->private_dirty
+ map.private_dirty;
}
fclose(stream);
/* Read the cmd */
totals->cmd[0] = '\0';
snprintf(filename, 100, "/proc/%i/cmdline", pid);
stream = fopen(filename, "r");
fgets(totals->cmd, 200, stream);
fclose(stream);
return 0;
}
static void showtotals(const int pid, const struct Totals *totals)
{
if (showtitle)
printf("PID\tSIZE\tRSS\tS_CLN\tS_DTY\tP_CLN\tP_DTY\tCMD\n");
printf("%i\t%i\t%i\t%i\t%i\t%i\t%i\t%s\n",
pid,
totals->size,
totals->rss,
totals->shared_clean,
totals->shared_dirty,
totals->private_clean,
totals->private_dirty,
totals->cmd);
}
static void showhelp(const char *progname)
{
fprintf(stderr,"usage: %s <pid>\n", progname);
}
int main(int argc, char *argv[])
{
int pid;
struct Totals t;
int res;
if (argc < 2)
{
showhelp(argv[0]);
return 1;
}
if (argc == 2)
pid = atoi(argv[1]);
else
{
if (argv[1][1] == 'q')
showtitle = 0;
pid = atoi(argv[2]);
}
res = readsmap(pid, &t);
if (res == -1)
return -1;
showtotals(pid, &t);
return 0;
}