about summary refs log tree commit diff
path: root/misc/syslog.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1996-12-07 03:30:25 +0000
committerUlrich Drepper <drepper@redhat.com>1996-12-07 03:30:25 +0000
commita18f587da5a0a91bcd1307ed0f122ca2ce994c15 (patch)
tree174cca5dd1f842dff255d6491ff6677ac7772eab /misc/syslog.c
parent6b612c67093292a99a336fae38e459ee00927d0f (diff)
downloadglibc-a18f587da5a0a91bcd1307ed0f122ca2ce994c15.tar.gz
glibc-a18f587da5a0a91bcd1307ed0f122ca2ce994c15.tar.xz
glibc-a18f587da5a0a91bcd1307ed0f122ca2ce994c15.zip
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.c92
1 files changed, 85 insertions, 7 deletions
diff --git a/misc/syslog.c b/misc/syslog.c
index 9db16ca352..205909e1cd 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)