dmesg: dynamically allocate dmesg buffer.

The previous version assumed the kernel dmesg buffer was 128k.  All
reasonably recent kernels can tell you the buffer size using a syscall, so
let's use that instead.

Change-Id: Ida692a4210e9c653e5455548f7b37609c1103abf
diff --git a/dmesg.c b/dmesg.c
index 94e80ca..4086ecb 100644
--- a/dmesg.c
+++ b/dmesg.c
@@ -5,9 +5,6 @@
 #include <sys/klog.h>
 #include <string.h>
 
-#define KLOG_BUF_SHIFT	17	/* CONFIG_LOG_BUF_SHIFT from our kernel */
-#define KLOG_BUF_LEN	(1 << KLOG_BUF_SHIFT)
-
 // From Android sys/klog.h
 #ifndef KLOG_READ_ALL
 #define KLOG_READ_ALL   3
@@ -15,13 +12,28 @@
 #ifndef KLOG_READ_CLEAR
 #define KLOG_READ_CLEAR 4
 #endif
+#ifndef KLOG_SIZE_BUFFER
+#define KLOG_SIZE_BUFFER 10
+#endif
 
 int dmesg_main(int argc, char **argv)
 {
-    char buffer[KLOG_BUF_LEN + 1];
-    char *p = buffer;
+    char *buffer;
+    char *p;
     ssize_t ret;
-    int n, op;
+    int n, op, bufsize;
+
+    bufsize = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
+    if (bufsize <= 0) {
+        perror("klogctl size_buffer");
+        return EXIT_FAILURE;
+    }
+    buffer = malloc(bufsize);
+    if (!buffer) {
+        perror("malloc");
+        return EXIT_FAILURE;
+    }
+    buffer[0] = 0;
 
     if((argc == 2) && (!strcmp(argv[1],"-c"))) {
         op = KLOG_READ_CLEAR;
@@ -29,14 +41,15 @@
         op = KLOG_READ_ALL;
     }
 
-    n = klogctl(op, buffer, KLOG_BUF_LEN);
+    n = klogctl(op, buffer, bufsize);
     if (n < 0) {
         perror("klogctl");
         return EXIT_FAILURE;
     }
     buffer[n] = '\0';
 
-    while((ret = write(STDOUT_FILENO, p, n))) {
+    p = buffer;
+    while ((ret = write(STDOUT_FILENO, p, n))) {
         if (ret == -1) {
 	    if (errno == EINTR)
                 continue;
@@ -46,6 +59,6 @@
 	p += ret;
 	n -= ret;
     }
-
+    free(buffer);
     return 0;
 }