diff options
author | Ulrich Drepper <drepper@redhat.com> | 1996-12-07 03:30:25 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1996-12-07 03:30:25 +0000 |
commit | a18f587da5a0a91bcd1307ed0f122ca2ce994c15 (patch) | |
tree | 174cca5dd1f842dff255d6491ff6677ac7772eab /misc/syslog.c | |
parent | 6b612c67093292a99a336fae38e459ee00927d0f (diff) | |
download | glibc-a18f587da5a0a91bcd1307ed0f122ca2ce994c15.zip glibc-a18f587da5a0a91bcd1307ed0f122ca2ce994c15.tar.gz glibc-a18f587da5a0a91bcd1307ed0f122ca2ce994c15.tar.bz2 |
update from main archive 961206
Sat Dec 7 03:24:36 1996 Ulrich Drepper <drepper@cygnus.com>
* configure.in: Discard error message from test in test for
bash-2.0.
* io/getpw.c: Don't apply getcwd on user supplied buffer.
Instead always use temporary buffer and only copy the result.
Patch by HJ Lu.
* stdlib/canonicalize.c: Likewise.
* libio/fileops.c: Change comments according to libg++2.8b5.
* libio/iosetvbuf.c: Follow change in libg++-2.8b5 to clear
unbuffered flag.
Reported by HJ Lu.
* manual/nss.texi: Correct prototypes.
* misc/syslog.c: Make reentrant. Catch SIGPIPE signal to prevent
crash if syslog daemon is restarted.
* stdlib/rand_r.c: New file. Implementation of POSIX.2 function
rand_r.
* stdlib/Makefile (routines): Add rand_r.
* sysdeps/stub/libc-lock.h: Define __libc_lock_trylock and
__libc_mutex_lock.
* configure.in: Add --disable-sanity-check option.
* sysdeps/unix/sysv/linux/configure.in: If linuxthreads or
des-crypt are not available and --disbale-sanity-check is not
given abort with a message.
Thu Dec 5 19:19:53 1996 Richard Henderson <rth@tamu.edu>
* posix/glob.c: Tests against STDC_HEADERS should also test
__GNU_LIBRARY__.
Thu Dec 5 16:20:55 1996 Ulrich Drepper <drepper@cygnus.com>
* misc/err.c (vwarn): Set errno again before using %m format.
Thu Dec 5 10:14:05 1996 Andreas Jaeger <aj@arthur.pfalz.de>
* grp/grp.h: Add declaration of __getgrent_r.
* io/fts.c (fts_build): Remove "register" from variables dirbuf
and dp since their address is needed.
* sysdeps/posix/getcwd.c (__getcwd): Remove "register" from
variable d since d's address is needed.
* misc/tst-dirname.c (main): Provide prototype.
* misc/ioctltst.c (main): Dito.
* Makefile: Add gnu/lib-names.h to install-others before including
Makerules.
Wed Dec 4 16:00:09 1996 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/sys/socketvar.h: New file. Simply use
<sys/socket.h>.
* sysdeps/unix/sysv/linux/Dist: Add sys/socketvar.h.
* sysdeps/unix/sysv/linux/Makefile [$(subdir)=inet)]: Add
sys/socketvar.h to sysdep_headers.
since the value might be outside the range of the `long int'.
Diffstat (limited to 'misc/syslog.c')
-rw-r--r-- | misc/syslog.c | 92 |
1 files changed, 85 insertions, 7 deletions
diff --git a/misc/syslog.c b/misc/syslog.c index 9db16ca..205909e 100644 --- a/misc/syslog.c +++ b/misc/syslog.c @@ -49,6 +49,8 @@ static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94"; #include <time.h> #include <unistd.h> #include <stdlib.h> +#include <libc-lock.h> +#include <signal.h> #if __STDC__ #include <stdarg.h> @@ -65,6 +67,14 @@ static int LogFacility = LOG_USER; /* default facility code */ static int LogMask = 0xff; /* mask of priorities to be logged */ extern char *__progname; /* Program name, from crt0. */ +/* Define the lock. */ +__libc_lock_define_initialized (static, syslog_lock) + +static void openlog_internal(const char *, int, int); +static void closelog_internal(void); +static void sigpipe_handler (int); +static void cancel_handler (void *); + /* * syslog, vsyslog -- * print message on log file; output is intended for syslogd(8). @@ -103,6 +113,9 @@ vsyslog(pri, fmt, ap) char *buf = 0; size_t bufsize = 0; size_t prioff, msgoff; + struct sigaction action, oldaction; + struct sigaction *oldaction_ptr = NULL; + int sigpipe; #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID /* Check for invalid bits. */ @@ -163,9 +176,22 @@ vsyslog(pri, fmt, ap) (void)writev(STDERR_FILENO, iov, 2); } + /* Prepare for multiple users. We have to take care: open and + write are cancelation points. */ + __libc_cleanup_region_start (cancel_handler, &oldaction_ptr); + __libc_lock_lock (syslog_lock); + + /* Prepare for a broken connection. */ + memset (&action, 0, sizeof (action)); + action.sa_handler = sigpipe_handler; + sigemptyset (&action.sa_mask); + sigpipe = sigaction (SIGPIPE, &action, &oldaction); + if (sigpipe == 0) + oldaction_ptr = &oldaction; + /* Get connected, output the message to the local logger. */ if (!connected) - openlog(LogTag, LogStat | LOG_NDELAY, 0); + openlog_internal(LogTag, LogStat | LOG_NDELAY, 0); /* If we have a SOCK_STREAM connection, also send ASCII NUL as a record terminator. */ @@ -174,7 +200,7 @@ vsyslog(pri, fmt, ap) if (__send(LogFile, buf, bufsize, 0) < 0) { - closelog (); /* attempt re-open next time */ + closelog_internal (); /* attempt re-open next time */ /* * Output the message to the console; don't worry about blocking, * if console blocks everything will. Make sure the error reported @@ -188,15 +214,20 @@ vsyslog(pri, fmt, ap) } } + if (sigpipe == 0) + sigaction (SIGPIPE, &oldaction, (struct sigaction *) NULL); + + /* End of critical section. */ + __libc_cleanup_region_end (0); + __libc_lock_unlock (syslog_lock); + free (buf); } static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ -void -openlog(ident, logstat, logfac) - const char *ident; - int logstat, logfac; +static void +openlog_internal(const char *ident, int logstat, int logfac) { if (ident != NULL) LogTag = ident; @@ -237,13 +268,60 @@ openlog(ident, logstat, logfac) } void -closelog() +openlog (const char *ident, int logstat, int logfac) +{ + /* Protect against multiple users. */ + __libc_cleanup_region_start ((void (*) __P ((void *))) __libc_mutex_unlock, + &syslog_lock); + __libc_lock_lock (syslog_lock); + + openlog_internal (ident, logstat, logfac); + + /* Free the lock. */ + __libc_cleanup_region_end (1); +} + +static void +sigpipe_handler (int signo) +{ + closelog_internal(); +} + +static void +closelog_internal() { (void)close(LogFile); LogFile = -1; connected = 0; } +void +closelog () +{ + /* Protect against multiple users. */ + __libc_cleanup_region_start ((void (*) __P ((void *))) __libc_mutex_unlock, + &syslog_lock); + __libc_lock_lock (syslog_lock); + + closelog_internal (); + + /* Free the lock. */ + __libc_cleanup_region_end (1); +} + +static void +cancel_handler (void *ptr) +{ + /* Restore the old signal handler. */ + struct sigaction *oldaction = *((struct sigaction **) ptr); + + if (oldaction != (struct sigaction *) NULL) + sigaction (SIGPIPE, oldaction, (struct sigaction *) NULL); + + /* Free the lock. */ + __libc_lock_unlock (syslog_lock); +} + /* setlogmask -- set the log mask level */ int setlogmask(pmask) |