1/* See LICENSE file for copyright and license details. */
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <unistd.h>
7
8#include "util.h"
9
10ssize_t get_dmesg(char *, size_t);
11int clear_dmesg(void);
12int set_console_level(int);
13
14static void
15dmesg_show(const void *buf, size_t n)
16{
17 const char *p = buf;
18 ssize_t r;
19
20 r = write(1, p, n);
21 if (r < 0)
22 eprintf("write:");
23 if (r > 0 && p[r - 1] != '\n')
24 putchar('\n');
25}
26
27static void
28usage(void)
29{
30 eprintf("usage: %s [-Ccr] [-n level]\n", argv0);
31}
32
33// ?man dmesg: print kernel ring buffer
34// ?man display or control the kernel ring buffer messages
35int
36main(int argc, char *argv[])
37{
38 ssize_t n;
39 char *buf;
40 int cflag = 0;
41 long level;
42
43 ARGBEGIN
44 {
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 }
66 ARGEND;
67
68 if (argc)
69 usage();
70
71 n = get_dmesg(NULL, 0);
72 if (n <= 0)
73 n = 16384;
74
75 buf = emalloc(n);
76
77 n = get_dmesg(buf, n);
78 if (n < 0)
79 eprintf("get_dmesg:");
80
81 dmesg_show(buf, n);
82
83 if (cflag && clear_dmesg() < 0)
84 eprintf("clear_dmesg:");
85
86 free(buf);
87
88 if (fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"))
89 return 1;
90
91 return 0;
92}