diff -Naur old/memstat-0.9/Makefile memstat-0.9/Makefile
--- old/memstat-0.9/Makefile	2012-01-20 14:18:08.444775271 +0100
+++ memstat-0.9/Makefile	2012-01-20 14:26:41.284768094 +0100
@@ -4,6 +4,7 @@
 # This file is under the GPL.
 #
 CFLAGS = -g -Wall -O2
+LDFLAGS = -lm
 prefix = $(DESTDIR)/
 exec_prefix = $(prefix)/usr
 
diff -Naur old/memstat-0.9/memstat.c memstat-0.9/memstat.c
--- old/memstat-0.9/memstat.c	2012-01-20 14:18:08.444775271 +0100
+++ memstat-0.9/memstat.c	2012-01-23 16:55:36.760860969 +0100
@@ -19,6 +19,11 @@
 #include <unistd.h>
 #include <getopt.h>
 #include <errno.h>
+#include <math.h>
+
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif
 
 /* blacklist devices that just map physical memory */
 char *blacklist[] = { "/dev/mem",
@@ -58,11 +63,40 @@
     maptab_size = maptab_size * 2 + 100;
 }
 
+static char * 
+get_line(FILE * f)
+{
+    char * buf  = NULL;
+    size_t buf_size = 0;
+    size_t last = 0; // first unused byte
+
+    while (!feof(f))
+    {
+    //The usual approach is to reallocate the buffer geometrically
+    if (buf_size < last + BUFSIZ + 1) {
+	buf_size = buf_size ? buf_size * 2 : BUFSIZ + 1;
+	buf = realloc(buf, buf_size);
+    }
+
+    if (fgets(buf+last, BUFSIZ, f) == NULL) {
+	free(buf);
+	return NULL;
+    }
+    last = strlen(buf);
+    if (buf[last-1] == '\n') 
+	    return buf;
+    }
+
+    return buf;
+}
+
 static void read_proc(void)
 {
     unsigned int nread, pid;
     unsigned long inode, lo, hi, offs;
-    char *p, major[8], minor[8], buff[PATH_MAX + 300], *path, perm[4];
+    char *p, major[8], minor[8], *path, perm[4];
+    char *buff = NULL;
+    int buff_size = 0;
     DIR *d;
     struct dirent *ent;
     FILE *f;
@@ -85,11 +119,23 @@
 	}
 	if (pid == 0 || (only_pid != 0 && pid != only_pid))
 	    continue;
+	
+	buff_size = 11; /* size of the format string without "%x" expressions */
+	buff_size += sizeof(int) * 3 + 1;
+	buff_size += 1; // '\0'
+	buff = (char *)malloc((buff_size) * sizeof(char));
 	sprintf(buff, "/proc/%d/maps", pid);
 	f = fopen(buff, "r");
+	free(buff);
 	if (f == NULL)
 	    continue;
-	while (fgets(buff, sizeof(buff), f)) {
+	
+	/* Read the file line by line. */
+	while (!feof(f)) 
+	{
+        buff = get_line(f);
+        if (buff == NULL) { break; }
+        
 	    p = strchr(buff, '-');
 	    if (p)
 		*p = ' ';
@@ -97,11 +143,16 @@
 	    if (p)
 		*p = ' ';
 	    path = NULL;
-	    if ((strlen(buff) == 10) && (strcmp(buff, " (deleted)") == 0))
+	    if ((strlen(buff) == 10) && (strcmp(buff, " (deleted)") == 0)) {
+		free(buff);
 		continue;
+	    }
 	    nread = sscanf(buff, "%lx %lx %4s %lx %s %s %lu %as", &lo, &hi, perm, &offs, major, minor, &inode, &path);
+	    free(buff);
 	    if (nread < 7) {
 		fprintf(stderr, "I don't recognize format of /proc/%d/maps. (nread=%d)\n", pid, nread);
+		fclose(f);
+		closedir(d);
 		exit(1);
 	    }
 	    if (maptab_fill == maptab_size)
@@ -128,6 +179,12 @@
 			m->valid = 0;
 		}
 	    } else {
+		buff_size = 4; /* size of the format string without "%x" expressions */
+		buff_size += strlen(major);
+		buff_size += strlen(minor);
+		buff_size += sizeof(int) * 3 + 1; // inode
+		buff_size += 1; // '\0'
+		buff = (char *)malloc((buff_size) * sizeof(char));
 		sprintf(buff, "[%s:%s]:%lu", major, minor, inode);
 		m->path = strdup(buff);
 		needinode = 1;
@@ -251,17 +308,39 @@
     grand = sharedgrand = 0;
     qsort(maptab_data, maptab_fill, sizeof(struct mapping), (qcmp) sort_by_pid);
     for (offs = 0; offs < maptab_fill; offs = scan) {
-	char linkname[PATH_MAX], filename[PATH_MAX];
+	char *linkname = NULL;
+	char *filename = NULL;
+	unsigned int filename_size = 0;
+	struct stat sb;
 	ssize_t len;
 	int deleted = 0;
 
 	pid = maptab_data[offs].pid;
+	filename_size = 10; /* size of the format string without "%x" expressions */
+	filename_size += sizeof(int) * 3 + 1;
+	filename_size += 1; // '\0'
+	filename = (char *)malloc((filename_size) * sizeof(char));
 	sprintf(filename, "/proc/%d/exe", pid);
-	if ((len = readlink(filename, linkname, PATH_MAX)) == -1) {
-	    fprintf(stderr, "Cannot read link information for %s\n", filename);
+	
+	if (lstat(filename, &sb) == -1) {
+        perror("lstat");
+        exit(EXIT_FAILURE);
+    }
+    linkname = malloc(sb.st_size + 1);
+    if (linkname == NULL) {
+        fprintf(stderr, "insufficient memory\n");
+        exit(EXIT_FAILURE);
+    }
+    
+	len = readlink(filename, linkname, sb.st_size + 1);
+	
+	if (len < 0 || len > sb.st_size) {
+    	fprintf(stderr, "Cannot read link information for %s\n", filename);
 	    deleted = 1;
 	}
-	linkname[len] = '\0';
+	free(filename);
+	linkname[sb.st_size] = '\0';
+	
 	total = 0;
 	for (scan = offs; scan < maptab_fill; scan++) {
 	    m = maptab_data + scan;
@@ -277,6 +356,7 @@
 		printline(buffer);
 		grand += total;
 	}
+    free(linkname);
     }
 
     qsort(maptab_data, maptab_fill, sizeof(struct mapping), (qcmp) sort_by_inode);
