diff options
Diffstat (limited to 'src/port/pqsignal.c')
-rw-r--r-- | src/port/pqsignal.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/port/pqsignal.c b/src/port/pqsignal.c new file mode 100644 index 00000000000..ffb6f843308 --- /dev/null +++ b/src/port/pqsignal.c @@ -0,0 +1,76 @@ +/*------------------------------------------------------------------------- + * + * pqsignal.c + * reliable BSD-style signal(2) routine stolen from RWW who stole it + * from Stevens... + * + * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/port/pqsignal.c + * + * A NOTE ABOUT SIGNAL HANDLING ACROSS THE VARIOUS PLATFORMS. + * + * pg_config.h defines the macro HAVE_POSIX_SIGNALS for some platforms and + * not for others. We use that here to decide how to handle signalling. + * + * Ultrix and SunOS provide BSD signal(2) semantics by default. + * + * SVID2 and POSIX signal(2) semantics differ from BSD signal(2) + * semantics. We can use the POSIX sigaction(2) on systems that + * allow us to request restartable signals (SA_RESTART). + * + * Some systems don't allow restartable signals at all unless we + * link to a special BSD library. + * + * We devoutly hope that there aren't any Unix-oid systems that provide + * neither POSIX signals nor BSD signals. The alternative is to do + * signal-handler reinstallation, which doesn't work well at all. + * + * Windows, of course, is resolutely in a class by itself. This file + * should not get compiled at all on Windows. We have an emulation of + * pqsignal() in src/backend/port/win32/signal.c for the backend + * environment; frontend programs are out of luck. + * ------------------------------------------------------------------------ + */ + +#include "c.h" + +#include <signal.h> + +#ifndef WIN32 + +/* + * Set up a signal handler for signal "signo" + * + * Returns the previous handler. It's expected that the installed handler + * will persist across multiple deliveries of the signal (unlike the original + * POSIX definition of signal(2)). + */ +pqsigfunc +pqsignal(int signo, pqsigfunc func) +{ +#if !defined(HAVE_POSIX_SIGNALS) + return signal(signo, func); +#else + struct sigaction act, + oact; + + act.sa_handler = func; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + if (signo != SIGALRM) + act.sa_flags |= SA_RESTART; +#ifdef SA_NOCLDSTOP + if (signo == SIGCHLD) + act.sa_flags |= SA_NOCLDSTOP; +#endif + if (sigaction(signo, &act, &oact) < 0) + return SIG_ERR; + return oact.sa_handler; +#endif /* !HAVE_POSIX_SIGNALS */ +} + +#endif /* WIN32 */ |