klibc-utils: add dmesg
read and/or clear kernel message ring buffer
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Signed-off-by: maximilian attems <max@stro.at>
diff --git a/usr/utils/Kbuild b/usr/utils/Kbuild
index 4ce17be..09157a8 100644
--- a/usr/utils/Kbuild
+++ b/usr/utils/Kbuild
@@ -4,7 +4,7 @@
progs := chroot dd mkdir mkfifo mknod mount pivot_root umount
progs += true false sleep ln nuke minips cat
-progs += insmod uname halt kill readlink cpio sync
+progs += insmod uname halt kill readlink cpio sync dmesg
static-y := $(addprefix static/, $(progs))
shared-y := $(addprefix shared/, $(progs))
@@ -14,6 +14,8 @@
shared/chroot-y := chroot.o
static/dd-y := dd.o
shared/dd-y := dd.o
+static/dmesg-y := dmesg.o
+shared/dmesg-y := dmesg.o
static/mkdir-y := mkdir.o file_mode.o
shared/mkdir-y := mkdir.o file_mode.o
static/mkfifo-y := mkfifo.o file_mode.o
diff --git a/usr/utils/dmesg.c b/usr/utils/dmesg.c
new file mode 100644
index 0000000..5369c03
--- /dev/null
+++ b/usr/utils/dmesg.c
@@ -0,0 +1,71 @@
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+static void usage(char *name)
+{
+ fprintf(stderr, "usage: %s [-c]\n", name);
+}
+
+int main(int argc, char *argv[])
+{
+ char *buf = NULL;
+ int bufsz = 0;
+ int cmd = 3; /* Read all messages remaining in the ring buffer */
+ int len = 0;
+ int opt;
+ int i = 0;
+
+ while ((opt = getopt(argc, argv, "c")) != -1) {
+ switch(opt) {
+ /* Read and clear all messages remaining in the ring buffer */
+ case 'c':
+ cmd = 4;
+ break;
+ case '?':
+ default:
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ if (!bufsz) {
+ len = klogctl(10, NULL, 0); /* Return size of the log buffer */
+ if (len > 0)
+ bufsz = len;
+ }
+
+ if (bufsz) {
+ int sz = bufsz + 8;
+
+ buf = (char *)malloc(sz);
+ len = klogctl(cmd, buf, sz);
+ }
+
+ if (len < 0) {
+ perror("klogctl");
+ exit(1);
+ }
+
+ while (buf[i] && i < len)
+ switch (buf[i]) {
+ case '<':
+ if (i == 0 || buf[i-1] == '\n')
+ i++;
+ case '0' ... '9':
+ if (i > 0 && buf[i-1] == '<')
+ i++;
+ case '>':
+ if (i > 0 && isdigit(buf[i-1]))
+ i++;
+ default:
+ putchar(buf[i++]);
+ }
+
+ if (buf[i-1] != '\n')
+ putchar('\n');
+
+ return 0;
+}