busybox/util-linux/dmesg.c
<<
>>
Prefs
   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