From 73299943388c0eebf6a9c8d6288e9da8289f9dca Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 15 Jul 2003 07:52:52 +0000 Subject: Update. More cancellation handling fixups. * sysdeps/unix/sysv/linux/not-cancel.h: Add waitpid_not_cancel. * sysdeps/generic/not-cancel.h: Likewise. * catgets/open_catalog.c: Use not-cancelable syscalls. * time/Makefile (CFLAGS-getdate.c): Add -fexceptions. * sysdeps/unix/sysv/linux/llseek.c: Must not be cancelable. * sysdeps/unix/syscalls.list: Don't mark lseek as cancelable. * dlfcn/dlfcn.h: Mark dlopen with __THROW again. * io/fcntl.h: Don't mark posix_fallocate with __THROW. * libio/fileops.c: Use not-cancelable syscalls for fclose. * libio/iopopen.c: Use no-cancelable syscalls. * libio/stdio.h: Mark popen and pclose with __THROW again. * misc/Makefile (CFLAGS-syslog.c): Add -fexceptions. * misc/syslog.c: Fix locking and cancellation cleanup handling. * posix/unistd.h: Mark ttyname and ttyname_r again with __THROW. * stdio-common/Makefile (CFLAGS-tmpfile.c, CFLAGS-tmpfile64.c, CFLAGS-tempname.c): Add -fexceptions. * stdlib/Makefile (CFLAGS-mkstemp.c): Add -fexceptions. * string/string.h: Mark strerror and strerror_r with _THROW again. * sysdeps/generic/unwind.inc: New file. Copied from gcc. * sysdeps/generic/unwind-dw2.c: Update from gcc version. Remove #ifs since we now need all the code compiled. * sysdeps/posix/spawni.c: Use close_not_cancel instead of close. * sysdeps/unix/closedir.c: Use not-cancelable syscalls. * sysdeps/unix/opendir.c: Likewise. --- misc/Makefile | 1 + misc/syslog.c | 101 ++++++++++++++++++++++++++++------------------------------ 2 files changed, 50 insertions(+), 52 deletions(-) (limited to 'misc') diff --git a/misc/Makefile b/misc/Makefile index 2685e908ee..e8828109a7 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -81,6 +81,7 @@ CFLAGS-pselect.c = -fexceptions CFLAGS-readv.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-writev.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-usleep.c = -fexceptions +CFLAGS-syslog.c = -fexceptions include ../Rules diff --git a/misc/syslog.c b/misc/syslog.c index c1fdf5b6b9..d84cbbf47f 100644 --- a/misc/syslog.c +++ b/misc/syslog.c @@ -41,6 +41,7 @@ static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94"; #include #include #include +#include #include #include #include @@ -74,9 +75,27 @@ __libc_lock_define_initialized (static, syslog_lock) static void openlog_internal(const char *, int, int) internal_function; static void closelog_internal(void); static void sigpipe_handler (int); -#ifdef _LIBC_REENTRANT -static void cancel_handler (void *); -#endif + + +struct cleanup_arg +{ + void *buf; + struct sigaction *oldaction; +}; + +static void +cancel_handler (void *ptr) +{ + /* Restore the old signal handler. */ + struct cleanup_arg *clarg = (struct cleanup_arg *) ptr; + + if (clarg != NULL && clarg->oldaction != NULL) + __sigaction (SIGPIPE, clarg->oldaction, NULL); + + /* Free the lock. */ + __libc_lock_unlock (syslog_lock); +} + /* * syslog, vsyslog -- @@ -118,7 +137,6 @@ vsyslog(pri, fmt, ap) size_t bufsize = 0; size_t prioff, msgoff; struct sigaction action, oldaction; - struct sigaction *oldaction_ptr = NULL; int sigpipe; int saved_errno = errno; char failbuf[3 * sizeof (pid_t) + sizeof "out of memory []"]; @@ -165,6 +183,7 @@ vsyslog(pri, fmt, ap) } else { + __fsetlocking (f, FSETLOCKING_BYCALLER); prioff = fprintf (f, "<%d>", pri); (void) time (&now); #ifdef USE_IN_LIBIO @@ -182,9 +201,12 @@ vsyslog(pri, fmt, ap) if (LogTag != NULL) fputs_unlocked (LogTag, f); if (LogStat & LOG_PID) - fprintf (f, "[%d]", __getpid ()); + fprintf (f, "[%d]", (int) __getpid ()); if (LogTag != NULL) - putc_unlocked (':', f), putc_unlocked (' ', f); + { + putc_unlocked (':', f); + putc_unlocked (' ', f); + } /* Restore errno for %m format. */ __set_errno (saved_errno); @@ -212,16 +234,22 @@ vsyslog(pri, fmt, ap) v->iov_base = (char *) "\n"; v->iov_len = 1; } + + __libc_cleanup_push (free, buf); + + /* writev is a cancellation point. */ (void)__writev(STDERR_FILENO, iov, v - iov + 1); + + __libc_cleanup_pop (0); } -#ifdef _LIBC_REENTRANT /* Prepare for multiple users. We have to take care: open and write are cancellation points. */ - __libc_cleanup_region_start (1, (void (*) (void *)) cancel_handler, - &oldaction_ptr); + struct cleanup_arg clarg; + clarg.buf = buf; + clarg.oldaction = NULL; + __libc_cleanup_push (cancel_handler, &clarg); __libc_lock_lock (syslog_lock); -#endif /* Prepare for a broken connection. */ memset (&action, 0, sizeof (action)); @@ -229,7 +257,7 @@ vsyslog(pri, fmt, ap) sigemptyset (&action.sa_mask); sigpipe = __sigaction (SIGPIPE, &action, &oldaction); if (sigpipe == 0) - oldaction_ptr = &oldaction; + clarg.oldaction = &oldaction; /* Get connected, output the message to the local logger. */ if (!connected) @@ -271,11 +299,9 @@ vsyslog(pri, fmt, ap) if (sigpipe == 0) __sigaction (SIGPIPE, &oldaction, (struct sigaction *) NULL); -#ifdef _LIBC_REENTRANT /* End of critical section. */ - __libc_cleanup_region_end (0); + __libc_cleanup_pop (0); __libc_lock_unlock (syslog_lock); -#endif free (buf); } @@ -283,6 +309,7 @@ libc_hidden_def (vsyslog) static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ + static void internal_function openlog_internal(const char *ident, int logstat, int logfac) @@ -312,8 +339,9 @@ openlog_internal(const char *ident, int logstat, int logfac) == -1) { int saved_errno = errno; - (void)__close(LogFile); + int fd = LogFile; LogFile = -1; + (void)__close(fd); if (LogType == SOCK_DGRAM && saved_errno == EPROTOTYPE) { @@ -329,28 +357,16 @@ openlog_internal(const char *ident, int logstat, int logfac) } } - -static void -log_cleanup (void *arg) -{ - __libc_lock_unlock (syslog_lock); -} - void openlog (const char *ident, int logstat, int logfac) { -#ifdef _LIBC_REENTRANT - /* Protect against multiple users. */ - __libc_cleanup_region_start (1, log_cleanup, NULL); + /* Protect against multiple users and cancellation. */ + __libc_cleanup_push (cancel_handler, NULL); __libc_lock_lock (syslog_lock); -#endif openlog_internal (ident, logstat, logfac); -#ifdef _LIBC_REENTRANT - /* Free the lock. */ - __libc_cleanup_region_end (1); -#endif + __libc_cleanup_pop (1); } static void @@ -373,36 +389,17 @@ closelog_internal() void closelog () { -#ifdef _LIBC_REENTRANT - /* Protect against multiple users. */ - __libc_cleanup_region_start (1, log_cleanup, NULL); + /* Protect against multiple users and cancellation. */ + __libc_cleanup_push (cancel_handler, NULL); __libc_lock_lock (syslog_lock); -#endif closelog_internal (); LogTag = NULL; LogType = SOCK_DGRAM; /* this is the default */ -#ifdef _LIBC_REENTRANT - /* Free the lock. */ - __libc_cleanup_region_end (1); -#endif -} - -#ifdef _LIBC_REENTRANT -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); + __libc_cleanup_pop (1); } -#endif /* setlogmask -- set the log mask level */ int -- cgit v1.2.3