42 |
int klogd_main(int argc UNUSED_PARAM, char **argv) |
int klogd_main(int argc UNUSED_PARAM, char **argv) |
43 |
{ |
{ |
44 |
int i = 0; |
int i = 0; |
45 |
char *start; |
char *opt_c; |
46 |
int opt; |
int opt; |
47 |
int used = 0; |
int used = 0; |
48 |
|
|
49 |
opt = getopt32(argv, "c:n", &start); |
opt = getopt32(argv, "c:n", &opt_c); |
50 |
if (opt & OPT_LEVEL) { |
if (opt & OPT_LEVEL) { |
51 |
/* Valid levels are between 1 and 8 */ |
/* Valid levels are between 1 and 8 */ |
52 |
i = xatou_range(start, 1, 8); |
i = xatou_range(opt_c, 1, 8); |
53 |
} |
} |
54 |
if (!(opt & OPT_FOREGROUND)) { |
if (!(opt & OPT_FOREGROUND)) { |
55 |
bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); |
bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); |
57 |
|
|
58 |
openlog("kernel", 0, LOG_KERN); |
openlog("kernel", 0, LOG_KERN); |
59 |
|
|
60 |
bb_signals(0 |
bb_signals(BB_FATAL_SIGS, klogd_signal); |
|
+ (1 << SIGINT) |
|
|
+ (1 << SIGTERM) |
|
|
, klogd_signal); |
|
61 |
signal(SIGHUP, SIG_IGN); |
signal(SIGHUP, SIG_IGN); |
62 |
|
|
63 |
/* "Open the log. Currently a NOP" */ |
/* "Open the log. Currently a NOP" */ |
73 |
while (1) { |
while (1) { |
74 |
int n; |
int n; |
75 |
int priority; |
int priority; |
76 |
|
char *start; |
77 |
|
|
78 |
/* "2 -- Read from the log." */ |
/* "2 -- Read from the log." */ |
79 |
n = klogctl(2, log_buffer + used, KLOGD_LOGBUF_SIZE-1 - used); |
start = log_buffer + used; |
80 |
|
n = klogctl(2, start, KLOGD_LOGBUF_SIZE-1 - used); |
81 |
if (n < 0) { |
if (n < 0) { |
82 |
if (errno == EINTR) |
if (errno == EINTR) |
83 |
continue; |
continue; |
85 |
errno); |
errno); |
86 |
break; |
break; |
87 |
} |
} |
88 |
log_buffer[used + n] = '\0'; |
start[n] = '\0'; |
89 |
|
|
90 |
/* klogctl buffer parsing modelled after code in dmesg.c */ |
/* klogctl buffer parsing modelled after code in dmesg.c */ |
|
start = &log_buffer[0]; |
|
|
|
|
91 |
/* Process each newline-terminated line in the buffer */ |
/* Process each newline-terminated line in the buffer */ |
92 |
|
start = log_buffer; |
93 |
while (1) { |
while (1) { |
94 |
char *newline = strchr(start, '\n'); |
char *newline = strchrnul(start, '\n'); |
95 |
|
|
96 |
if (!newline) { |
if (*newline == '\0') { |
97 |
/* This line is incomplete... */ |
/* This line is incomplete... */ |
98 |
if (start != log_buffer) { |
if (start != log_buffer) { |
99 |
/* move it to the front of the buffer */ |
/* move it to the front of the buffer */ |
100 |
overlapping_strcpy(log_buffer, start); |
overlapping_strcpy(log_buffer, start); |
101 |
|
used = newline - start; |
102 |
/* don't log it yet */ |
/* don't log it yet */ |
|
used = strlen(log_buffer); |
|
103 |
break; |
break; |
104 |
} |
} |
105 |
/* ...but buffer is full, so log it anyway */ |
/* ...but if buffer is full, log it anyway */ |
106 |
used = 0; |
used = 0; |
107 |
|
newline = NULL; |
108 |
} else { |
} else { |
109 |
*newline++ = '\0'; |
*newline++ = '\0'; |
110 |
} |
} |
118 |
priority = (*start - '0'); |
priority = (*start - '0'); |
119 |
start++; |
start++; |
120 |
} |
} |
121 |
if (*start == '>') { |
if (*start == '>') |
122 |
start++; |
start++; |
|
} |
|
123 |
} |
} |
124 |
|
/* Log (only non-empty lines) */ |
125 |
if (*start) |
if (*start) |
126 |
syslog(priority, "%s", start); |
syslog(priority, "%s", start); |
127 |
|
|
128 |
if (!newline) |
if (!newline) |
129 |
break; |
break; |
130 |
start = newline; |
start = newline; |