Index: sys/kern/subr_log.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_log.c,v retrieving revision 1.57 diff -u -u -r1.57 subr_log.c --- sys/kern/subr_log.c 31 Mar 2018 23:12:01 -0000 1.57 +++ sys/kern/subr_log.c 1 Apr 2018 01:46:52 -0000 @@ -404,6 +404,35 @@ } } +static void +logaddchar(struct kern_msgbuf *mbp, int c) +{ + mbp->msg_bufc[mbp->msg_bufx++] = c; + if (mbp->msg_bufx < 0 || mbp->msg_bufx >= mbp->msg_bufs) + mbp->msg_bufx = 0; + + /* If the buffer is full, keep the most recent data. */ + if (mbp->msg_bufr == mbp->msg_bufx) + logskip(mbp); +} + +static int logneedtstamp = 1; + +static void +logaddtstamp(struct kern_msgbuf *mbp) +{ + char buf[64]; + struct timespec ts; + int n; + + getnanouptime(&ts); + n = snprintf(buf, sizeof(buf), "[% 9jd.%.9ld] ", + (intptr_t)ts.tv_sec, ts.tv_nsec); + + for (int i = 0; i < n; i++) + logaddchar(mbp, buf[i]); +} + void logputchar(int c) { @@ -430,14 +459,14 @@ goto out; } + if (logneedtstamp) { + logaddtstamp(mbp); + logneedtstamp = 0; + } + if (c == '\n') + logneedtstamp++; - mbp->msg_bufc[mbp->msg_bufx++] = c; - if (mbp->msg_bufx < 0 || mbp->msg_bufx >= mbp->msg_bufs) - mbp->msg_bufx = 0; - - /* If the buffer is full, keep the most recent data. */ - if (mbp->msg_bufr == mbp->msg_bufx) - logskip(mbp); + logaddchar(mbp, c); out: if (!cold) Index: sbin/dmesg/dmesg.8 =================================================================== RCS file: /cvsroot/src/sbin/dmesg/dmesg.8,v retrieving revision 1.17 diff -u -u -r1.17 dmesg.8 --- sbin/dmesg/dmesg.8 11 Sep 2016 02:24:00 -0000 1.17 +++ sbin/dmesg/dmesg.8 1 Apr 2018 01:46:52 -0000 @@ -29,7 +29,7 @@ .\" .\" @(#)dmesg.8 8.1 (Berkeley) 6/5/93 .\" -.Dd September 11, 2016 +.Dd March 31, 2018 .Dt DMESG 8 .Os .Sh NAME @@ -37,6 +37,7 @@ .Nd "display the system message buffer" .Sh SYNOPSIS .Nm +.Op Fl qt .Op Fl M Ar core .Op Fl N Ar system .Sh DESCRIPTION @@ -51,6 +52,10 @@ .It Fl N Extract the name list from the specified system instead of the default ``/netbsd''. +.It Fl q +Quiet printing, don't print timestamps. +.It Fl t +Format uptime timestamps in a human readable form. .El .Pp The system message buffer is a circular buffer of a fixed size. Index: sbin/dmesg/dmesg.c =================================================================== RCS file: /cvsroot/src/sbin/dmesg/dmesg.c,v retrieving revision 1.27 diff -u -u -r1.27 dmesg.c --- sbin/dmesg/dmesg.c 29 Aug 2011 14:34:59 -0000 1.27 +++ sbin/dmesg/dmesg.c 1 Apr 2018 01:46:52 -0000 @@ -48,6 +48,7 @@ #include #include +#include #include #include #include @@ -73,16 +74,27 @@ main(int argc, char *argv[]) { struct kern_msgbuf cur; - int ch, newl, skip, i; + int ch, newl, log, i; + size_t tstamp, size; char *p, *bufdata; + char buf[5]; #ifndef SMALL + char tbuf[64]; char *memf, *nlistf; -#endif - char buf[5]; + struct timeval boottime; + int ptime = 0; + + static const int bmib[] = { CTL_KERN, KERN_BOOTTIME }; + size = sizeof(boottime); + + boottime.tv_sec = 0; + boottime.tv_usec = 0; + ptime = 0; + + (void)sysctl(bmib, 2, &boottime, &size, NULL, 0); -#ifndef SMALL memf = nlistf = NULL; - while ((ch = getopt(argc, argv, "M:N:")) != -1) + while ((ch = getopt(argc, argv, "M:N:qt")) != -1) switch(ch) { case 'M': memf = optarg; @@ -90,6 +102,12 @@ case 'N': nlistf = optarg; break; + case 'q': + ptime = -1; + break; + case 't': + ptime = 1; + break; case '?': default: usage(); @@ -99,15 +117,11 @@ if (memf == NULL) { #endif - size_t size; - int mib[2]; - - mib[0] = CTL_KERN; - mib[1] = KERN_MSGBUF; + static const int mmib[2] = { CTL_KERN, KERN_MSGBUF }; - if (sysctl(mib, 2, NULL, &size, NULL, 0) == -1 || + if (sysctl(mmib, 2, NULL, &size, NULL, 0) == -1 || (bufdata = malloc(size)) == NULL || - sysctl(mib, 2, bufdata, &size, NULL, 0) == -1) + sysctl(mmib, 2, bufdata, &size, NULL, 0) == -1) err(1, "can't get msgbuf"); /* make a dummy struct msgbuf for the display logic */ @@ -159,22 +173,70 @@ * over cur.msg_bufs times. Unused area is skipped since it * contains nul. */ - for (newl = skip = i = 0, p = bufdata + cur.msg_bufx; + for (tstamp = 0, newl = 1, log = i = 0, p = bufdata + cur.msg_bufx; i < cur.msg_bufs; i++, p++) { #ifndef SMALL if (p == bufdata + cur.msg_bufs) p = bufdata; +#define ADDC(c) \ + do \ + if (tstamp < sizeof(tbuf) - 1) \ + tbuf[tstamp++] = (c); \ + while (/*CONSTCOND*/0) +#else +#define ADDC(c) #endif ch = *p; /* Skip "\n<.*>" syslog sequences. */ - if (skip) { - if (ch == '>') - newl = skip = 0; - continue; - } - if (newl && ch == '<') { - skip = 1; - continue; + /* Gather timestamp sequences */ + if (newl) { + switch (ch) { + case '[': + ADDC(ch); + continue; + case '<': + log = 1; + continue; + case '>': + log = newl = 0; + continue; + case ']': + ADDC(ch); + ADDC('\0'); + tstamp = 0; +#ifndef SMALL + if (ptime == 1) { + intmax_t sec; + time_t t; + long nsec; + struct tm tm; + + sscanf(tbuf, "[%jd.%ld]", &sec, &nsec); + t = boottime.tv_sec + sec; + if (localtime_r(&t, &tm) != NULL) { + strftime(tbuf, sizeof(tbuf), + "[%a %b %e %H:%M:%S %Z %Y]", + &tm); + printf("%s ", tbuf); + } + continue; + } else if (ptime != -1) + printf("%s ", tbuf); +#endif + continue; + case ' ': + if (!tstamp) + continue; + /*FALLTHROUGH*/ + default: + if (tstamp) { + ADDC(ch); + continue; + } + if (log) + continue; + break; + } } if (ch == '\0') continue; @@ -189,7 +251,7 @@ } if (!newl) (void)putchar('\n'); - exit(0); + return EXIT_SUCCESS; } #ifndef SMALL @@ -197,7 +259,8 @@ usage(void) { - (void)fprintf(stderr, "usage: dmesg [-M core] [-N system]\n"); - exit(1); + (void)fprintf(stderr, "Usage: %s [-qt] [-M core] [-N system]\n", + getprogname()); + exit(EXIT_FAILURE); } #endif