diff options
Diffstat (limited to 'libc/misc')
-rw-r--r-- | libc/misc/syslog/syslog.c | 107 |
1 files changed, 59 insertions, 48 deletions
diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c index 794c0c17f..b10a55615 100644 --- a/libc/misc/syslog/syslog.c +++ b/libc/misc/syslog/syslog.c @@ -80,22 +80,25 @@ #include <signal.h> - #include <bits/uClibc_mutex.h> -__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); + +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); +/* !glibc_compat: glibc uses argv[0] by default + * (default: if there was no openlog or if openlog passed NULL), + * not string "syslog" + */ +static const char *LogTag = "syslog"; /* string to tag the entry with */ static int LogFile = -1; /* fd for log */ static smalluint connected; /* have done connect */ -/* all bits in option argument for openlog() fit in 8 bits */ -static smalluint LogStat = 0; /* status bits, set by openlog() */ -static const char *LogTag = "syslog"; /* string to tag the entry with */ -/* this fits in 8 bits too (LOG_LOCAL7 = 23<<3 = 184), - * but NB: LOG_FACMASK is bigger (= 0x03f8 = 127<<3) for some strange reason. - * Oh well. */ -static int LogFacility = LOG_USER;/* default facility code */ -/* bits mask of priorities (eight prios - 8 bits is enough) */ -static smalluint LogMask = 0xff; /* mask of priorities to be logged */ +/* all bits in option argument for openlog fit in 8 bits */ +static smalluint LogStat = 0; /* status bits, set by openlog */ +/* default facility code if openlog is not called */ +/* (this fits in 8 bits even without >> 3 shift, but playing extra safe) */ +static smalluint LogFacility = LOG_USER >> 3; +/* bits mask of priorities to be logged (eight prios - 8 bits is enough) */ +static smalluint LogMask = 0xff; /* AF_UNIX address of local logger (we use struct sockaddr * instead of struct sockaddr_un since "/dev/log" is small enough) */ static const struct sockaddr SyslogAddr = { @@ -115,45 +118,46 @@ closelog_intern(int sig) if (sig == 0) { /* called from closelog()? - reset to defaults */ LogStat = 0; LogTag = "syslog"; - LogFacility = LOG_USER; + LogFacility = LOG_USER >> 3; LogMask = 0xff; } } -/* - * OPENLOG -- open system log - */ -void -openlog(const char *ident, int logstat, int logfac) +static void +openlog_intern(const char *ident, int logstat, int logfac) { + int fd; int logType = SOCK_DGRAM; - __UCLIBC_MUTEX_LOCK(mylock); - if (ident != NULL) LogTag = ident; LogStat = logstat; - if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) - LogFacility = logfac; - if (LogFile == -1) { -retry: - if (LogStat & LOG_NDELAY) { - if ((LogFile = socket(AF_UNIX, logType, 0)) == -1) { - goto DONE; + /* (we were checking also for logfac != 0, but it breaks + * openlog(xx, LOG_KERN) since LOG_KERN == 0) */ + if ((logfac & ~LOG_FACMASK) == 0) /* if we don't have invalid bits */ + LogFacility = (unsigned)logfac >> 3; + + fd = LogFile; + if (fd == -1) { + retry: + if (logstat & LOG_NDELAY) { + LogFile = fd = socket(AF_UNIX, logType, 0); + if (fd == -1) { + return; } - fcntl(LogFile, F_SETFD, FD_CLOEXEC); + fcntl(fd, F_SETFD, FD_CLOEXEC); /* We don't want to block if e.g. syslogd is SIGSTOPed */ - fcntl(LogFile, F_SETFL, O_NONBLOCK | fcntl(LogFile, F_GETFL)); + fcntl(fd, F_SETFL, O_NONBLOCK | fcntl(fd, F_GETFL)); } } - if (LogFile != -1 && !connected) { - if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) != -1) { + if (fd != -1 && !connected) { + if (connect(fd, &SyslogAddr, sizeof(SyslogAddr)) != -1) { connected = 1; } else { - if (LogFile != -1) { - close(LogFile); - LogFile = -1; + if (fd != -1) { + close(fd); + LogFile = fd = -1; } if (logType == SOCK_DGRAM) { logType = SOCK_STREAM; @@ -161,8 +165,16 @@ retry: } } } +} -DONE: +/* + * OPENLOG -- open system log + */ +void +openlog(const char *ident, int logstat, int logfac) +{ + __UCLIBC_MUTEX_LOCK(mylock); + openlog_intern(ident, logstat, logfac); __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_def(openlog) @@ -180,25 +192,24 @@ vsyslog(int pri, const char *fmt, va_list ap) int fd, saved_errno; int rc; char tbuf[1024]; /* syslogd is unable to handle longer messages */ - struct sigaction action, oldaction; - memset(&action, 0, sizeof(action)); - action.sa_handler = closelog_intern; - sigaction(SIGPIPE, &action, &oldaction); + /* Just throw out this message if pri has bad bits. */ + if ((pri & ~(LOG_PRIMASK|LOG_FACMASK)) != 0) + return; saved_errno = errno; __UCLIBC_MUTEX_LOCK(mylock); - /* See if we should just throw out this message. */ - if (!(LogMask & LOG_MASK(LOG_PRI(pri))) || (pri &~ (LOG_PRIMASK|LOG_FACMASK))) + /* See if we should just throw out this message according to LogMask. */ + if ((LogMask & LOG_MASK(LOG_PRI(pri))) == 0) goto getout; if (LogFile < 0 || !connected) - openlog(LogTag, LogStat | LOG_NDELAY, 0); + openlog_intern(NULL, LogStat | LOG_NDELAY, LOG_USER); /* Set default facility if none specified. */ if ((pri & LOG_FACMASK) == 0) - pri |= LogFacility; + pri |= ((int)LogFacility << 3); /* Build the message. We know the starting part of the message can take * no longer than 64 characters plus length of the LogTag. So it's @@ -206,7 +217,7 @@ vsyslog(int pri, const char *fmt, va_list ap) */ (void)time(&now); stdp = p = tbuf + sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); - if (LogTag) { + /*if (LogTag) - always true */ { if (strlen(LogTag) < sizeof(tbuf) - 64) p += sprintf(p, "%s", LogTag); else @@ -214,7 +225,7 @@ vsyslog(int pri, const char *fmt, va_list ap) } if (LogStat & LOG_PID) p += sprintf(p, "[%d]", getpid()); - if (LogTag) { + /*if (LogTag) - always true */ { *p++ = ':'; *p++ = ' '; } @@ -253,10 +264,11 @@ vsyslog(int pri, const char *fmt, va_list ap) /* Output the message to the local logger using NUL as a message delimiter. */ p = tbuf; - *last_chr = 0; + *last_chr = '\0'; if (LogFile >= 0) { do { - rc = write(LogFile, p, last_chr + 1 - p); + /* can't just use write, it can result in SIGPIPE */ + rc = send(LogFile, p, last_chr + 1 - p, MSG_NOSIGNAL); if (rc < 0) { /* I don't think looping forever on EAGAIN is a good idea. * Imagine that syslogd is SIGSTOPed... */ @@ -288,9 +300,8 @@ vsyslog(int pri, const char *fmt, va_list ap) (void)close(fd); } -getout: + getout: __UCLIBC_MUTEX_UNLOCK(mylock); - sigaction(SIGPIPE, &oldaction, NULL); } libc_hidden_def(vsyslog) |