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