aboutsummaryrefslogtreecommitdiff
path: root/toys/lsb/dmesg.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/lsb/dmesg.c')
-rw-r--r--toys/lsb/dmesg.c167
1 files changed, 0 insertions, 167 deletions
diff --git a/toys/lsb/dmesg.c b/toys/lsb/dmesg.c
deleted file mode 100644
index a991e898..00000000
--- a/toys/lsb/dmesg.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* dmesg.c - display/control kernel ring buffer.
- *
- * Copyright 2006, 2007 Rob Landley <rob@landley.net>
- *
- * http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/dmesg.html
-
-// We care that FLAG_c is 1, so keep c at the end.
-USE_DMESG(NEWTOY(dmesg, "w(follow)Ctrs#<1n#c[!tr][!Cc]", TOYFLAG_BIN))
-
-config DMESG
- bool "dmesg"
- default y
- help
- usage: dmesg [-Cc] [-r|-t] [-n LEVEL] [-s SIZE] [-w]
-
- Print or control the kernel ring buffer.
-
- -C Clear ring buffer without printing
- -c Clear ring buffer after printing
- -n Set kernel logging LEVEL (1-9)
- -r Raw output (with <level markers>)
- -s Show the last SIZE many bytes
- -t Don't print kernel's timestamps
- -w Keep waiting for more output (aka --follow)
-*/
-
-#define FOR_dmesg
-#include "toys.h"
-#include <sys/klog.h>
-
-GLOBALS(
- long level;
- long size;
-
- int color;
-)
-
-static int xklogctl(int type, char *buf, int len)
-{
- int rc = klogctl(type, buf, len);
-
- if (rc<0) perror_exit("klogctl");
-
- return rc;
-}
-
-// Use klogctl for reading if we're on a pre-3.5 kernel.
-static void legacy_mode()
-{
- char *data, *to, *from;
- int size;
-
- // Figure out how much data we need, and fetch it.
- if (!(size = TT.size)) size = xklogctl(10, 0, 0);
- data = to = from = xmalloc(size+1);
- data[size = xklogctl(3 + (toys.optflags & FLAG_c), data, size)] = 0;
-
- // Filter out level markers and optionally time markers
- if (!(toys.optflags & FLAG_r)) while ((from - data) < size) {
- if (from == data || from[-1] == '\n') {
- char *to;
-
- if (*from == '<' && (to = strchr(from, '>'))) from = ++to;
- if ((toys.optflags&FLAG_t) && *from == '[' && (to = strchr(from, ']')))
- from = to+1+(to[1]==' ');
- }
- *(to++) = *(from++);
- } else to = data+size;
-
- // Write result. The odds of somebody requesting a buffer of size 3 and
- // getting "<1>" are remote, but don't segfault if they do.
- if (to != data) {
- xwrite(1, data, to-data);
- if (to[-1] != '\n') xputc('\n');
- }
- if (CFG_TOYBOX_FREE) free(data);
-}
-
-static void color(int c)
-{
- if (TT.color) printf("\033[%dm", c);
-}
-
-static void print_all(void)
-{
- // http://kernel.org/doc/Documentation/ABI/testing/dev-kmsg
-
- // Each read returns one message. By default, we block when there are no
- // more messages (--follow); O_NONBLOCK is needed for for usual behavior.
- int fd = xopen("/dev/kmsg", O_RDONLY | ((toys.optflags&FLAG_w)?0:O_NONBLOCK));
-
- // With /dev/kmsg, SYSLOG_ACTION_CLEAR (5) doesn't actually remove anything;
- // you need to seek to the last clear point.
- lseek(fd, 0, SEEK_DATA);
-
- while (1) {
- char msg[8192]; // CONSOLE_EXT_LOG_MAX.
- unsigned long long time_us;
- int facpri, subsystem, pos;
- char *p, *text;
- ssize_t len;
-
- // kmsg fails with EPIPE if we try to read while the buffer moves under
- // us; the next read will succeed and return the next available entry.
- do {
- len = read(fd, msg, sizeof(msg));
- } while (len == -1 && errno == EPIPE);
- // All reads from kmsg fail if you're on a pre-3.5 kernel.
- if (len == -1 && errno == EINVAL) {
- close(fd);
- return legacy_mode();
- }
- if (len <= 0) break;
-
- msg[len] = 0;
-
- if (sscanf(msg, "%u,%*u,%llu,%*[^;];%n", &facpri, &time_us, &pos) != 2)
- continue;
-
- // Drop extras after end of message text.
- text = msg + pos;
- if ((p = strchr(text, '\n'))) *p = 0;
-
- // Is there a subsystem? (The ": " is just a convention.)
- p = strstr(text, ": ");
- subsystem = p ? (p - text) : 0;
-
- // "Raw" is a lie for /dev/kmsg. In practice, it just means we show the
- // syslog facility/priority at the start of each line.
- if (toys.optflags&FLAG_r) printf("<%d>", facpri);
-
- if (!(toys.optflags&FLAG_t)) {
- color(32);
- printf("[%5lld.%06lld] ", time_us/1000000, time_us%1000000);
- color(0);
- }
-
- // Errors (or worse) are shown in red, subsystems are shown in yellow.
- if (subsystem) {
- color(33);
- printf("%.*s", subsystem, text);
- text += subsystem;
- color(0);
- }
- if (!((facpri&7) <= 3)) xputs(text);
- else {
- color(31);
- printf("%s", text);
- color(0);
- xputc('\n');
- }
- }
- close(fd);
-}
-
-void dmesg_main(void)
-{
- TT.color = isatty(1);
-
- if (!(toys.optflags & (FLAG_C|FLAG_n))) print_all();
-
- // Set the log level?
- if (toys.optflags & FLAG_n) xklogctl(8, 0, TT.level);
-
- // Clear the buffer?
- if (toys.optflags & (FLAG_C|FLAG_c)) xklogctl(5, 0, 0);
-}