Путь: Toys/LSB, команды версии: Ver.4 Ver.9 dmesg Комментарии в файле dmesg.c :
Исходный текст в файле dmesg.c #define FOR_dmesg #include "toys.h" #include <sys/klog.h> GLOBALS( long n, s; int use_color; time_t tea; ) static void color(int c) { if (TT.use_color) printf("\e[%dm", c); } static void format_message(char *msg, int new) { unsigned long long time_s, time_us; int facpri, subsystem, pos, ii, jj, in, out; char *p, *text; // The new /dev/kmsg and the old syslog(2) formats differ slightly. if (new) { if (sscanf(msg, "%u,%*u,%llu,%*[^;]; %n", &facpri, &time_us, &pos) != 2) return; time_s = time_us/1000000; time_us %= 1000000; } else if (sscanf(msg, "<%u>[%llu.%llu] %n", &facpri, &time_s, &time_us, &pos) != 3) return; // Drop extras after end of message text. if ((p = strchr(text = msg+pos, '\n'))) *p = 0; // Is there a subsystem? (The ": " is just a convention.) p = strstr(text, ": "); subsystem = p ? (p-text) : 0; // To get "raw" output for /dev/kmsg we need to add priority to each line if (FLAG(r)) { color(0); printf("<%d>", facpri); } else for (in = out = subsystem;; ) { jj = 0; if (text[in]=='\\'&& 1==sscanf(text+in, "\\x%2x%n", &ii, &jj) && jj==4) { in += 4; text[out++] = ii; } else if (!(text[out++] = text[in++])) break; } // Format the time. if (!FLAG(t)) { color(32); if (FLAG(T)) { time_t t = TT.tea+time_s; char *ts = ctime(&t); printf("[%.*s] ", (int)(strlen(ts)-1), ts); } else printf("[%5lld.%06lld] ", time_s, time_us); } // Errors (or worse) are shown in red, subsystems are shown in yellow. if (subsystem) { color(33); printf("%.*s", subsystem, text); text += subsystem; } color(31*((facpri&7)<=3)); xputs(text); } static int xklogctl(int type, char *buf, int len) { int rc = klogctl(type, buf, len); if (rc<0) perror_exit("klogctl"); return rc; } static void dmesg_cleanup(void) { color(0); } void dmesg_main(void) { TT.use_color = isatty(1); if (TT.use_color) sigatexit(dmesg_cleanup); // If we're displaying output, is it klogctl or /dev/kmsg? if (FLAG(C)||FLAG(n)) goto no_output; if (FLAG(T)) { struct sysinfo info; sysinfo(&info); TT.tea = time(0)-info.uptime; } if (!FLAG(S)) { char msg[8193]; // CONSOLE_EXT_LOG_MAX+1 ssize_t len; int fd; // Each read returns one message. By default, we block when there are no // more messages (--follow); O_NONBLOCK is needed for for usual behavior. fd = open("/dev/kmsg", O_RDONLY|(O_NONBLOCK*!FLAG(w))); if (fd == -1) goto klogctl_mode; // SYSLOG_ACTION_CLEAR(5) doesn't actually remove anything from /dev/kmsg, // you need to seek to the last clear point. lseek(fd, 0, SEEK_DATA); for (;;) { // why does /dev/kmesg return EPIPE instead of EAGAIN if oldest message // expires as we read it? if (-1==(len = read(fd, msg, sizeof(msg)-1)) && errno==EPIPE) continue; // read() from kmsg always fails on a pre-3.5 kernel. if (len==-1 && errno==EINVAL) goto klogctl_mode; if (len<1) break; msg[len] = 0; format_message(msg, 1); } close(fd); } else { char *data, *to, *from, *end; int size; klogctl_mode: // Figure out how much data we need, and fetch it. if (!(size = TT.s)) size = xklogctl(10, 0, 0); data = from = xmalloc(size+1); data[size = xklogctl(3+!!FLAG(c), data, size)] = 0; // Send each line to format_message. to = data + size; while (from < to) { if (!(end = memchr(from, '\n', to-from))) break; *end = 0; format_message(from, 0); from = end + 1; } if (CFG_TOYBOX_FREE) free(data); } no_output: // Set the log level? if (FLAG(n)) xklogctl(8, 0, TT.n); // Clear the buffer? if (FLAG(C)||FLAG(c)) xklogctl(5, 0, 0); } |