1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
/*-------------------------------------------------------------------------
*
* pqsignal.c
* Backend signal(2) support (see also src/port/pqsignal.c)
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/backend/libpq/pqsignal.c
*
* ------------------------------------------------------------------------
*/
#include "postgres.h"
#include "libpq/pqsignal.h"
/* Global variables */
sigset_t UnBlockSig,
BlockSig,
StartupBlockSig;
/*
* Initialize BlockSig, UnBlockSig, and StartupBlockSig.
*
* 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.
*
* StartupBlockSig is the set of signals to block during startup packet
* collection; it's essentially BlockSig minus SIGTERM, SIGQUIT, SIGALRM.
*
* UnBlockSig is the set of signals to block when we don't want to block
* signals.
*/
void
pqinitmask(void)
{
sigemptyset(&UnBlockSig);
/* Note: InitializeLatchSupport() modifies UnBlockSig. */
/* First set all signals, then clear some. */
sigfillset(&BlockSig);
sigfillset(&StartupBlockSig);
/*
* 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...
*/
#ifdef SIGTRAP
sigdelset(&BlockSig, SIGTRAP);
sigdelset(&StartupBlockSig, SIGTRAP);
#endif
#ifdef SIGABRT
sigdelset(&BlockSig, SIGABRT);
sigdelset(&StartupBlockSig, SIGABRT);
#endif
#ifdef SIGILL
sigdelset(&BlockSig, SIGILL);
sigdelset(&StartupBlockSig, SIGILL);
#endif
#ifdef SIGFPE
sigdelset(&BlockSig, SIGFPE);
sigdelset(&StartupBlockSig, SIGFPE);
#endif
#ifdef SIGSEGV
sigdelset(&BlockSig, SIGSEGV);
sigdelset(&StartupBlockSig, SIGSEGV);
#endif
#ifdef SIGBUS
sigdelset(&BlockSig, SIGBUS);
sigdelset(&StartupBlockSig, SIGBUS);
#endif
#ifdef SIGSYS
sigdelset(&BlockSig, SIGSYS);
sigdelset(&StartupBlockSig, SIGSYS);
#endif
#ifdef SIGCONT
sigdelset(&BlockSig, SIGCONT);
sigdelset(&StartupBlockSig, SIGCONT);
#endif
/* Signals unique to startup */
#ifdef SIGQUIT
sigdelset(&StartupBlockSig, SIGQUIT);
#endif
#ifdef SIGTERM
sigdelset(&StartupBlockSig, SIGTERM);
#endif
#ifdef SIGALRM
sigdelset(&StartupBlockSig, SIGALRM);
#endif
}
/*
* 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
}
|