1 /*-------------------------------------------------------------------------
4 * reliable BSD-style signal(2) routine stolen from RWW who stole it
7 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
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 server.
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 AuthBlockSig.
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 * AuthBlockSig is the set of signals to block during authentication;
68 * 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(&AuthBlockSig
);
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(&AuthBlockSig
, SIGTRAP
);
94 sigdelset(&BlockSig
, SIGABRT
);
95 sigdelset(&AuthBlockSig
, SIGABRT
);
98 sigdelset(&BlockSig
, SIGILL
);
99 sigdelset(&AuthBlockSig
, SIGILL
);
102 sigdelset(&BlockSig
, SIGFPE
);
103 sigdelset(&AuthBlockSig
, SIGFPE
);
106 sigdelset(&BlockSig
, SIGSEGV
);
107 sigdelset(&AuthBlockSig
, SIGSEGV
);
110 sigdelset(&BlockSig
, SIGBUS
);
111 sigdelset(&AuthBlockSig
, SIGBUS
);
114 sigdelset(&BlockSig
, SIGSYS
);
115 sigdelset(&AuthBlockSig
, SIGSYS
);
118 sigdelset(&BlockSig
, SIGCONT
);
119 sigdelset(&AuthBlockSig
, SIGCONT
);
122 /* Signals unique to Auth */
124 sigdelset(&AuthBlockSig
, SIGQUIT
);
127 sigdelset(&AuthBlockSig
, SIGTERM
);
130 sigdelset(&AuthBlockSig
, 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 AuthBlockSig
= 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 */