wget https://github.com/bminor/glibc/archive/refs/tags/glibc-2.17.zip

unzip glibc-2.17.zip

glibc-2.17
头文件

syslog.h

源文件 bits/syslog.h
源文件 syslog.c
syslog => __syslog_chk => __vsyslog_chk => __vsyslog_chk(...){lockif not connected "/dev/log"open connectsend dataif send failsreopen connecttry send againif send failedclose connectunlock
}

syslog 实例 logger

[root@localhost util-linux-2.23.2]# which logger
/usr/bin/logger
[root@localhost util-linux-2.23.2]# rpm -qf /usr/bin/logger
util-linux-2.23.2-65.el7_9.1.x86_64
[root@localhost util-linux-2.23.2]#
[root@localhost util-linux-2.23.2]# wget wget https://mirrors.aliyun.com/centos-vault/7.5.1804/os/Source/SPackages/util-linux-2.23.2-52.el7.src.rpm--2022-08-07 18:49:42--  http://wget/
Resolving wget (wget)... failed: Name or service not known.
wget: unable to resolve host address ‘wget’
--2022-08-07 18:50:02--  https://mirrors.aliyun.com/centos-vault/7.5.1804/os/Source/SPackages/util-linux-2.23.2-52.el7.src.rpm
Resolving mirrors.aliyun.com (mirrors.aliyun.com)... 121.14.152.235, 183.2.193.237, 183.2.193.235
Connecting to mirrors.aliyun.com (mirrors.aliyun.com)|121.14.152.235|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3808730 (3.6M) [application/x-rpm]
Saving to: ‘util-linux-2.23.2-52.el7.src.rpm’100%[==========================================================================================================================>] 3,808,730   2.93MB/s   in 1.2s   2022-08-07 18:50:19 (2.93 MB/s) - ‘util-linux-2.23.2-52.el7.src.rpm’ saved [3808730/3808730]FINISHED --2022-08-07 18:50:19--
Total wall clock time: 36s
Downloaded: 1 files, 3.6M in 1.2s (2.93 MB/s)
/** Copyright (c) 1983, 1993*    The Regents of the University of California.  All rights reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:* 1. Redistributions of source code must retain the above copyright*    notice, this list of conditions and the following disclaimer.* 2. Redistributions in binary form must reproduce the above copyright*    notice, this list of conditions and the following disclaimer in the*    documentation and/or other materials provided with the distribution.* 3. All advertising materials mentioning features or use of this software*    must display the following acknowledgement:*    This product includes software developed by the University of*  California, Berkeley and its contributors.* 4. Neither the name of the University nor the names of its contributors*    may be used to endorse or promote products derived from this software*    without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE* ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF* SUCH DAMAGE.** 1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>* - added Native Language Support* Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>* - fixed strerr(errno) in gettext calls*/#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <getopt.h>#include "c.h"
#include "closestream.h"
#include "nls.h"
#include "strutils.h"#define  SYSLOG_NAMES
#include <syslog.h>enum {TYPE_UDP = (1 << 1),TYPE_TCP = (1 << 2),ALL_TYPES = TYPE_UDP | TYPE_TCP
};static int decode(char *name, CODE *codetab)
{register CODE *c;if (isdigit(*name))return (atoi(name));for (c = codetab; c->c_name; c++)if (!strcasecmp(name, c->c_name))return (c->c_val);return -1;
}static int pencode(char *s)
{char *save;int fac, lev;for (save = s; *s && *s != '.'; ++s);if (*s) {*s = '\0';fac = decode(save, facilitynames);if (fac < 0)errx(EXIT_FAILURE, _("unknown facility name: %s."), save);*s++ = '.';}else {fac = LOG_USER;s = save;}lev = decode(s, prioritynames);if (lev < 0)errx(EXIT_FAILURE, _("unknown priority name: %s."), save);return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK));
}static int
unix_socket(const char *path, const int socket_type)
{int fd, i;static struct sockaddr_un s_addr;    /* AF_UNIX address of local logger */if (strlen(path) >= sizeof(s_addr.sun_path))errx(EXIT_FAILURE, _("openlog %s: pathname too long"), path);s_addr.sun_family = AF_UNIX;strcpy(s_addr.sun_path, path);for (i = 2; i; i--) {int st = -1;if (i == 2 && socket_type & TYPE_UDP)st = SOCK_DGRAM;if (i == 1 && socket_type & TYPE_TCP)st = SOCK_STREAM;if (st == -1 || (fd = socket(AF_UNIX, st, 0)) == -1)continue;if (connect(fd, (struct sockaddr *)&s_addr, sizeof(s_addr)) == -1) {close(fd);continue;}break;}if (i == 0)err(EXIT_FAILURE, _("socket %s"), path);return fd;
}static int
inet_socket(const char *servername, const char *port, const int socket_type)
{int fd, errcode, i;struct addrinfo hints, *res;const char *p = port;for (i = 2; i; i--) {memset(&hints, 0, sizeof(hints));if (i == 2 && socket_type & TYPE_UDP) {hints.ai_socktype = SOCK_DGRAM;if (port == NULL)p = "syslog";}if (i == 1 && socket_type & TYPE_TCP) {hints.ai_socktype = SOCK_STREAM;if (port == NULL)p = "syslog-conn";}if (hints.ai_socktype == 0)continue;hints.ai_family = AF_UNSPEC;errcode = getaddrinfo(servername, p, &hints, &res);if (errcode != 0)errx(EXIT_FAILURE, _("getaddrinfo %s:%s: %s"),servername, p, gai_strerror(errcode));if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {freeaddrinfo(res);continue;}if (connect(fd, res->ai_addr, res->ai_addrlen) == -1) {freeaddrinfo(res);close(fd);continue;}freeaddrinfo(res);break;}if (i == 0)errx(EXIT_FAILURE, _("failed to connect %s port %s"), servername, p);return fd;
}static void
mysyslog(int fd, int logflags, int pri, char *tag, char *msg) {char buf[1000], pid[30], *cp, *tp;time_t now;if (fd > -1) {if (logflags & LOG_PID)snprintf (pid, sizeof(pid), "[%d]", getpid());elsepid[0] = 0;if (tag)cp = tag;else {cp = getlogin();if (!cp)cp = "<someone>";}(void)time(&now);tp = ctime(&now)+4;snprintf(buf, sizeof(buf), "<%d>%.15s %.200s%s: %.400s",pri, tp, cp, pid, msg);if (write(fd, buf, strlen(buf)+1) < 0)return; /* error */}
}static void __attribute__ ((__noreturn__)) usage(FILE *out)
{fputs(_("\nUsage:\n"), out);fprintf(out,_(" %s [options] [message]\n"), program_invocation_short_name);fputs(_("\nOptions:\n"), out);fputs(_(" -T, --tcp             use TCP only\n"), out);fputs(_(" -d, --udp             use UDP only\n"" -i, --id              log the process ID too\n"" -f, --file <file>     log the contents of this file\n"" -h, --help            display this help text and exit\n"), out);fputs(_(" -n, --server <name>   write to this remote syslog server\n"" -P, --port <number>   use this UDP port\n"" -p, --priority <prio> mark given message with this priority\n"" -s, --stderr          output message to standard error as well\n"), out);fputs(_(" -t, --tag <tag>       mark every line with this tag\n"" -u, --socket <socket> write to this Unix socket\n"" -V, --version         output version information and exit\n\n"), out);exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}/** logger -- read and log utility**   Reads from an input and arranges to write the result on the system* log.*/
int
main(int argc, char **argv) {int ch, logflags, pri;char *tag, buf[1024];char *usock = NULL;char *server = NULL;char *port = NULL;int LogSock = -1, socket_type = ALL_TYPES;static const struct option longopts[] = {{ "id",     no_argument,        0, 'i' },{ "stderr",    no_argument,        0, 's' },{ "file",  required_argument,  0, 'f' },{ "priority",  required_argument,  0, 'p' },{ "tag",   required_argument,  0, 't' },{ "socket",    required_argument,  0, 'u' },{ "udp",   no_argument,        0, 'd' },{ "tcp",   no_argument,        0, 'T' },{ "server",    required_argument,  0, 'n' },{ "port",  required_argument,  0, 'P' },{ "version",   no_argument,        0, 'V' },{ "help",  no_argument,        0, 'h' },{ NULL,      0, 0, 0 }};setlocale(LC_ALL, "");bindtextdomain(PACKAGE, LOCALEDIR);textdomain(PACKAGE);atexit(close_stdout);tag = NULL;pri = LOG_NOTICE;logflags = 0;while ((ch = getopt_long(argc, argv, "f:ip:st:u:dTn:P:Vh",longopts, NULL)) != -1) {switch((char)ch) {case 'f':     /* file to log */if (freopen(optarg, "r", stdin) == NULL)err(EXIT_FAILURE, _("file %s"),optarg);break;case 'i':     /* log process id also */logflags |= LOG_PID;break;case 'p':     /* priority */pri = pencode(optarg);break;case 's':      /* log to standard error */logflags |= LOG_PERROR;break;case 't':        /* tag */tag = optarg;break;case 'u':        /* unix socket */usock = optarg;break;case 'd':socket_type = TYPE_UDP;break;case 'T':socket_type = TYPE_TCP;break;case 'n':server = optarg;break;case 'P':port = optarg;break;case 'V':printf(UTIL_LINUX_VERSION);exit(EXIT_SUCCESS);case 'h':usage(stdout);case '?':default:usage(stderr);}}argc -= optind;argv += optind;/* setup for logging */if (server)LogSock = inet_socket(server, port, socket_type);else if (usock)LogSock = unix_socket(usock, socket_type);elseopenlog(tag ? tag : getlogin(), logflags, 0);/* log input line if appropriate */if (argc > 0) {register char *p, *endp;size_t len;for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) {len = strlen(*argv);if (p + len > endp && p > buf) {if (!usock && !server)syslog(pri, "%s", buf);elsemysyslog(LogSock, logflags, pri, tag, buf);p = buf;}if (len > sizeof(buf) - 1) {if (!usock && !server)syslog(pri, "%s", *argv++);elsemysyslog(LogSock, logflags, pri, tag, *argv++);} else {if (p != buf)*p++ = ' ';memmove(p, *argv++, len);*(p += len) = '\0';}}if (p != buf) {if (!usock && !server)syslog(pri, "%s", buf);elsemysyslog(LogSock, logflags, pri, tag, buf);}} else {while (fgets(buf, sizeof(buf), stdin) != NULL) {/* glibc is buggy and adds an additional newline,so we have to remove it here until glibc is fixed */int len = strlen(buf);if (len > 0 && buf[len - 1] == '\n')buf[len - 1] = '\0';if (!usock && !server)syslog(pri, "%s", buf);elsemysyslog(LogSock, logflags, pri, tag, buf);}}if (!usock && !server)closelog();elseclose(LogSock);return EXIT_SUCCESS;
}

dmesg:  查看内核消息日志

/** dmesg.c -- Print out the contents of the kernel ring buffer** Copyright (C) 1993 Theodore Ts'o <tytso@athena.mit.edu>* Copyright (C) 2011 Karel Zak <kzak@redhat.com>** This program comes with ABSOLUTELY NO WARRANTY.*/
#include <linux/unistd.h>
#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <sys/klog.h>
#include <sys/syslog.h>
#include <sys/time.h>
#include <sys/sysinfo.h>
#include <ctype.h>
#include <time.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>#include "c.h"
#include "colors.h"
#include "nls.h"
#include "strutils.h"
#include "xalloc.h"
#include "widechar.h"
#include "all-io.h"
#include "bitops.h"
#include "closestream.h"
#include "optutils.h"
#include "mangle.h"
#include "pager.h"/* Close the log.  Currently a NOP. */
#define SYSLOG_ACTION_CLOSE          0
/* Open the log. Currently a NOP. */
#define SYSLOG_ACTION_OPEN           1
/* Read from the log. */
#define SYSLOG_ACTION_READ           2
/* Read all messages remaining in the ring buffer. (allowed for non-root) */
#define SYSLOG_ACTION_READ_ALL       3
/* Read and clear all messages remaining in the ring buffer */
#define SYSLOG_ACTION_READ_CLEAR     4
/* Clear ring buffer. */
#define SYSLOG_ACTION_CLEAR          5
/* Disable printk's to console */
#define SYSLOG_ACTION_CONSOLE_OFF    6
/* Enable printk's to console */
#define SYSLOG_ACTION_CONSOLE_ON     7
/* Set level of messages printed to console */
#define SYSLOG_ACTION_CONSOLE_LEVEL  8
/* Return number of unread characters in the log buffer */
#define SYSLOG_ACTION_SIZE_UNREAD    9
/* Return size of the log buffer */
#define SYSLOG_ACTION_SIZE_BUFFER   10/** Colors*/
#define DMESG_COLOR_SUBSYS  UL_COLOR_BROWN
#define DMESG_COLOR_TIME    UL_COLOR_GREEN
#define DMESG_COLOR_RELTIME UL_COLOR_BOLD_GREEN
#define DMESG_COLOR_ALERT   UL_COLOR_REVERSE UL_COLOR_RED
#define DMESG_COLOR_CRIT    UL_COLOR_BOLD_RED
#define DMESG_COLOR_ERR     UL_COLOR_RED
#define DMESG_COLOR_WARN    UL_COLOR_BOLD
#define DMESG_COLOR_SEGFAULT    UL_COLOR_HALFBRIGHT UL_COLOR_RED/** Priority and facility names*/
struct dmesg_name {const char *name;const char *help;
};/** Priority names -- based on sys/syslog.h*/
static const struct dmesg_name level_names[] =
{[LOG_EMERG]   = { "emerg", N_("system is unusable") },[LOG_ALERT]   = { "alert", N_("action must be taken immediately") },[LOG_CRIT]    = { "crit",  N_("critical conditions") },[LOG_ERR]     = { "err",   N_("error conditions") },[LOG_WARNING] = { "warn",  N_("warning conditions") },[LOG_NOTICE]  = { "notice",N_("normal but significant condition") },[LOG_INFO]    = { "info",  N_("informational") },[LOG_DEBUG]   = { "debug", N_("debug-level messages") }
};/** sys/syslog.h uses (f << 3) for all facility codes.* We want to use the codes as array idexes, so shift back...** Note that libc LOG_FAC() macro returns the base codes, not the* shifted code :-)*/
#define FAC_BASE(f) ((f) >> 3)static const struct dmesg_name facility_names[] =
{[FAC_BASE(LOG_KERN)]     = { "kern",     N_("kernel messages") },[FAC_BASE(LOG_USER)]     = { "user",     N_("random user-level messages") },[FAC_BASE(LOG_MAIL)]     = { "mail",     N_("mail system") },[FAC_BASE(LOG_DAEMON)]   = { "daemon",   N_("system daemons") },[FAC_BASE(LOG_AUTH)]     = { "auth",     N_("security/authorization messages") },[FAC_BASE(LOG_SYSLOG)]   = { "syslog",   N_("messages generated internally by syslogd") },[FAC_BASE(LOG_LPR)]      = { "lpr",      N_("line printer subsystem") },[FAC_BASE(LOG_NEWS)]     = { "news",     N_("network news subsystem") },[FAC_BASE(LOG_UUCP)]     = { "uucp",     N_("UUCP subsystem") },[FAC_BASE(LOG_CRON)]     = { "cron",     N_("clock daemon") },[FAC_BASE(LOG_AUTHPRIV)] = { "authpriv", N_("security/authorization messages (private)") },[FAC_BASE(LOG_FTP)]      = { "ftp",      N_("ftp daemon") },
};/* supported methods to read message buffer*/
enum {DMESG_METHOD_KMSG,    /* read messages from /dev/kmsg (default) */DMESG_METHOD_SYSLOG,    /* klogctl() buffer */DMESG_METHOD_MMAP /* mmap file with records (see --file) */
};struct dmesg_control {/* bit arrays -- see include/bitops.h */char levels[ARRAY_SIZE(level_names) / NBBY + 1];char facilities[ARRAY_SIZE(facility_names) / NBBY + 1];struct timeval lasttime;   /* last printed timestamp */struct tm   lasttm;     /* last localtime */time_t      boot_time;  /* system boot time */int       action;     /* SYSLOG_ACTION_* */int        method;     /* DMESG_METHOD_* */size_t      bufsize;    /* size of syslog buffer */int      kmsg;       /* /dev/kmsg file descriptor */ssize_t      kmsg_first_read;/* initial read() return code */char        kmsg_buf[BUFSIZ];/* buffer to read kmsg data *//** For the --file option we mmap whole file. The unnecessary (already* printed) pages are always unmapped. The result is that we have in* memory only the currently used page(s).*/char     *filename;char      *mmap_buff;size_t       pagesize;unsigned int   follow:1,   /* wait for new messages */raw:1,       /* raw mode */fltr_lev:1,   /* filter out by levels[] */fltr_fac:1, /* filter out by facilities[] */decode:1,   /* use "facility: level: " prefix */notime:1, /* don't print timestamp */delta:1,    /* show time deltas */reltime:1,    /* show human readable relative times */ctime:1,    /* show human readable time */pager:1,  /* pipe output into a pager */color:1;  /* colorize messages */
};struct dmesg_record {const char   *mesg;size_t        mesg_size;int       level;int       facility;struct timeval  tv;const char  *next;      /* buffer with next unparsed record */size_t        next_size;  /* size of the next buffer */
};#define INIT_DMESG_RECORD(_r)  do { \(_r)->mesg = NULL; \(_r)->mesg_size = 0; \(_r)->facility = -1; \(_r)->level = -1; \(_r)->tv.tv_sec = 0; \(_r)->tv.tv_usec = 0; \} while (0)static int read_kmsg(struct dmesg_control *ctl);static int set_level_color(int log_level, const char *mesg, size_t mesgsz)
{switch (log_level) {case LOG_ALERT:color_enable(DMESG_COLOR_ALERT);return 0;case LOG_CRIT:color_enable(DMESG_COLOR_CRIT);return 0;case LOG_ERR:color_enable(DMESG_COLOR_ERR);return 0;case LOG_WARNING:color_enable(DMESG_COLOR_WARN);return 0;default:break;}/* well, sometimes the messges contains important keywords, but in* non-warning/error messages*/if (memmem(mesg, mesgsz, "segfault at", 11)) {color_enable(DMESG_COLOR_SEGFAULT);return 0;}return 1;
}static void __attribute__((__noreturn__)) usage(FILE *out)
{size_t i;fputs(USAGE_HEADER, out);fprintf(out, _(" %s [options]\n"), program_invocation_short_name);fputs(USAGE_OPTIONS, out);fputs(_(" -C, --clear                 clear the kernel ring buffer\n"), out);fputs(_(" -c, --read-clear            read and clear all messages\n"), out);fputs(_(" -D, --console-off           disable printing messages to console\n"), out);fputs(_(" -d, --show-delta            show time delta between printed messages\n"), out);fputs(_(" -e, --reltime               show local time and time delta in readable format\n"), out);fputs(_(" -E, --console-on            enable printing messages to console\n"), out);fputs(_(" -F, --file <file>           use the file instead of the kernel log buffer\n"), out);fputs(_(" -f, --facility <list>       restrict output to defined facilities\n"), out);fputs(_(" -H, --human                 human readable output\n"), out);fputs(_(" -k, --kernel                display kernel messages\n"), out);fputs(_(" -L, --color                 colorize messages\n"), out);fputs(_(" -l, --level <list>          restrict output to defined levels\n"), out);fputs(_(" -n, --console-level <level> set level of messages printed to console\n"), out);fputs(_(" -P, --nopager               do not pipe output into a pager\n"), out);fputs(_(" -r, --raw                   print the raw message buffer\n"), out);fputs(_(" -S, --syslog                force to use syslog(2) rather than /dev/kmsg\n"), out);fputs(_(" -s, --buffer-size <size>    buffer size to query the kernel ring buffer\n"), out);fputs(_(" -T, --ctime                 show human readable timestamp (could be \n""                               inaccurate if you have used SUSPEND/RESUME)\n"), out);fputs(_(" -t, --notime                don't print messages timestamp\n"), out);fputs(_(" -u, --userspace             display userspace messages\n"), out);fputs(_(" -w, --follow                wait for new messages\n"), out);fputs(_(" -x, --decode                decode facility and level to readable string\n"), out);fputs(USAGE_SEPARATOR, out);fputs(USAGE_HELP, out);fputs(USAGE_VERSION, out);fputs(_("\nSupported log facilities:\n"), out);for (i = 0; i < ARRAY_SIZE(level_names); i++)fprintf(out, " %7s - %s\n",facility_names[i].name,_(facility_names[i].help));fputs(_("\nSupported log levels (priorities):\n"), out);for (i = 0; i < ARRAY_SIZE(level_names); i++)fprintf(out, " %7s - %s\n",level_names[i].name,_(level_names[i].help));fputs(USAGE_SEPARATOR, out);fprintf(out, USAGE_MAN_TAIL("dmesg(q)"));exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}/** LEVEL     ::= <number> | <name>*  <number> ::= @len is set:  number in range <0..N>, where N < ARRAY_SIZE(level_names)*           ::= @len not set: number in range <1..N>, where N <= ARRAY_SIZE(level_names)*  <name>   ::= case-insensitive text**  Note that @len argument is not set when parsing "-n <level>" command line*  option. The console_level is intepreted as "log level less than the value".**  For example "dmesg -n 8" or "dmesg -n debug" enables debug console log*  level by klogctl(SYSLOG_ACTION_CONSOLE_LEVEL, NULL, 8). The @str argument*  has to be parsed to number in range <1..8>.*/
static int parse_level(const char *str, size_t len)
{int offset = 0;if (!str)return -1;if (!len) {len = strlen(str);offset = 1;}errno = 0;if (isdigit(*str)) {char *end = NULL;long x = strtol(str, &end, 10) - offset;if (!errno && end && end > str && (size_t) (end - str) == len &&x >= 0 && (size_t) x < ARRAY_SIZE(level_names))return x + offset;} else {size_t i;for (i = 0; i < ARRAY_SIZE(level_names); i++) {const char *n = level_names[i].name;if (strncasecmp(str, n, len) == 0 && *(n + len) == '\0')return i + offset;}}if (errno)err(EXIT_FAILURE, _("failed to parse level '%s'"), str);errx(EXIT_FAILURE, _("unknown level '%s'"), str);return -1;
}/** FACILITY  ::= <number> | <name>*  <number> ::= number in range <0..N>, where N < ARRAY_SIZE(facility_names)*  <name>   ::= case-insensitive text*/
static int parse_facility(const char *str, size_t len)
{if (!str)return -1;if (!len)len = strlen(str);errno = 0;if (isdigit(*str)) {char *end = NULL;long x = strtol(str, &end, 10);if (!errno && end && end > str && (size_t) (end - str) == len &&x >= 0 && (size_t) x < ARRAY_SIZE(facility_names))return x;} else {size_t i;for (i = 0; i < ARRAY_SIZE(facility_names); i++) {const char *n = facility_names[i].name;if (strncasecmp(str, n, len) == 0 && *(n + len) == '\0')return i;}}if (errno)err(EXIT_FAILURE, _("failed to parse facility '%s'"), str);errx(EXIT_FAILURE, _("unknown facility '%s'"), str);return -1;
}/** Parses numerical prefix used for all messages in kernel ring buffer.** Priorities/facilities are encoded into a single 32-bit quantity, where the* bottom 3 bits are the priority (0-7) and the top 28 bits are the facility* (0-big number).** Note that the number has to end with '>' or ',' char.*/
static const char *parse_faclev(const char *str, int *fac, int *lev)
{long num;char *end = NULL;if (!str)return str;errno = 0;num = strtol(str, &end, 10);if (!errno && end && end > str) {*fac = LOG_FAC(num);*lev = LOG_PRI(num);if (*lev < 0 || (size_t) *lev > ARRAY_SIZE(level_names))*lev = -1;if (*fac < 0 || (size_t) *fac > ARRAY_SIZE(facility_names))*fac = -1;return end + 1;     /* skip '<' or ',' */}return str;
}/** Parses timestamp from syslog message prefix, expected format:**    seconds.microseconds]** the ']' is the timestamp field terminator.*/
static const char *parse_syslog_timestamp(const char *str0, struct timeval *tv)
{const char *str = str0;char *end = NULL;if (!str0)return str0;errno = 0;tv->tv_sec = strtol(str, &end, 10);if (!errno && end && *end == '.' && *(end + 1)) {str = end + 1;end = NULL;tv->tv_usec = strtol(str, &end, 10);}if (errno || !end || end == str || *end != ']')return str0;return end + 1;  /* skip ']' */
}/** Parses timestamp from /dev/kmsg, expected formats:**   microseconds,*  microseconds;** the ',' is fields separators and ';' items terminator (for the last item)*/
static const char *parse_kmsg_timestamp(const char *str0, struct timeval *tv)
{const char *str = str0;char *end = NULL;uint64_t usec;if (!str0)return str0;errno = 0;usec = strtoumax(str, &end, 10);if (!errno && end && (*end == ';' || *end == ',')) {tv->tv_usec = usec % 1000000;tv->tv_sec = usec / 1000000;} elsereturn str0;return end + 1;  /* skip separator */
}static double time_diff(struct timeval *a, struct timeval *b)
{return (a->tv_sec - b->tv_sec) + (a->tv_usec - b->tv_usec) / 1E6;
}static int get_syslog_buffer_size(void)
{int n = klogctl(SYSLOG_ACTION_SIZE_BUFFER, NULL, 0);return n > 0 ? n : 0;
}static time_t get_boot_time(void)
{struct sysinfo info;struct timeval tv;if (sysinfo(&info) != 0)warn(_("sysinfo failed"));else if (gettimeofday(&tv, NULL) != 0)warn(_("gettimeofday failed"));elsereturn tv.tv_sec -= info.uptime;return 0;
}/** Reads messages from regular file by mmap*/
static ssize_t mmap_file_buffer(struct dmesg_control *ctl, char **buf)
{struct stat st;int fd;if (!ctl->filename)return -1;fd = open(ctl->filename, O_RDONLY);if (fd < 0)err(EXIT_FAILURE, _("cannot open %s"), ctl->filename);if (fstat(fd, &st))err(EXIT_FAILURE, _("stat failed %s"), ctl->filename);*buf = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);if (*buf == MAP_FAILED)err(EXIT_FAILURE, _("cannot mmap: %s"), ctl->filename);ctl->mmap_buff = *buf;ctl->pagesize = getpagesize();close(fd);return st.st_size;
}/** Reads messages from kernel ring buffer by klogctl()*/
static ssize_t read_syslog_buffer(struct dmesg_control *ctl, char **buf)
{size_t sz;int rc = -1;if (ctl->bufsize) {sz = ctl->bufsize + 8;*buf = xmalloc(sz * sizeof(char));rc = klogctl(ctl->action, *buf, sz);} else {sz = 16392;while (1) {*buf = xmalloc(sz * sizeof(char));rc = klogctl(SYSLOG_ACTION_READ_ALL, *buf, sz);if (rc < 0)break;if ((size_t) rc != sz || sz > (1 << 28))break;free(*buf);*buf = NULL;sz *= 4;}if (rc > 0 && ctl->action == SYSLOG_ACTION_READ_CLEAR)rc = klogctl(SYSLOG_ACTION_READ_CLEAR, *buf, sz);}return rc;
}/** Top level function to read messages*/
static ssize_t read_buffer(struct dmesg_control *ctl, char **buf)
{ssize_t n = -1;switch (ctl->method) {case DMESG_METHOD_MMAP:n = mmap_file_buffer(ctl, buf);break;case DMESG_METHOD_SYSLOG:if (!ctl->bufsize)ctl->bufsize = get_syslog_buffer_size();n = read_syslog_buffer(ctl, buf);break;case DMESG_METHOD_KMSG:/** Since kernel 3.5.0*/n = read_kmsg(ctl);if (n == 0 && ctl->action == SYSLOG_ACTION_READ_CLEAR)n = klogctl(SYSLOG_ACTION_CLEAR, NULL, 0);break;}return n;
}static int fwrite_hex(const char *buf, size_t size, FILE *out)
{size_t i;for (i = 0; i < size; i++) {int rc = fprintf(out, "\\x%02x", buf[i]);if (rc < 0)return rc;}return 0;
}/** Prints to 'out' and non-printable chars are replaced with \x<hex> sequences.*/
static void safe_fwrite(const char *buf, size_t size, FILE *out)
{size_t i;
#ifdef HAVE_WIDECHARmbstate_t s;memset(&s, 0, sizeof (s));
#endiffor (i = 0; i < size; i++) {const char *p = buf + i;int rc, hex = 0;size_t len = 1;#ifdef HAVE_WIDECHARwchar_t wc;len = mbrtowc(&wc, p, size - i, &s);if (len == 0)              /* L'\0' */return;if (len == (size_t)-1 || len == (size_t)-2) {       /* invalid sequence */memset(&s, 0, sizeof (s));len = hex = 1;} else if (len > 1 && !iswprint(wc)) {   /* non-printable multibyte */hex = 1;}i += len - 1;
#elseif (!isprint((unsigned int) *p) &&!isspace((unsigned int) *p))        /* non-printable */hex = 1;
#endifif (hex)rc = fwrite_hex(p, len, out);elserc = fwrite(p, 1, len, out) != len;if (rc != 0)err(EXIT_FAILURE, _("write failed"));}
}static const char *skip_item(const char *begin, const char *end, const char *sep)
{while (begin < end) {int c = *begin++;if (c == '\0' || strchr(sep, c))break;}return begin;
}/** Parses one record from syslog(2) buffer*/
static int get_next_syslog_record(struct dmesg_control *ctl,struct dmesg_record *rec)
{size_t i;const char *begin = NULL;if (ctl->method != DMESG_METHOD_MMAP &&ctl->method != DMESG_METHOD_SYSLOG)return -1;if (!rec->next || !rec->next_size)return 1;INIT_DMESG_RECORD(rec);/** Unmap already printed file data from memory*/if (ctl->mmap_buff && (size_t) (rec->next - ctl->mmap_buff) > ctl->pagesize) {void *x = ctl->mmap_buff;ctl->mmap_buff += ctl->pagesize;munmap(x, ctl->pagesize);}for (i = 0; i < rec->next_size; i++) {const char *p = rec->next + i;const char *end = NULL;if (!begin)begin = p;if (i + 1 == rec->next_size) {end = p + 1;i++;} else if (*p == '\n' && *(p + 1) == '<')end = p;if (begin && !*begin)begin = NULL;   /* zero(s) at the end of the buffer? */if (!begin || !end)continue;if (end <= begin)continue;   /* error or empty line? */if (*begin == '<') {if (ctl->fltr_lev || ctl->fltr_fac || ctl->decode || ctl->color)begin = parse_faclev(begin + 1, &rec->facility,&rec->level);elsebegin = skip_item(begin, end, ">");}if (*begin == '[' && (*(begin + 1) == ' ' ||isdigit(*(begin + 1)))) {if (ctl->delta || ctl->ctime || ctl->reltime)begin = parse_syslog_timestamp(begin + 1, &rec->tv);else if (ctl->notime)begin = skip_item(begin, end, "]");if (begin < end && *begin == ' ')begin++;}rec->mesg = begin;rec->mesg_size = end - begin;rec->next_size -= end - rec->next;rec->next = rec->next_size > 0 ? end + 1 : NULL;if (rec->next_size > 0)rec->next_size--;return 0;}return 1;
}static int accept_record(struct dmesg_control *ctl, struct dmesg_record *rec)
{if (ctl->fltr_lev && (rec->facility < 0 ||!isset(ctl->levels, rec->level)))return 0;if (ctl->fltr_fac && (rec->facility < 0 ||!isset(ctl->facilities, rec->facility)))return 0;return 1;
}static void raw_print(struct dmesg_control *ctl, const char *buf, size_t size)
{int lastc = '\n';if (!ctl->mmap_buff) {/** Print whole ring buffer*/safe_fwrite(buf, size, stdout);lastc = buf[size - 1];} else {/** Print file in small chunks to save memory*/while (size) {size_t sz = size > ctl->pagesize ? ctl->pagesize : size;char *x = ctl->mmap_buff;safe_fwrite(x, sz, stdout);lastc = x[sz - 1];size -= sz;ctl->mmap_buff += sz;munmap(x, sz);}}if (lastc != '\n')putchar('\n');
}static struct tm *record_localtime(struct dmesg_control *ctl,struct dmesg_record *rec,struct tm *tm)
{time_t t = ctl->boot_time + rec->tv.tv_sec;return localtime_r(&t, tm);
}static char *record_ctime(struct dmesg_control *ctl,struct dmesg_record *rec,char *buf, size_t bufsiz)
{struct tm tm;record_localtime(ctl, rec, &tm);if (strftime(buf, bufsiz, "%a %b %e %H:%M:%S %Y", &tm) == 0)*buf = '\0';return buf;
}static char *short_ctime(struct tm *tm, char *buf, size_t bufsiz)
{if (strftime(buf, bufsiz, "%b%e %H:%M", tm) == 0)*buf = '\0';return buf;
}static double record_count_delta(struct dmesg_control *ctl,struct dmesg_record *rec)
{double delta = 0;if (timerisset(&ctl->lasttime))delta = time_diff(&rec->tv, &ctl->lasttime);ctl->lasttime = rec->tv;return delta;
}static const char *get_subsys_delimiter(const char *mesg, size_t mesg_size)
{const char *p = mesg;size_t sz = mesg_size;while (sz > 0) {const char *d = strnchr(p, sz, ':');if (!d)return NULL;sz -= d - p;if (sz) {if (isblank(*(d + 1)))return d;p = d + 1;}}return NULL;
}static void print_record(struct dmesg_control *ctl,struct dmesg_record *rec)
{char buf[256];int has_color = 0;const char *mesg;size_t mesg_size;if (!accept_record(ctl, rec))return;if (!rec->mesg_size) {putchar('\n');return;}/** compose syslog(2) compatible raw output -- used for /dev/kmsg for* backward compatibility with syslog(2) buffers only*/if (ctl->raw) {printf("<%d>[%5d.%06d] ",LOG_MAKEPRI(rec->facility, rec->level),(int) rec->tv.tv_sec,(int) rec->tv.tv_usec);goto mesg;}/** facility : priority :*/if (ctl->decode &&-1 < rec->level    && rec->level     < (int) ARRAY_SIZE(level_names) &&-1 < rec->facility && rec->facility  < (int) ARRAY_SIZE(facility_names))printf("%-6s:%-6s: ", facility_names[rec->facility].name,level_names[rec->level].name);/** [sec.usec <delta>] or [ctime <delta>]*/if (ctl->delta) {if (ctl->color)color_enable(DMESG_COLOR_TIME);if (ctl->ctime)printf("[%s ", record_ctime(ctl, rec, buf, sizeof(buf)));else if (ctl->notime)putchar('[');elseprintf("[%5d.%06d ", (int) rec->tv.tv_sec,(int) rec->tv.tv_usec);printf("<%12.06f>] ", record_count_delta(ctl, rec));if (ctl->color)color_disable();/** [ctime]*/} else if (ctl->ctime) {if (ctl->color)color_enable(DMESG_COLOR_TIME);printf("[%s] ", record_ctime(ctl, rec, buf, sizeof(buf)));if (ctl->color)color_disable();}/** [reltime]*/else if (ctl->reltime) {double delta;struct tm cur;record_localtime(ctl, rec, &cur);delta = record_count_delta(ctl, rec);if (cur.tm_min  != ctl->lasttm.tm_min ||cur.tm_hour != ctl->lasttm.tm_hour ||cur.tm_yday != ctl->lasttm.tm_yday) {if (ctl->color)color_enable(DMESG_COLOR_RELTIME);printf("[%s] ", short_ctime(&cur, buf, sizeof(buf)));} else {if (ctl->color)color_enable(DMESG_COLOR_TIME);if (delta < 10)printf("[  %+8.06f] ", delta);elseprintf("[ %+9.06f] ", delta);}if (ctl->color)color_disable();ctl->lasttm = cur;}/** In syslog output the timestamp is part of the message and we don't* parse the timestamp by default. We parse the timestamp only if* --show-delta or --ctime is specified.** In kmsg output we always parse the timesptamp, so we have to compose* the [sec.usec] string.*/if (ctl->method == DMESG_METHOD_KMSG &&!ctl->notime && !ctl->delta && !ctl->ctime && !ctl->reltime) {if (ctl->color)color_enable(DMESG_COLOR_TIME);printf("[%5d.%06d] ", (int) rec->tv.tv_sec, (int) rec->tv.tv_usec);if (ctl->color)color_disable();}mesg:mesg = rec->mesg;mesg_size = rec->mesg_size;/* Colorize output */if (ctl->color) {/* subsystem prefix */const char *subsys = get_subsys_delimiter(mesg, mesg_size);if (subsys) {color_enable(DMESG_COLOR_SUBSYS);safe_fwrite(mesg, subsys - mesg, stdout);color_disable();mesg_size -= subsys - mesg;mesg = subsys;}/* error, alert .. etc. colors */has_color = set_level_color(rec->level, mesg, mesg_size) == 0;safe_fwrite(mesg, mesg_size, stdout);if (has_color)color_disable();} elsesafe_fwrite(mesg, mesg_size, stdout);if (*(mesg + mesg_size - 1) != '\n')putchar('\n');
}/** Prints the 'buf' kernel ring buffer; the messages are filtered out according* to 'levels' and 'facilities' bitarrays.*/
static void print_buffer(struct dmesg_control *ctl,const char *buf, size_t size)
{struct dmesg_record rec = { .next = buf, .next_size = size };if (ctl->raw) {raw_print(ctl, buf, size);return;}while (get_next_syslog_record(ctl, &rec) == 0)print_record(ctl, &rec);
}static ssize_t read_kmsg_one(struct dmesg_control *ctl)
{ssize_t size;/* kmsg returns EPIPE if record was modified while reading */do {size = read(ctl->kmsg, ctl->kmsg_buf,sizeof(ctl->kmsg_buf) - 1);} while (size < 0 && errno == EPIPE);return size;
}static int init_kmsg(struct dmesg_control *ctl)
{int mode = O_RDONLY;if (!ctl->follow)mode |= O_NONBLOCK;ctl->kmsg = open("/dev/kmsg", mode);if (ctl->kmsg < 0)return -1;/** Seek after the last record available at the time* the last SYSLOG_ACTION_CLEAR was issued.** ... otherwise SYSLOG_ACTION_CLEAR will have no effect for kmsg.*/lseek(ctl->kmsg, 0, SEEK_DATA);/** Old kernels (<3.5) allow to successfully open /dev/kmsg for* read-only, but read() returns -EINVAL :-(((** Let's try to read the first record. The record is later processed in* read_kmsg().*/ctl->kmsg_first_read = read_kmsg_one(ctl);if (ctl->kmsg_first_read < 0) {close(ctl->kmsg);ctl->kmsg = -1;return -1;}return 0;
}/** /dev/kmsg record format:**     faclev,seqnum,timestamp[optional, ...];messgage\n*      TAGNAME=value*      ...** - fields are separated by ','* - last field is terminated by ';'**/
#define LAST_KMSG_FIELD(s)  (!s || !*s || *(s - 1) == ';')static int parse_kmsg_record(struct dmesg_control *ctl,struct dmesg_record *rec,char *buf,size_t sz)
{const char *p = buf, *end;if (sz == 0 || !buf || !*buf)return -1;end = buf + (sz - 1);INIT_DMESG_RECORD(rec);while (p < end && isspace(*p))p++;/* A) priority and facility */if (ctl->fltr_lev || ctl->fltr_fac || ctl->decode ||ctl->raw || ctl->color)p = parse_faclev(p, &rec->facility, &rec->level);elsep = skip_item(p, end, ",");if (LAST_KMSG_FIELD(p))goto mesg;/* B) sequence number */p = skip_item(p, end, ",;");if (LAST_KMSG_FIELD(p))goto mesg;/* C) timestamp */if (ctl->notime)p = skip_item(p, end, ",;");elsep = parse_kmsg_timestamp(p, &rec->tv);if (LAST_KMSG_FIELD(p))goto mesg;/* D) optional fields (ignore) */p = skip_item(p, end, ";");if (LAST_KMSG_FIELD(p))goto mesg;mesg:/* E) message text */rec->mesg = p;p = skip_item(p, end, "\n");if (!p)return -1;rec->mesg_size = p - rec->mesg;/** Kernel escapes non-printable characters, unfortuately kernel* definition of "non-printable" is too strict. On UTF8 console we can* print many chars, so let's decode from kernel.*/unhexmangle_to_buffer(rec->mesg, (char *) rec->mesg, rec->mesg_size + 1);/* F) message tags (ignore) */return 0;
}/** Note that each read() call for /dev/kmsg returns always one record. It means* that we don't have to read whole message buffer before the records parsing.** So this function does not compose one huge buffer (like read_syslog_buffer())* and print_buffer() is unnecessary. All is done in this function.** Returns 0 on success, -1 on error.*/
static int read_kmsg(struct dmesg_control *ctl)
{struct dmesg_record rec;ssize_t sz;if (ctl->method != DMESG_METHOD_KMSG || ctl->kmsg < 0)return -1;/** The very first read() call is done in kmsg_init() where we test* /dev/kmsg usability. The return code from the initial read() is* stored in ctl->kmsg_first_read;*/sz = ctl->kmsg_first_read;while (sz > 0) {*(ctl->kmsg_buf + sz) = '\0';   /* for debug messages */if (parse_kmsg_record(ctl, &rec,ctl->kmsg_buf, (size_t) sz) == 0)print_record(ctl, &rec);sz = read_kmsg_one(ctl);}return 0;
}int main(int argc, char *argv[])
{char *buf = NULL;int  c, nopager = 0;int  console_level = 0;int  klog_rc = 0;ssize_t n;static struct dmesg_control ctl = {.filename = NULL,.action = SYSLOG_ACTION_READ_ALL,.method = DMESG_METHOD_KMSG,.kmsg = -1,};static const struct option longopts[] = {{ "buffer-size",   required_argument, NULL, 's' },{ "clear",         no_argument,          NULL, 'C' },{ "color",         no_argument,         NULL, 'L' },{ "console-level", required_argument, NULL, 'n' },{ "console-off",   no_argument,       NULL, 'D' },{ "console-on",    no_argument,       NULL, 'E' },{ "decode",        no_argument,       NULL, 'x' },{ "file",          required_argument, NULL, 'F' },{ "facility",      required_argument, NULL, 'f' },{ "follow",        no_argument,       NULL, 'w' },{ "human",         no_argument,       NULL, 'H' },{ "help",          no_argument,         NULL, 'h' },{ "kernel",        no_argument,       NULL, 'k' },{ "level",         required_argument, NULL, 'l' },{ "syslog",        no_argument,       NULL, 'S' },{ "raw",           no_argument,       NULL, 'r' },{ "read-clear",    no_argument,         NULL, 'c' },{ "reltime",       no_argument,       NULL, 'e' },{ "show-delta",    no_argument,       NULL, 'd' },{ "ctime",         no_argument,       NULL, 'T' },{ "notime",        no_argument,       NULL, 't' },{ "nopager",       no_argument,       NULL, 'P' },{ "userspace",     no_argument,       NULL, 'u' },{ "version",       no_argument,         NULL, 'V' },{ NULL,            0, NULL, 0 }};static const ul_excl_t excl[] = { /* rows and cols in in ASCII order */{ 'C','D','E','c','n' }, /* clear,off,on,read-clear,level*/{ 'H','r' },          /* human, raw */{ 'L','r' },            /* color, raw */{ 'S','w' },            /* syslog,follow */{ 0 }};int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;setlocale(LC_ALL, "");bindtextdomain(PACKAGE, LOCALEDIR);textdomain(PACKAGE);atexit(close_stdout);while ((c = getopt_long(argc, argv, "CcDdEeF:f:HhkLl:n:iPrSs:TtuVwx",longopts, NULL)) != -1) {err_exclusive_options(c, longopts, excl, excl_st);switch (c) {case 'C':ctl.action = SYSLOG_ACTION_CLEAR;break;case 'c':ctl.action = SYSLOG_ACTION_READ_CLEAR;break;case 'D':ctl.action = SYSLOG_ACTION_CONSOLE_OFF;break;case 'd':ctl.delta = 1;break;case 'E':ctl.action = SYSLOG_ACTION_CONSOLE_ON;break;case 'e':ctl.reltime = 1;break;case 'F':ctl.filename = optarg;ctl.method = DMESG_METHOD_MMAP;break;case 'f':ctl.fltr_fac = 1;if (string_to_bitarray(optarg,ctl.facilities, parse_facility) < 0)return EXIT_FAILURE;break;case 'H':ctl.reltime = 1;ctl.color = 1;ctl.pager = 1;break;case 'h':usage(stdout);break;case 'k':ctl.fltr_fac = 1;setbit(ctl.facilities, FAC_BASE(LOG_KERN));break;case 'L':ctl.color = 1;break;case 'l':ctl.fltr_lev= 1;if (string_to_bitarray(optarg,ctl.levels, parse_level) < 0)return EXIT_FAILURE;break;case 'n':ctl.action = SYSLOG_ACTION_CONSOLE_LEVEL;console_level = parse_level(optarg, 0);break;case 'P':nopager = 1;break;case 'r':ctl.raw = 1;break;case 'S':ctl.method = DMESG_METHOD_SYSLOG;break;case 's':ctl.bufsize = strtou32_or_err(optarg,_("invalid buffer size argument"));if (ctl.bufsize < 4096)ctl.bufsize = 4096;break;case 'T':ctl.boot_time = get_boot_time();if (ctl.boot_time)ctl.ctime = 1;break;case 't':ctl.notime = 1;break;case 'u':ctl.fltr_fac = 1;for (n = 1; (size_t) n < ARRAY_SIZE(facility_names); n++)setbit(ctl.facilities, n);break;case 'V':printf(_("%s from %s\n"), program_invocation_short_name,PACKAGE_STRING);return EXIT_SUCCESS;case 'w':ctl.follow = 1;break;case 'x':ctl.decode = 1;break;case '?':default:usage(stderr);}}argc -= optind;argv += optind;if (argc > 1)usage(stderr);if (ctl.raw && (ctl.fltr_lev || ctl.fltr_fac || ctl.delta ||ctl.notime || ctl.ctime || ctl.decode))errx(EXIT_FAILURE, _("--raw can't be used together with level, ""facility, decode, delta, ctime or notime options"));if (ctl.notime && (ctl.ctime || ctl.reltime))errx(EXIT_FAILURE, _("--notime can't be used together with --ctime or --reltime"));if (ctl.reltime && ctl.ctime)errx(EXIT_FAILURE, _("--reltime can't be used together with --ctime "));if (ctl.reltime) {ctl.boot_time = get_boot_time();if (!ctl.boot_time)ctl.reltime = 0;}if (ctl.color)ctl.color = colors_init() ? 1 : 0;if (ctl.follow)nopager = 1;ctl.pager = nopager ? 0 : ctl.pager;if (ctl.pager)setup_pager();switch (ctl.action) {case SYSLOG_ACTION_READ_ALL:case SYSLOG_ACTION_READ_CLEAR:if (ctl.method == DMESG_METHOD_KMSG && init_kmsg(&ctl) != 0)ctl.method = DMESG_METHOD_SYSLOG;if (ctl.pager)setup_pager();n = read_buffer(&ctl, &buf);if (n > 0)print_buffer(&ctl, buf, n);if (!ctl.mmap_buff)free(buf);if (n < 0)err(EXIT_FAILURE, _("read kernel buffer failed"));if (ctl.kmsg >= 0)close(ctl.kmsg);break;case SYSLOG_ACTION_CLEAR:case SYSLOG_ACTION_CONSOLE_OFF:case SYSLOG_ACTION_CONSOLE_ON:klog_rc = klogctl(ctl.action, NULL, 0);break;case SYSLOG_ACTION_CONSOLE_LEVEL:klog_rc = klogctl(ctl.action, NULL, console_level);break;default:errx(EXIT_FAILURE, _("unsupported command"));break;}if (klog_rc)err(EXIT_FAILURE, _("klogctl failed"));return EXIT_SUCCESS;
}

syslog、logger、kmesg相关推荐

  1. 2、Flume1.7.0入门:安装、部署、及flume的案例

    一.什么是Flume? flume 作为 cloudera 开发的实时日志收集系统,受到了业界的认可与广泛应用. flume的特点: flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的 ...

  2. java log4j logback jcl_知识总结-Java日志框架Log4j、Log4j2、logback、slf4j、简介

    功能简介 上一篇介绍了为什么打印日志.什么时候打印日志以及怎么打印日志.本篇介绍下在项目开发中常见的日志组件以及关系. 先看一张图 接口:将所有日志实现适配到了一起,用统一的接口调用. 实现:目前主流 ...

  3. logging、hashlib、collections模块

    一.hashlib模块(加密模块) 1.什么叫hash:hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 , ...

  4. Log4j、Log4j 2、JUL、JCL 、SFL4J 、Logback 与 Lombok 的使用

    Log4J Log4j = Log for Java. Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.数据库等:我们也可以控制每一条 ...

  5. 大数据Hadoop、Hive、Kafka、Hbase、Spark等框架面经

    大数据组件 学习路线: 阶段1:学习绿色箭头的知识点: 阶段2:学习红色箭头的知识点: 阶段3:学习蓝色箭头的知识点: 1 Hadoop 1.1 Hadoop1.x与Hadoop2.x的区别 1.2 ...

  6. Flume中sources、channels、sinks的常用配置(多个案例)

    Flume中sources.channels.sinks的常用配置(多个案例) 文章目录 Flume中sources.channels.sinks的常用配置(多个案例) Flume基础及架构 案例1: ...

  7. Syslog 教程:工作原理、示例、最佳实践等

    Syslog 是用于从各种网络设备以特定格式发送和接收通知消息的标准.这些消息包括时间戳.事件消息.严重性.主机 IP 地址.诊断等.就其内置的严重性级别而言,它可以传达 0 级.紧急.5 级.警告. ...

  8. 一个高效、快速、稳定的PHP日志扩展。

    SeasLog An effective,fast,stable log extension for PHP @author Chitao.Gao [neeke@php.net] @交流群 31291 ...

  9. Flume1.5.0的安装、部署、简单应用(含伪分布式、与hadoop2.2.0、hbase0.96的案例)

    原文地址:http://www.cnblogs.com/lion.net/p/3903197.html 目录: 一.什么是Flume? 1)flume的特点 2)flume的可靠性 3)flume的可 ...

最新文章

  1. 机器学习01-定义、线性回归、梯度下降
  2. java session 生命周期_JavaWeb关于session生命周期的几种设置方法
  3. android壁纸居中,Android Launcher 如何实现壁纸居中
  4. qt 控件坐标系_Qt中,如何找准控件坐标
  5. 最常见到的runtime exception 异常
  6. 删除本地.svn文件
  7. c语言中除法取整6,关于C语言的除法与取整问题!?
  8. WA5320-C-EI无线接入点,WX2510H-F无线控制器设置WAPI
  9. Authentication—身份验证流程
  10. 【SoDiaoEditor电子病历编辑器】阶段性更新--新增复选框、日期控件、表格排版支持等--B/S架构...
  11. 苹果手表GPS和蜂窝有什么区别
  12. Revit二次开发--为管道添加标注
  13. 终于理解了VT虚拟化技术的作用!(内详)
  14. Geany 一些使用技巧
  15. k8s调度之亲和/反亲和
  16. 【每日论文】GenCo: Generative Co-training for Generative Adversarial Networks with Limited Data
  17. Android 开机动画(bootanimation)启动
  18. 案例研究:设计令人震撼的名片!
  19. 794. 有效的井字游戏
  20. 运 算 符 和 表 达式

热门文章

  1. 建筑储能相变材料:两种热性能标准测试方法比较
  2. 浪潮发布新型水冷服务器 可以快装移动式液冷集群
  3. 基于Matlab的图片压缩(超简单)
  4. 频分复用、时分复用和码分复用
  5. 中级程序员面试阿里失败总结
  6. 《品味大数据》的“魔力”
  7. 你知道为啥给JVM分配的内存越大,结果性能越差吗?
  8. python安装报错类型_解决安装python库时windows error5 报错的问题
  9. 福建警院计算机系老师,许发见(计算机与信息管理系)老师 - 福建警察学院 - 院校大全...
  10. 【医疗健康项目】传智健康项目(八)