1 /*-------------------------------------------------------------------------
4 * reliable BSD-style signal(2) routine stolen from RWW who stole it
7 * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
12 * src/backend/libpq/pqsignal.c
15 * This shouldn't be in libpq, but the monitor and some other
18 * A NOTE ABOUT SIGNAL HANDLING ACROSS THE VARIOUS PLATFORMS.
20 * pg_config.h defines the macro HAVE_POSIX_SIGNALS for some platforms and
21 * not for others. This file and pqsignal.h use that macro to decide
22 * how to handle signalling.
24 * signal(2) handling - this is here because it affects some of
25 * the frontend commands as well as the backend processes.
27 * Ultrix and SunOS provide BSD signal(2) semantics by default.
29 * SVID2 and POSIX signal(2) semantics differ from BSD signal(2)
30 * semantics. We can use the POSIX sigaction(2) on systems that
31 * allow us to request restartable signals (SA_RESTART).
33 * Some systems don't allow restartable signals at all unless we
34 * link to a special BSD library.
36 * We devoutly hope that there aren't any systems that provide
37 * neither POSIX signals nor BSD signals. The alternative
38 * is to do signal-handler reinstallation, which doesn't work well
40 * ------------------------------------------------------------------------*/
46 #include "libpq/pqsignal.h"
49 #ifdef HAVE_SIGPROCMASK
61 * Initialize BlockSig, UnBlockSig, and StartupBlockSig.
63 * BlockSig is the set of signals to block when we are trying to block
64 * signals. This includes all signals we normally expect to get, but NOT
65 * signals that should never be turned off.
67 * StartupBlockSig is the set of signals to block during startup packet
68 * collection; it's essentially BlockSig minus SIGTERM, SIGQUIT, SIGALRM.
70 * UnBlockSig is the set of signals to block when we don't want to block
71 * signals (is this ever nonzero??)
76 #ifdef HAVE_SIGPROCMASK
78 sigemptyset(&UnBlockSig);
80 /* First set all signals, then clear some. */
81 sigfillset(&BlockSig);
82 sigfillset(&StartupBlockSig);
85 * Unmark those signals that should never be blocked. Some of these signal
86 * names don't exist on all platforms. Most do, but might as well ifdef
87 * them all for consistency...
90 sigdelset(&BlockSig, SIGTRAP);
91 sigdelset(&StartupBlockSig, SIGTRAP);
94 sigdelset(&BlockSig, SIGABRT);
95 sigdelset(&StartupBlockSig, SIGABRT);
98 sigdelset(&BlockSig, SIGILL);
99 sigdelset(&StartupBlockSig, SIGILL);
102 sigdelset(&BlockSig, SIGFPE);
103 sigdelset(&StartupBlockSig, SIGFPE);
106 sigdelset(&BlockSig, SIGSEGV);
107 sigdelset(&StartupBlockSig, SIGSEGV);
110 sigdelset(&BlockSig, SIGBUS);
111 sigdelset(&StartupBlockSig, SIGBUS);
114 sigdelset(&BlockSig, SIGSYS);
115 sigdelset(&StartupBlockSig, SIGSYS);
118 sigdelset(&BlockSig, SIGCONT);
119 sigdelset(&StartupBlockSig, SIGCONT);
122 /* Signals unique to startup */
124 sigdelset(&StartupBlockSig, SIGQUIT);
127 sigdelset(&StartupBlockSig, SIGTERM);
130 sigdelset(&StartupBlockSig, SIGALRM);
133 /* Set the signals we want. */
135 BlockSig = sigmask(SIGQUIT) |
136 sigmask(SIGTERM) | sigmask(SIGALRM) |
137 /* common signals between two */
139 sigmask(SIGINT) | sigmask(SIGUSR1) |
140 sigmask(SIGUSR2) | sigmask(SIGCHLD) |
141 sigmask(SIGWINCH) | sigmask(SIGFPE);
142 StartupBlockSig = sigmask(SIGHUP) |
143 sigmask(SIGINT) | sigmask(SIGUSR1) |
144 sigmask(SIGUSR2) | sigmask(SIGCHLD) |
145 sigmask(SIGWINCH) | sigmask(SIGFPE);
150 /* Win32 signal handling is in backend/port/win32/signal.c */
154 * Set up a signal handler
157 pqsignal(int signo, pqsigfunc func)
159 #if !defined(HAVE_POSIX_SIGNALS)
160 return signal(signo, func);
162 struct sigaction act,
165 act.sa_handler = func;
166 sigemptyset(&act.sa_mask);
168 if (signo != SIGALRM)
169 act.sa_flags |= SA_RESTART;
171 if (signo == SIGCHLD)
172 act.sa_flags |= SA_NOCLDSTOP;
174 if (sigaction(signo, &act, &oact) < 0)
176 return oact.sa_handler;
177 #endif /* !HAVE_POSIX_SIGNALS */