Unua versio. default tip
authorviric@llimona
Fri, 23 Feb 2007 23:54:45 +0100
changeset 0 5425a5439bcd
Unua versio.
Makefile
smapsum.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Fri Feb 23 23:54:45 2007 +0100
@@ -0,0 +1,2 @@
+CFLAGS?=-g -Wall -pedantic
+smapsum: smapsum.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smapsum.c	Fri Feb 23 23:54:45 2007 +0100
@@ -0,0 +1,248 @@
+#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;
+}