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