1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00
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.
This commit is contained in:
Ulrich Drepper
2003-07-15 07:52:52 +00:00
parent da35d15e2b
commit 7329994338
27 changed files with 543 additions and 179 deletions

View File

@ -41,6 +41,7 @@ static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94";
#include <fcntl.h>
#include <paths.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
@ -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,37 +389,18 @@ 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
__libc_cleanup_pop (1);
}
#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);
}
#endif
/* setlogmask -- set the log mask level */
int
setlogmask(pmask)