From 461b90c341090c46083e83ca59ccb88371e051e4 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Wed, 4 Jan 2017 10:45:55 -0800 Subject: Fix dmesg -c and -C. I never use these, so I didn't notice I'd broken them until someone who does bringup complained. The "one weird trick" with SEEK_DATA is documented at the URL we already point to. SEEK_DATA was added in Linux 3.1 (2011) and isn't available in glibc 2.19 (2014), so I've added that to "portability.h" for the benefit of Ubuntu 14.04. Also make -c and -C mutually exclusive. Also fix some of the formatting I introduced earlier. (A clang-format file would help prevent these mistakes...) --- lib/portability.h | 4 ++++ toys/lsb/dmesg.c | 44 ++++++++++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/lib/portability.h b/lib/portability.h index afe02c1c..e0dd914e 100644 --- a/lib/portability.h +++ b/lib/portability.h @@ -45,6 +45,10 @@ #define RLIMIT_RTTIME 15 #endif +#ifndef SEEK_DATA +#define SEEK_DATA 3 +#endif + // We don't define GNU_dammit because we're not part of the gnu project, and // don't want to get any FSF on us. Unfortunately glibc (gnu libc) // won't give us Linux syscall wrappers without claiming to be part of the diff --git a/toys/lsb/dmesg.c b/toys/lsb/dmesg.c index c88fe113..a991e898 100644 --- a/toys/lsb/dmesg.c +++ b/toys/lsb/dmesg.c @@ -5,7 +5,7 @@ * 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]", TOYFLAG_BIN)) +USE_DMESG(NEWTOY(dmesg, "w(follow)Ctrs#<1n#c[!tr][!Cc]", TOYFLAG_BIN)) config DMESG bool "dmesg" @@ -45,7 +45,8 @@ static int xklogctl(int type, char *buf, int len) } // Use klogctl for reading if we're on a pre-3.5 kernel. -static void legacy_mode() { +static void legacy_mode() +{ char *data, *to, *from; int size; @@ -75,33 +76,23 @@ static void legacy_mode() { if (CFG_TOYBOX_FREE) free(data); } -static void color(int c) { +static void color(int c) +{ if (TT.color) printf("\033[%dm", c); } -void dmesg_main(void) +static void print_all(void) { - // For -n just tell kernel which messages to keep. - if (toys.optflags & FLAG_n) { - xklogctl(8, 0, TT.level); - - return; - } - - // For -C just tell kernel to throw everything out. - if (toys.optflags & FLAG_C) { - xklogctl(5, 0, 0); - - return; - } - - TT.color = isatty(1); - // 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; @@ -161,3 +152,16 @@ void dmesg_main(void) } 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); +} -- cgit v1.2.3