📄 klogd.c
字号:
int sig;{ Terminate(); return;}void reload_daemon(sig) int sig;{ change_state = 1; reload_symbols = 1; if ( sig == SIGUSR2 ) { ++reload_symbols; signal(SIGUSR2, reload_daemon); } else signal(SIGUSR1, reload_daemon); return;}static void Terminate(){ CloseLogSrc(); Syslog(LOG_INFO, "Kernel log daemon terminating."); sleep(1); if ( output_file != (FILE *) 0 ) fclose(output_file); closelog();#ifndef TESTING (void) remove_pid(PidFile);#endif exit(1);}static void SignalDaemon(sig) int sig;{#ifndef TESTING auto int pid = check_pid(PidFile); kill(pid, sig);#else kill(getpid(), sig);#endif return;}static void ReloadSymbols(){ if (symbol_lookup) { if ( reload_symbols > 1 ) InitKsyms(symfile); InitMsyms(); } reload_symbols = change_state = 0; return;}static void ChangeLogging(void){ /* Terminate kernel logging. */ if ( terminate == 1 ) Terminate(); /* Indicate that something is happening. */ Syslog(LOG_INFO, "klogd %s.%s, ---------- state change ----------\n", \ VERSION, PATCHLEVEL); /* Reload symbols. */ if ( reload_symbols > 0 ) { ReloadSymbols(); return; } /* Stop kernel logging. */ if ( caught_TSTP == 1 ) { CloseLogSrc(); logsrc = none; change_state = 0; return; } /* * The rest of this function is responsible for restarting * kernel logging after it was stopped. * * In the following section we make a decision based on the * kernel log state as to what is causing us to restart. Somewhat * groady but it keeps us from creating another static variable. */ if ( logsrc != none ) { Syslog(LOG_INFO, "Kernel logging re-started after SIGSTOP."); change_state = 0; return; } /* Restart logging. */ logsrc = GetKernelLogSrc(); change_state = 0; return;}static enum LOGSRC GetKernelLogSrc(void){ auto struct stat sb; /* Set level of kernel console messaging.. */ if ( (console_log_level != -1) && (ksyslog(8, NULL, console_log_level) < 0) && \ (errno == EINVAL) ) { /* * An invalid arguement error probably indicates that * a pre-0.14 kernel is being run. At this point we * issue an error message and simply shut-off console * logging completely. */ Syslog(LOG_WARNING, "Cannot set console log level - disabling " "console output."); } /* * First do a stat to determine whether or not the proc based * file system is available to get kernel messages from. */ if ( use_syscall || ((stat(_PATH_KLOG, &sb) < 0) && (errno == ENOENT)) ) { /* Initialize kernel logging. */ ksyslog(1, NULL, 0);#ifdef DEBRELEASE Syslog(LOG_INFO, "klogd %s.%s#%s, log source = ksyslog " "started.", VERSION, PATCHLEVEL, DEBRELEASE);#else Syslog(LOG_INFO, "klogd %s.%s, log source = ksyslog " "started.", VERSION, PATCHLEVEL);#endif return(kernel); }#ifndef TESTING if ( (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 ) { fprintf(stderr, "klogd: Cannot open proc file system, " \ "%d - %s.\n", errno, strerror(errno)); ksyslog(7, NULL, 0); exit(1); }#else kmsg = fileno(stdin);#endif#ifdef DEBRELEASE Syslog(LOG_INFO, "klogd %s.%s#%s, log source = %s started.", \ VERSION, PATCHLEVEL, DEBRELEASE, _PATH_KLOG);#else Syslog(LOG_INFO, "klogd %s.%s, log source = %s started.", \ VERSION, PATCHLEVEL, _PATH_KLOG);#endif return(proc);}extern void Syslog(int priority, char *fmt, ...){ va_list ap; char *argl; if ( debugging ) { fputs("Logging line:\n", stderr); fprintf(stderr, "\tLine: %s\n", fmt); fprintf(stderr, "\tPriority: %d\n", priority); } /* Handle output to a file. */ if ( output_file != (FILE *) 0 ) { va_start(ap, fmt); vfprintf(output_file, fmt, ap); va_end(ap); fputc('\n', output_file); fflush(output_file); if (!one_shot) fsync(fileno(output_file)); return; } /* Output using syslog. */ if (!strcmp(fmt, "%s")) { va_start(ap, fmt); argl = va_arg(ap, char *); if (argl[0] == '<' && argl[1] && argl[2] == '>') { switch ( argl[1] ) { case '0': priority = LOG_EMERG; break; case '1': priority = LOG_ALERT; break; case '2': priority = LOG_CRIT; break; case '3': priority = LOG_ERR; break; case '4': priority = LOG_WARNING; break; case '5': priority = LOG_NOTICE; break; case '6': priority = LOG_INFO; break; case '7': default: priority = LOG_DEBUG; } argl += 3; } syslog(priority, fmt, argl); va_end(ap);#ifdef TESTING putchar('\n');#endif return; } va_start(ap, fmt); vsyslog(priority, fmt, ap); va_end(ap);#ifdef TESTING printf ("\n");#endif return;}/* * Copy characters from ptr to line until a char in the delim * string is encountered or until min( space, len ) chars have * been copied. * * Returns the actual number of chars copied. */static int copyin( char *line, int space, const char *ptr, int len, const char *delim ){ auto int i; auto int count; count = len < space ? len : space; for(i=0; i<count && !strchr(delim, *ptr); i++ ) { *line++ = *ptr++; } return( i );}/* * Messages are separated by "\n". Messages longer than * LOG_LINE_LENGTH are broken up. * * Kernel symbols show up in the input buffer as : "[<aaaaaa>]", * where "aaaaaa" is the address. These are replaced with * "[symbolname+offset/size]" in the output line - symbolname, * offset, and size come from the kernel symbol table. * * If a kernel symbol happens to fall at the end of a message close * in length to LOG_LINE_LENGTH, the symbol will not be expanded. * (This should never happen, since the kernel should never generate * messages that long. * * To preserve the original addresses, lines containing kernel symbols * are output twice. Once with the symbols converted and again with the * original text. Just in case somebody wants to run their own Oops * analysis on the syslog, e.g. ksymoops. */static void LogLine(char *ptr, int len){ enum parse_state_enum { PARSING_TEXT, PARSING_SYMSTART, /* at < */ PARSING_SYMBOL, PARSING_SYMEND /* at ] */ }; static char line_buff[LOG_LINE_LENGTH]; static char *line =line_buff; static enum parse_state_enum parse_state = PARSING_TEXT; static int space = sizeof(line_buff)-1; static char *sym_start; /* points at the '<' of a symbol */ auto int delta = 0; /* number of chars copied */ auto int symbols_expanded = 0; /* 1 if symbols were expanded */ auto int skip_symbol_lookup = 0; /* skip symbol lookup on this pass */ auto char *save_ptr = ptr; /* save start of input line */ auto int save_len = len; /* save length at start of input line */ while( len > 0 ) { if( space == 0 ) /* line buffer is full */ { /* ** Line too long. Start a new line. */ *line = 0; /* force null terminator */ if ( debugging ) { fputs("Line buffer full:\n", stderr); fprintf(stderr, "\tLine: %s\n", line); } Syslog( LOG_INFO, "%s", line_buff ); line = line_buff; space = sizeof(line_buff)-1; parse_state = PARSING_TEXT; symbols_expanded = 0; skip_symbol_lookup = 0; save_ptr = ptr; save_len = len; } switch( parse_state ) { case PARSING_TEXT: delta = copyin( line, space, ptr, len, "\n[" ); line += delta; ptr += delta; space -= delta; len -= delta; if( space == 0 || len == 0 ) { break; /* full line_buff or end of input buffer */ } if( *ptr == '\0' ) /* zero byte */ { ptr++; /* skip zero byte */ space -= 1; len -= 1; break; } if( *ptr == '\n' ) /* newline */ { ptr++; /* skip newline */ space -= 1; len -= 1; *line = 0; /* force null terminator */ Syslog( LOG_INFO, "%s", line_buff ); line = line_buff; space = sizeof(line_buff)-1; if (symbols_twice) { if (symbols_expanded) { /* reprint this line without symbol lookup */ symbols_expanded = 0; skip_symbol_lookup = 1; ptr = save_ptr; len = save_len; } else { skip_symbol_lookup = 0; save_ptr = ptr; save_len = len; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -