59#define PG_NSIG (PG_SIGNAL_COUNT)
69StaticAssertDecl(SIGTERM < PG_NSIG, "SIGTERM >=
PG_NSIG");
72static volatile pqsigfunc pqsignal_handlers[PG_NSIG];
75 * Except when called with SIG_IGN or SIG_DFL, pqsignal() sets up this function
76 * as the handler for all signals. This wrapper handler function checks that
77 * it is called within a process that knew to maintain MyProcPid, and not a
78 * child process forked by system(3), etc. This check ensures that such child
79 * processes do not modify shared memory, which is often detrimental. If the
80 * check succeeds, the function originally provided to pqsignal() is called.
81 * Otherwise, the default signal handler is installed and then called.
83 * This wrapper also handles restoring the value of errno.
86wrapper_handler(SIGNAL_ARGS)
88 int save_errno = errno;
90 Assert(postgres_signal_arg > 0);
91 Assert(postgres_signal_arg < PG_NSIG);
96 * We expect processes to set MyProcPid before calling pqsignal() or
97 * before accepting signals.
100 Assert(MyProcPid != PostmasterPid || !IsUnderPostmaster);
102 if (unlikely(MyProcPid != (int) getpid()))
104 pqsignal(postgres_signal_arg, SIG_DFL);
105 raise(postgres_signal_arg);
110 (*pqsignal_handlers[postgres_signal_arg]) (postgres_signal_arg);
116 * Set up a signal handler, with SA_RESTART, for signal "signo
"
118 * Note: the actual name of this function is either pqsignal_fe when
119 * compiled with -DFRONTEND, or pqsignal_be when compiled without that.
120 * This is to avoid a name collision with libpq's legacy-pqsignal.c.
123pqsignal(int signo, pqsigfunc func)
125#if !(defined(WIN32) && defined(FRONTEND))
126 struct sigaction act;
130 Assert(signo < PG_NSIG);
132 if (func != SIG_IGN && func != SIG_DFL)
134 pqsignal_handlers[signo] = func; /* assumed atomic */
135 func = wrapper_handler;
138#if !(defined(WIN32) && defined(FRONTEND))
139 act.sa_handler = func;
140 sigemptyset(&act.sa_mask);
141 act.sa_flags = SA_RESTART;
143 if (signo == SIGCHLD)
144 act.sa_flags |= SA_NOCLDSTOP;
146 if (sigaction(signo, &act, NULL) < 0)
147 Assert(false); /* probably indicates coding error */
149 /* Forward to Windows native signal system. */
150 if (signal(signo, func) == SIG_ERR)
151 Assert(false); /* probably indicates coding error */
StaticAssertDecl(SIGUSR2< PG_NSIG, "SIGUSR2 >= PG_NSIG")