about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-04-18 21:11:23 -0400
committerRich Felker <dalias@aerifal.cx>2011-04-18 21:11:23 -0400
commitd2c604d5a40bc75fe83a62fd20377c20a73aa0d5 (patch)
treed255bb9d997ebe0b509d0f47d30f29051306c3bd /src
parentbe2e06d347fdb83e9c4f57e57fa29b78f6276a0c (diff)
downloadmusl-d2c604d5a40bc75fe83a62fd20377c20a73aa0d5.tar.gz
musl-d2c604d5a40bc75fe83a62fd20377c20a73aa0d5.tar.xz
musl-d2c604d5a40bc75fe83a62fd20377c20a73aa0d5.zip
protect syslog against cancellation
these functions are allowed to be cancellation points, but then we
would have to install cleanup handlers to avoid termination with locks
held.
Diffstat (limited to 'src')
-rw-r--r--src/misc/syslog.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/misc/syslog.c b/src/misc/syslog.c
index 0f757640..cbe65209 100644
--- a/src/misc/syslog.c
+++ b/src/misc/syslog.c
@@ -7,6 +7,7 @@
 #include <time.h>
 #include <signal.h>
 #include <string.h>
+#include <pthread.h>
 #include "libc.h"
 
 static int lock;
@@ -33,10 +34,13 @@ static const struct {
 
 void closelog(void)
 {
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 	LOCK(&lock);
 	close(log_fd);
 	log_fd = -1;
 	UNLOCK(&lock);
+	pthread_setcancelstate(cs, 0);
 }
 
 static void __openlog(const char *ident, int opt, int facility)
@@ -53,12 +57,15 @@ static void __openlog(const char *ident, int opt, int facility)
 
 void openlog(const char *ident, int opt, int facility)
 {
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 	LOCK(&lock);
 	__openlog(ident, opt, facility);
 	UNLOCK(&lock);
+	pthread_setcancelstate(cs, 0);
 }
 
-void __vsyslog(int priority, const char *message, va_list ap)
+static void _vsyslog(int priority, const char *message, va_list ap)
 {
 	char timebuf[16];
 	time_t now;
@@ -67,10 +74,6 @@ void __vsyslog(int priority, const char *message, va_list ap)
 	int pid;
 	int l, l2;
 
-	if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return;
-
-	LOCK(&lock);
-
 	if (log_fd < 0) {
 		__openlog(log_ident, log_opt | LOG_NDELAY, log_facility);
 		if (log_fd < 0) {
@@ -98,6 +101,17 @@ void __vsyslog(int priority, const char *message, va_list ap)
 	UNLOCK(&lock);
 }
 
+void __vsyslog(int priority, const char *message, va_list ap)
+{
+	int cs;
+	if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	LOCK(&lock);
+	_vsyslog(priority, message, ap);
+	UNLOCK(&lock);
+	pthread_setcancelstate(cs, 0);
+}
+
 void syslog(int priority, const char *message, ...)
 {
 	va_list ap;