1/* vi: set sw=4 ts=4: */ 2/* 3 * 4 * dmesg - display/control kernel ring buffer. 5 * 6 * Copyright 2006 Rob Landley <rob@landley.net> 7 * Copyright 2006 Bernhard Reutner-Fischer <rep.nop@aon.at> 8 * 9 * Licensed under GPLv2, see file LICENSE in this source tree. 10 */ 11//config:config DMESG 12//config: bool "dmesg (3.7 kb)" 13//config: default y 14//config: select PLATFORM_LINUX 15//config: help 16//config: dmesg is used to examine or control the kernel ring buffer. When the 17//config: Linux kernel prints messages to the system log, they are stored in 18//config: the kernel ring buffer. You can use dmesg to print the kernel's ring 19//config: buffer, clear the kernel ring buffer, change the size of the kernel 20//config: ring buffer, and change the priority level at which kernel messages 21//config: are also logged to the system console. Enable this option if you 22//config: wish to enable the 'dmesg' utility. 23//config: 24//config:config FEATURE_DMESG_PRETTY 25//config: bool "Pretty output" 26//config: default y 27//config: depends on DMESG 28//config: help 29//config: If you wish to scrub the syslog level from the output, say 'Y' here. 30//config: The syslog level is a string prefixed to every line with the form 31//config: "<#>". 32//config: 33//config: With this option you will see: 34//config: # dmesg 35//config: Linux version 2.6.17.4 ..... 36//config: BIOS-provided physical RAM map: 37//config: BIOS-e820: 0000000000000000 - 000000000009f000 (usable) 38//config: 39//config: Without this option you will see: 40//config: # dmesg 41//config: <5>Linux version 2.6.17.4 ..... 42//config: <6>BIOS-provided physical RAM map: 43//config: <6> BIOS-e820: 0000000000000000 - 000000000009f000 (usable) 44 45//applet:IF_DMESG(APPLET(dmesg, BB_DIR_BIN, BB_SUID_DROP)) 46 47//kbuild:lib-$(CONFIG_DMESG) += dmesg.o 48 49//usage:#define dmesg_trivial_usage 50//usage: "[-c] [-n LEVEL] [-s SIZE]" 51//usage:#define dmesg_full_usage "\n\n" 52//usage: "Print or control the kernel ring buffer\n" 53//usage: "\n -c Clear ring buffer after printing" 54//usage: "\n -n LEVEL Set console logging level" 55//usage: "\n -s SIZE Buffer size" 56//usage: "\n -r Print raw message buffer" 57 58#include <sys/klog.h> 59#include "libbb.h" 60 61int dmesg_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 62int dmesg_main(int argc UNUSED_PARAM, char **argv) 63{ 64 int len, level; 65 char *buf; 66 unsigned opts; 67 enum { 68 OPT_c = 1 << 0, 69 OPT_s = 1 << 1, 70 OPT_n = 1 << 2, 71 OPT_r = 1 << 3 72 }; 73 74 opts = getopt32(argv, "cs:+n:+r", &len, &level); 75 if (opts & OPT_n) { 76 if (klogctl(8, NULL, (long) level)) 77 bb_perror_msg_and_die("klogctl"); 78 return EXIT_SUCCESS; 79 } 80 81 if (!(opts & OPT_s)) 82 len = klogctl(10, NULL, 0); /* read ring buffer size */ 83 if (len < 16*1024) 84 len = 16*1024; 85 if (len > 16*1024*1024) 86 len = 16*1024*1024; 87 88 buf = xmalloc(len); 89 len = klogctl(3 + (opts & OPT_c), buf, len); /* read ring buffer */ 90 if (len < 0) 91 bb_perror_msg_and_die("klogctl"); 92 if (len == 0) 93 return EXIT_SUCCESS; 94 95 96 if (ENABLE_FEATURE_DMESG_PRETTY && !(opts & OPT_r)) { 97 int last = '\n'; 98 int in = 0; 99 100 /* Skip <[0-9]+> at the start of lines */ 101 while (1) { 102 if (last == '\n' && buf[in] == '<') { 103 while (buf[in++] != '>' && in < len) 104 ; 105 } else { 106 last = buf[in++]; 107 putchar(last); 108 } 109 if (in >= len) 110 break; 111 } 112 /* Make sure we end with a newline */ 113 if (last != '\n') 114 bb_putchar('\n'); 115 } else { 116 full_write(STDOUT_FILENO, buf, len); 117 if (buf[len-1] != '\n') 118 bb_putchar('\n'); 119 } 120 121 if (ENABLE_FEATURE_CLEAN_UP) free(buf); 122 123 return EXIT_SUCCESS; 124} 125