]> granicus.if.org Git - postgresql/blob - src/backend/libpq/pqsignal.c
Reduce hash size for compute_array_stats, compute_tsvector_stats.
[postgresql] / src / backend / libpq / pqsignal.c
1 /*-------------------------------------------------------------------------
2  *
3  * pqsignal.c
4  *        reliable BSD-style signal(2) routine stolen from RWW who stole it
5  *        from Stevens...
6  *
7  * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *        src/backend/libpq/pqsignal.c
13  *
14  * NOTES
15  *              This shouldn't be in libpq, but the monitor and some other
16  *              things need it...
17  *
18  *      A NOTE ABOUT SIGNAL HANDLING ACROSS THE VARIOUS PLATFORMS.
19  *
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.
23  *
24  *      signal(2) handling - this is here because it affects some of
25  *      the frontend commands as well as the backend processes.
26  *
27  *      Ultrix and SunOS provide BSD signal(2) semantics by default.
28  *
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).
32  *
33  *      Some systems don't allow restartable signals at all unless we
34  *      link to a special BSD library.
35  *
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
39  *      at all.
40  * ------------------------------------------------------------------------*/
41
42 #include "postgres.h"
43
44 #include <signal.h>
45
46 #include "libpq/pqsignal.h"
47
48
49 #ifdef HAVE_SIGPROCMASK
50 sigset_t        UnBlockSig,
51                         BlockSig,
52                         StartupBlockSig;
53 #else
54 int                     UnBlockSig,
55                         BlockSig,
56                         StartupBlockSig;
57 #endif
58
59
60 /*
61  * Initialize BlockSig, UnBlockSig, and StartupBlockSig.
62  *
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.
66  *
67  * StartupBlockSig is the set of signals to block during startup packet
68  * collection; it's essentially BlockSig minus SIGTERM, SIGQUIT, SIGALRM.
69  *
70  * UnBlockSig is the set of signals to block when we don't want to block
71  * signals (is this ever nonzero??)
72  */
73 void
74 pqinitmask(void)
75 {
76 #ifdef HAVE_SIGPROCMASK
77
78         sigemptyset(&UnBlockSig);
79
80         /* First set all signals, then clear some. */
81         sigfillset(&BlockSig);
82         sigfillset(&StartupBlockSig);
83
84         /*
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...
88          */
89 #ifdef SIGTRAP
90         sigdelset(&BlockSig, SIGTRAP);
91         sigdelset(&StartupBlockSig, SIGTRAP);
92 #endif
93 #ifdef SIGABRT
94         sigdelset(&BlockSig, SIGABRT);
95         sigdelset(&StartupBlockSig, SIGABRT);
96 #endif
97 #ifdef SIGILL
98         sigdelset(&BlockSig, SIGILL);
99         sigdelset(&StartupBlockSig, SIGILL);
100 #endif
101 #ifdef SIGFPE
102         sigdelset(&BlockSig, SIGFPE);
103         sigdelset(&StartupBlockSig, SIGFPE);
104 #endif
105 #ifdef SIGSEGV
106         sigdelset(&BlockSig, SIGSEGV);
107         sigdelset(&StartupBlockSig, SIGSEGV);
108 #endif
109 #ifdef SIGBUS
110         sigdelset(&BlockSig, SIGBUS);
111         sigdelset(&StartupBlockSig, SIGBUS);
112 #endif
113 #ifdef SIGSYS
114         sigdelset(&BlockSig, SIGSYS);
115         sigdelset(&StartupBlockSig, SIGSYS);
116 #endif
117 #ifdef SIGCONT
118         sigdelset(&BlockSig, SIGCONT);
119         sigdelset(&StartupBlockSig, SIGCONT);
120 #endif
121
122 /* Signals unique to startup */
123 #ifdef SIGQUIT
124         sigdelset(&StartupBlockSig, SIGQUIT);
125 #endif
126 #ifdef SIGTERM
127         sigdelset(&StartupBlockSig, SIGTERM);
128 #endif
129 #ifdef SIGALRM
130         sigdelset(&StartupBlockSig, SIGALRM);
131 #endif
132 #else
133         /* Set the signals we want. */
134         UnBlockSig = 0;
135         BlockSig = sigmask(SIGQUIT) |
136                 sigmask(SIGTERM) | sigmask(SIGALRM) |
137         /* common signals between two */
138                 sigmask(SIGHUP) |
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);
146 #endif
147 }
148
149
150 /* Win32 signal handling is in backend/port/win32/signal.c */
151 #ifndef WIN32
152
153 /*
154  * Set up a signal handler
155  */
156 pqsigfunc
157 pqsignal(int signo, pqsigfunc func)
158 {
159 #if !defined(HAVE_POSIX_SIGNALS)
160         return signal(signo, func);
161 #else
162         struct sigaction act,
163                                 oact;
164
165         act.sa_handler = func;
166         sigemptyset(&act.sa_mask);
167         act.sa_flags = 0;
168         if (signo != SIGALRM)
169                 act.sa_flags |= SA_RESTART;
170 #ifdef SA_NOCLDSTOP
171         if (signo == SIGCHLD)
172                 act.sa_flags |= SA_NOCLDSTOP;
173 #endif
174         if (sigaction(signo, &act, &oact) < 0)
175                 return SIG_ERR;
176         return oact.sa_handler;
177 #endif   /* !HAVE_POSIX_SIGNALS */
178 }
179
180 #endif   /* WIN32 */