master xplshn/aruu / cmd / pseudo / dmesg.c
 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}