On 02/20/2017 12:25 PM, enh wrote: > ping. dmesg -C/-c still broken; you can always apply your cleanup > after this patch, when you have time...
Yeah, my bad. I have a reply window open for Daniel Levy's cut stuff too apologizing for sitting on my own local changes there: > $ git diff toys/*/cut.c tests/cut.test | diffstat > tests/cut.test | 33 ++++ > toys/posix/cut.c | 373 > +++++++++++++++++++++---------------------------------- > 2 files changed, 176 insertions(+), 230 deletions(-) for months now without cycling back around to it. I suppose what I should do is extract the patch, attach it to the reply message acknowledging I committed the other patches I backed it out for, and then... abandon it like I basically have every time I've declared diff bankruptcy and started developing against a new "clean" checkout. (I keep meaning to come back to stuff but after 4 years in some cases, it ain't happening.) I miss the days when $DAYJOB wasn't in perpetual crisis mode. The theory behind tomorrow's ELC talk on my mkroot stuff is it forces me to get mkroot in shape by turning it into a crisis with deadline attached, which lets me ignore the other crises without deadlines attached. But of course I'm _also_ supposed to be preparing a table demo the next day for the Turtle boards we've been sitting on for a year now, in hopes of forcing us to take preorders and commit to an availability date. (It's a raspberry pi IIb form factor, all the same I/O devices in the same layout so it fits in the same cases and everything, but it's got an Xilinx Spartan 6 LX25 FPGA instead of an ARM SOC, so you load an open processor bitstream into it to run Linux. Of course I'm demoing it with j-core, and of course despite having the prototypes most of a year now we hadn't implemented an HDMI text console until... hardware has a new bitstream sitting in my inbox, kernel side driver they told me to write. So I guess that's my tomorrow night. And trying to buy a small HDTV in portland.) Tell you what: here's the unfinished dmesg patch. I will probably never look at it again. The theory was to have both the old and new APIs extract a line at a time from their input and then submit it to a common codepath that would color it appropriately upon output, that way the old and new APIs would use 90% the same code. And since you basically did a complete rewrite of dmesg that I haven't had a chance to do the design changes I want on: I'm putting it back into pending. (Not that this matters much to Android's build...) Rob P.S. If you can think of a way to implement tests/dmesg.test I'm all ears. Even with the mkroot stuff, making that reproducible is tricksy. P.P.S. An advantage of a --color command line option is I can test colored output without having to write a program that implements its own pseudo-terminal to collect the output.
diff --git a/toys/lsb/dmesg.c b/toys/lsb/dmesg.c index c88fe11..4aa1b15 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#<1>9c[!tr]", TOYFLAG_BIN)) config DMESG bool "dmesg" @@ -15,8 +15,8 @@ config DMESG Print or control the kernel ring buffer. - -C Clear ring buffer without printing - -c Clear ring buffer after printing + -C Clear the ring buffer + -c Clear the ring buffer after printing -n Set kernel logging LEVEL (1-9) -r Raw output (with <level markers>) -s Show the last SIZE many bytes @@ -35,24 +35,30 @@ GLOBALS( int color; ) -static int xklogctl(int type, char *buf, int len) +static void color(int c) +{ + if (TT.color) printf("\033[%dm", c); +} + +// Output lines appropriately colored +static void dmesg_line(int level, long long usec, char *str) { - 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() { +static void syscall_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); + size = TT.size; + if (!size && 1>(size = klogctl(10, 0, 0))) perror_exit("klogctl");; data = to = from = xmalloc(size+1); - data[size = xklogctl(3 + (toys.optflags & FLAG_c), data, size)] = 0; + size = klogctl(3 + (toys.optflags & FLAG_c), data, size); + if (size < 0) perror_exit("klogctl"); + data[size] = 0; // Filter out level markers and optionally time markers if (!(toys.optflags & FLAG_r)) while ((from - data) < size) { @@ -75,23 +81,19 @@ static void legacy_mode() { if (CFG_TOYBOX_FREE) free(data); } -static void color(int c) { - if (TT.color) printf("\033[%dm", c); -} - void dmesg_main(void) { - // For -n just tell kernel which messages to keep. - if (toys.optflags & FLAG_n) { - xklogctl(8, 0, TT.level); + int fd; + // For -n just tell kernel to which messages to keep. + if (TT.level) { + if (klogctl(8, NULL, TT.level)) perror_exit("klogctl"); return; } // For -C just tell kernel to throw everything out. if (toys.optflags & FLAG_C) { - xklogctl(5, 0, 0); - + if (klogctl(5, NULL, 0)) perror_exit("klogctl"); return; } @@ -100,36 +102,39 @@ void dmesg_main(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)); - while (1) { + // more messages (--follow); O_NONBLOCK is needed for usual behavior. + // If /dev/kmsg isn't there, we fall through to syscall. + fd = open("/dev/kmsg", O_RDONLY | ((toys.optflags&FLAG_w)?0:O_NONBLOCK)); + for (;;) { 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 (-1 == (len = read(fd, msg, sizeof(msg)))) { + // kmsg fails with EPIPE if we try to read while the buffer moves, + // because EAGAIN would have made too much sense. + if (errno == EPIPE) continue; + // All reads from kmsg fail if you're on a pre-3.5 kernel. + if (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. + // Format has csv prefix ending with ; and abitrary data after \n + pos = 0; + sscanf(msg, "%u,%*u,%llu,%*[^;];%n", &facpri, &time_us, &pos); + if (!pos) continue; text = msg + pos; if ((p = strchr(text, '\n'))) *p = 0; + + dmesg_line(facpri, time_us, text); + // Is there a subsystem? (The ": " is just a convention.) p = strstr(text, ": "); subsystem = p ? (p - text) : 0; @@ -151,7 +156,7 @@ void dmesg_main(void) text += subsystem; color(0); } - if (!((facpri&7) <= 3)) xputs(text); + if (!((facpri&7) <= 3)) puts(text); else { color(31); printf("%s", text);
_______________________________________________ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net