1/* See LICENSE file for copyright and license details. */
2
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <unistd.h>
8
9#include "util.h"
10
11ssize_t get_dmesg(char *, size_t);
12int clear_dmesg(void);
13int set_console_level(int);
14
15static void
16dmesg_show(const void *buf, size_t n)
17{
18 const char *p = buf;
19 ssize_t r;
20
21 r = write(1, p, n);
22 if (r < 0)
23 eprintf("write:");
24 if (r > 0 && p[r - 1] != '\n')
25 putchar('\n');
26}
27
28static void
29usage(void)
30{
31 eprintf("usage: %s [-Ccr] [-n level]\n", argv0);
32}
33
34// ?man dmesg: print kernel ring buffer
35// ?man display or control the kernel ring buffer messages
36int
37main(int argc, char *argv[])
38{
39 ssize_t n;
40 char *buf;
41 int cflag = 0;
42 long level;
43
44 ARGBEGIN {
45 // ?man -C: specify option flag
46 case 'C':
47 if (clear_dmesg() < 0)
48 eprintf("clear_dmesg:");
49 return 0;
50 // ?man -c: print count or perform stdout action
51 case 'c':
52 cflag = 1;
53 break;
54 // ?man -r: operate recursively
55 case 'r':
56 break;
57 // ?man -n:num: print line numbers or counts
58 case 'n':
59 level = estrtol(EARGF(usage()), 10);
60 if (set_console_level(level) < 0)
61 eprintf("set_console_level:");
62 return 0;
63 default:
64 usage();
65 } ARGEND;
66
67 if (argc)
68 usage();
69
70 n = get_dmesg(NULL, 0);
71 if (n <= 0)
72 n = 16384;
73
74 buf = emalloc(n);
75
76 n = get_dmesg(buf, n);
77 if (n < 0)
78 eprintf("get_dmesg:");
79
80 dmesg_show(buf, n);
81
82 if (cflag && clear_dmesg() < 0)
83 eprintf("clear_dmesg:");
84
85 free(buf);
86
87 if (fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"))
88 return 1;
89
90 return 0;
91}