diff options
author | Elliott Hughes <enh@google.com> | 2017-01-04 10:45:55 -0800 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2017-02-20 21:42:26 -0600 |
commit | 461b90c341090c46083e83ca59ccb88371e051e4 (patch) | |
tree | 98fc3da837953eb5c191c50b7059bbcb7530af3d | |
parent | ac22dfa9c751ca15c2cd90b6a702ebd960b202ee (diff) | |
download | toybox-461b90c341090c46083e83ca59ccb88371e051e4.tar.gz |
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...)
-rw-r--r-- | lib/portability.h | 4 | ||||
-rw-r--r-- | 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); +} |