xref: /aosp_15_r20/external/toybox/toys/pending/klogd.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
1 /* klogd.c - Klogd, The kernel log Dameon.
2  *
3  * Copyright 2013 Sandeep Sharma <[email protected]>
4  * Copyright 2013 Kyungwan Han <[email protected]>
5  *
6  * No standard
7 
8 USE_KLOGD(NEWTOY(klogd, "c#<1>8ns", TOYFLAG_SBIN))
9 
10 config KLOGD
11   bool "klogd"
12   default n
13   help
14   usage: klogd [-n] [-c PRIORITY]
15 
16   -c	Print to console messages more urgent than PRIORITY (1-8)"
17   -n	Run in foreground
18   -s	Use syscall instead of /proc
19 */
20 
21 #define FOR_klogd
22 #include "toys.h"
23 #include <sys/klog.h>
24 
GLOBALS(long level;int fd;)25 GLOBALS(
26   long level;
27 
28   int fd;
29 )
30 
31 static void set_log_level(int level)
32 {
33   if (FLAG(s)) klogctl(8, 0, level);
34   else {
35     FILE *fptr = xfopen("/proc/sys/kernel/printk", "w");
36 
37     fprintf(fptr, "%u\n", level);
38     fclose(fptr);
39   }
40 }
41 
handle_signal(int sig)42 static void handle_signal(int sig)
43 {
44   if (FLAG(s)) {
45     klogctl(7, 0, 0);
46     klogctl(0, 0, 0);
47   } else {
48     set_log_level(7); // TODO: hardwired? Old value...?
49     xclose(TT.fd);
50   }
51   syslog(LOG_NOTICE, "KLOGD: Daemon exiting......");
52 
53   toys.exitval = 1;
54   xexit();
55 }
56 
57 // Read kernel ring buffer in local buff and keep track of
58 // "used" amount to track next read to start.
klogd_main(void)59 void klogd_main(void)
60 {
61   int prio, size, used = 0;
62   char *start, *line_start;
63 
64   if (!FLAG(n) xvdaemon();
65   sigatexit(handle_signal);
66   if (FLAG(c)) set_log_level(TT.level);    //set log level
67 
68   if (FLAG(s)) klogctl(1, 0, 0);
69   else TT.fd = xopenro("/proc/kmsg"); //_PATH_KLOG in paths.h
70   syslog(LOG_NOTICE, "KLOGD: started with %s as log source\n",
71     FLAG(s) ? "Kernel ring buffer" : "/proc/kmsg");
72   openlog("Kernel", 0, LOG_KERN);    //open connection to system logger..
73 
74   for (;;) {
75     start = toybuf + used; //start updated for re-read.
76     size = sizeof(toybuf)-used-1;
77     if (FLAG(s)) size = klogctl(2, start, size);
78     else size = xread(TT.fd, start, size);
79     if (size < 0) perror_exit("error reading file:");
80     start[size] = 0;
81     if (used) start = toybuf;
82     while (start) {
83       if ((line_start = strsep(&start, "\n")) && start) used = 0;
84       else {      //Incomplete line, copy it to start of buff.
85         used = strlen(line_start);
86         strcpy(toybuf, line_start);
87         if (used < (sizeof(toybuf) - 1)) break;
88         used = 0; //we have buffer full, log it as it is.
89       }
90       prio = LOG_INFO;  //we dont know priority, mark it INFO
91       if (*line_start == '<') {  //we have new line to syslog
92         line_start++;
93         if (line_start) prio = strtoul(line_start, &line_start, 10);
94         if (*line_start == '>') line_start++;
95       }
96       if (*line_start) syslog(prio, "%s", line_start);
97     }
98   }
99 }
100