- 论坛徽章:
- 0
|
源代码分析
#include
#include
#include
#include
#include
#if 0
#include "syslog.h"
#include "pathnames.h"
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define _PATH_LOGNAME "/dev/log"
/* 日志文件句柄
* 文件句柄是全局的,存在于整理应用程序的生命周期
*/
static int LogFile = -1; /* fd for log */
static int connected; /* have done connect */
static int LogStat = 0; /* status bits, set by openlog() */
static const char *LogTag = "syslog"; /* string to tag the entry with */
static int LogFacility = LOG_USER; /* default facility code */
void
syslog(int pri, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsyslog(pri, fmt, ap);
va_end(ap);
}
void
vsyslog(pri, fmt, ap)
int pri;
const char *fmt;
va_list ap;
{
register int cnt;
register char *p;
time_t now;
int fd, saved_errno;
int result;
char tbuf[2048], fmt_cpy[1024], *stdp = (char *) 0;
saved_errno = errno;
/* see if we should just throw out this message */
/* 如果这个消息异常,则退出*/
if (!LOG_MASK(LOG_PRI(pri)) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
return;
/* 判断是否打开日志文件, 如果没有, 则打开日志 */
if (LogFile %.15s 表示消息级别以及时间 */
(void)sprintf(tbuf, "%.15s ", pri, ctime(&now) + 4);
/* 移动到字符串尾 */
for (p = tbuf; *p; ++p);
if (LogStat & LOG_PERROR)
stdp = p;
if (LogTag) {
/* 如果存在标签,则添加标签到字符串尾 */
(void)strcpy(p, LogTag);
for (; *p; ++p);
}
if (LogStat & LOG_PID) {
/* 如果要添加进程ID,则添加进程ID到字符串尾*/
(void)sprintf(p, "[%d]", getpid());
for (; *p; ++p);
}
if (LogTag) {
/* 如果存在标签, 则添加':'和空格*/
*p++ = ':';
*p++ = ' ';
}
/* substitute error message for %m */
/* 用错误信息替换 %m */
{
register char ch, *t1, *t2;
char *strerror();
for (t1 = fmt_cpy;
(ch = *fmt) != '\0' && t1iov_base = stdp;
v->iov_len = cnt - (stdp - tbuf);
++v;
v->iov_base = "\n";
v->iov_len = 1;
(void)writev(2, iov, 2);
}
/* output the message to the local logger */
/* 输出消息到本地的日志服务器 */
result = write(LogFile, tbuf, cnt + 1);
if (result == -1
&& (errno == ECONNRESET || errno == ENOTCONN || errno == ECONNREFUSED)) {
closelog();
openlog(LogTag, LogStat | LOG_NDELAY, LogFacility);
result = write(LogFile, tbuf, cnt + 1);
}
if (result >= 0 || !(LogStat&LOG_CONS))
return;
/*
* output the message to the console; don't worry about
* blocking, if console blocks everything will.
*/
if ((fd = open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) ') + 1;
(void)write(fd, p, cnt - (p - tbuf));
(void)close(fd);
}
#ifndef TESTING
static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
#endif
/*
* OPENLOG -- open system log
*/
void
openlog(ident, logstat, logfac)
const char *ident;
int logstat, logfac;
{
if (ident != NULL)
LogTag = ident;
LogStat = logstat;
#ifdef ALLOW_KERNEL_LOGGING
if ((logfac &~ LOG_FACMASK) == 0)
#else
if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
#endif
LogFacility = logfac;
#ifndef TESTING
if (LogFile == -1) {
SyslogAddr.sa_family = AF_UNIX;
strncpy(SyslogAddr.sa_data, _PATH_LOGNAME,
sizeof(SyslogAddr.sa_data));
if (LogStat & LOG_NDELAY) {
LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
/* fcntl(LogFile, F_SETFD, 1); */
}
}
if (LogFile != -1 && !connected &&
connect(LogFile, &SyslogAddr, sizeof(SyslogAddr.sa_family)+
strlen(SyslogAddr.sa_data)) != -1)
#else
LogFile = fileno(stdout);
#endif
connected = 1;
}
/*
* CLOSELOG -- close the system log
*/
void
closelog()
{
#ifndef TESTING
(void) close(LogFile);
#endif
LogFile = -1;
connected = 0;
}
static int LogMask = 0xff; /* mask of priorities to be logged */
/*
* SETLOGMASK -- set the log mask level
*/
int
setlogmask(pmask)
int pmask;
{
int omask;
omask = LogMask;
if (pmask != 0)
LogMask = pmask;
return (omask);
}
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/69931/showart_734185.html |
|