1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* pqsignal.c
|
2013-03-17 17:06:42 +01:00
|
|
|
* Backend signal(2) support (see also src/port/pqsignal.c)
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2020-01-01 18:21:45 +01:00
|
|
|
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/backend/libpq/pqsignal.c
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2013-03-17 17:06:42 +01:00
|
|
|
* ------------------------------------------------------------------------
|
|
|
|
*/
|
2004-01-27 01:45:26 +01:00
|
|
|
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "postgres.h"
|
|
|
|
|
1999-07-16 01:04:24 +02:00
|
|
|
#include "libpq/pqsignal.h"
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2000-06-28 05:33:33 +02:00
|
|
|
|
2015-08-31 21:52:56 +02:00
|
|
|
/* Global variables */
|
2004-05-30 00:48:23 +02:00
|
|
|
sigset_t UnBlockSig,
|
|
|
|
BlockSig,
|
2009-08-29 21:26:52 +02:00
|
|
|
StartupBlockSig;
|
2004-05-30 00:48:23 +02:00
|
|
|
|
|
|
|
|
2000-06-28 05:33:33 +02:00
|
|
|
/*
|
2009-08-29 21:26:52 +02:00
|
|
|
* Initialize BlockSig, UnBlockSig, and StartupBlockSig.
|
2000-06-28 05:33:33 +02:00
|
|
|
*
|
|
|
|
* BlockSig is the set of signals to block when we are trying to block
|
|
|
|
* signals. This includes all signals we normally expect to get, but NOT
|
|
|
|
* signals that should never be turned off.
|
|
|
|
*
|
2009-08-29 21:26:52 +02:00
|
|
|
* StartupBlockSig is the set of signals to block during startup packet
|
|
|
|
* collection; it's essentially BlockSig minus SIGTERM, SIGQUIT, SIGALRM.
|
2001-09-08 03:10:21 +02:00
|
|
|
*
|
2000-06-28 05:33:33 +02:00
|
|
|
* UnBlockSig is the set of signals to block when we don't want to block
|
|
|
|
* signals (is this ever nonzero??)
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
pqinitmask(void)
|
|
|
|
{
|
|
|
|
sigemptyset(&UnBlockSig);
|
2005-02-15 00:02:03 +01:00
|
|
|
|
|
|
|
/* First set all signals, then clear some. */
|
2000-06-28 05:33:33 +02:00
|
|
|
sigfillset(&BlockSig);
|
2009-08-29 21:26:52 +02:00
|
|
|
sigfillset(&StartupBlockSig);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2000-06-29 04:17:42 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Unmark those signals that should never be blocked. Some of these signal
|
|
|
|
* names don't exist on all platforms. Most do, but might as well ifdef
|
|
|
|
* them all for consistency...
|
2000-06-29 04:17:42 +02:00
|
|
|
*/
|
|
|
|
#ifdef SIGTRAP
|
|
|
|
sigdelset(&BlockSig, SIGTRAP);
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGTRAP);
|
2000-06-29 04:17:42 +02:00
|
|
|
#endif
|
|
|
|
#ifdef SIGABRT
|
2000-06-28 05:33:33 +02:00
|
|
|
sigdelset(&BlockSig, SIGABRT);
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGABRT);
|
2000-06-29 04:17:42 +02:00
|
|
|
#endif
|
|
|
|
#ifdef SIGILL
|
2000-06-28 05:33:33 +02:00
|
|
|
sigdelset(&BlockSig, SIGILL);
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGILL);
|
2000-06-29 04:17:42 +02:00
|
|
|
#endif
|
|
|
|
#ifdef SIGFPE
|
|
|
|
sigdelset(&BlockSig, SIGFPE);
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGFPE);
|
2000-06-29 04:17:42 +02:00
|
|
|
#endif
|
|
|
|
#ifdef SIGSEGV
|
2000-06-28 05:33:33 +02:00
|
|
|
sigdelset(&BlockSig, SIGSEGV);
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGSEGV);
|
2000-06-29 04:17:42 +02:00
|
|
|
#endif
|
|
|
|
#ifdef SIGBUS
|
2000-06-28 05:33:33 +02:00
|
|
|
sigdelset(&BlockSig, SIGBUS);
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGBUS);
|
2000-06-29 04:17:42 +02:00
|
|
|
#endif
|
|
|
|
#ifdef SIGSYS
|
2000-06-28 05:33:33 +02:00
|
|
|
sigdelset(&BlockSig, SIGSYS);
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGSYS);
|
2000-06-29 04:17:42 +02:00
|
|
|
#endif
|
|
|
|
#ifdef SIGCONT
|
|
|
|
sigdelset(&BlockSig, SIGCONT);
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGCONT);
|
2001-09-07 18:12:49 +02:00
|
|
|
#endif
|
2005-02-15 00:02:35 +01:00
|
|
|
|
2009-08-29 21:26:52 +02:00
|
|
|
/* Signals unique to startup */
|
2001-09-07 18:12:49 +02:00
|
|
|
#ifdef SIGQUIT
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGQUIT);
|
2000-06-29 04:17:42 +02:00
|
|
|
#endif
|
2005-02-15 00:02:35 +01:00
|
|
|
#ifdef SIGTERM
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGTERM);
|
2005-02-15 00:02:35 +01:00
|
|
|
#endif
|
2001-09-21 19:06:12 +02:00
|
|
|
#ifdef SIGALRM
|
2009-08-29 21:26:52 +02:00
|
|
|
sigdelset(&StartupBlockSig, SIGALRM);
|
2001-09-21 19:06:12 +02:00
|
|
|
#endif
|
2000-06-28 05:33:33 +02:00
|
|
|
}
|
2019-10-13 21:48:26 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up a postmaster signal handler for signal "signo"
|
|
|
|
*
|
|
|
|
* Returns the previous handler.
|
|
|
|
*
|
|
|
|
* This is used only in the postmaster, which has its own odd approach to
|
|
|
|
* signal handling. For signals with handlers, we block all signals for the
|
|
|
|
* duration of signal handler execution. We also do not set the SA_RESTART
|
|
|
|
* flag; this should be safe given the tiny range of code in which the
|
|
|
|
* postmaster ever unblocks signals.
|
|
|
|
*
|
|
|
|
* pqinitmask() must have been invoked previously.
|
|
|
|
*
|
|
|
|
* On Windows, this function is just an alias for pqsignal()
|
|
|
|
* (and note that it's calling the code in src/backend/port/win32/signal.c,
|
|
|
|
* not src/port/pqsignal.c). On that platform, the postmaster's signal
|
|
|
|
* handlers still have to block signals for themselves.
|
|
|
|
*/
|
|
|
|
pqsigfunc
|
|
|
|
pqsignal_pm(int signo, pqsigfunc func)
|
|
|
|
{
|
|
|
|
#ifndef WIN32
|
|
|
|
struct sigaction act,
|
|
|
|
oact;
|
|
|
|
|
|
|
|
act.sa_handler = func;
|
|
|
|
if (func == SIG_IGN || func == SIG_DFL)
|
|
|
|
{
|
|
|
|
/* in these cases, act the same as pqsignal() */
|
|
|
|
sigemptyset(&act.sa_mask);
|
|
|
|
act.sa_flags = SA_RESTART;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
act.sa_mask = BlockSig;
|
|
|
|
act.sa_flags = 0;
|
|
|
|
}
|
|
|
|
#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;
|
|
|
|
#else /* WIN32 */
|
|
|
|
return pqsignal(signo, func);
|
|
|
|
#endif
|
|
|
|
}
|