OSDN Git Service

Fix dmesg -c and -C.
authorElliott Hughes <enh@google.com>
Wed, 4 Jan 2017 18:45:55 +0000 (10:45 -0800)
committerRob Landley <rob@landley.net>
Tue, 21 Feb 2017 03:42:26 +0000 (21:42 -0600)
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
toys/lsb/dmesg.c

index afe02c1..e0dd914 100644 (file)
 #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
index c88fe11..a991e89 100644 (file)
@@ -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);
+}