diff options
| author | Austin Foxley <austinf@cetoncorp.com> | 2009-12-15 19:19:39 -0800 | 
|---|---|---|
| committer | Austin Foxley <austinf@cetoncorp.com> | 2009-12-15 19:35:37 -0800 | 
| commit | fae10d41d1262170f272bb5e183becd44ff94f66 (patch) | |
| tree | a58d4a5ef14f699c978520715a0798bff9a71239 | |
| parent | 2287f4337d86dce4d907f136b3dc29c1956515ab (diff) | |
| parent | 8cd420c223f1a39c01835189669928ea8df9d221 (diff) | |
Merge remote branch 'origin/master' into nptl
Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
| -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)  | 
