58 #ifdef PG_SIGNAL_COUNT
59 #define PG_NSIG (PG_SIGNAL_COUNT)
61 #define PG_NSIG (NSIG)
69 StaticAssertDecl(SIGTERM < PG_NSIG, "SIGTERM >=
PG_NSIG");
72 static 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 the server knows about (i.e., any process
78 * that has called InitProcessGlobals(), such as a client backend), and not a
79 * child process forked by system(3), etc. This check ensures that such child
80 * processes do not modify shared memory, which is often detrimental. If the
81 * check succeeds, the function originally provided to pqsignal() is called.
82 * Otherwise, the default signal handler is installed and then called.
84 * This wrapper also handles restoring the value of errno.
87 wrapper_handler(SIGNAL_ARGS)
89 int save_errno = errno;
94 * We expect processes to set MyProcPid before calling pqsignal() or
95 * before accepting signals.
98 Assert(MyProcPid != PostmasterPid || !IsUnderPostmaster);
100 if (unlikely(MyProcPid != (int) getpid()))
102 pqsignal(postgres_signal_arg, SIG_DFL);
103 raise(postgres_signal_arg);
108 (*pqsignal_handlers[postgres_signal_arg]) (postgres_signal_arg);
114 * Set up a signal handler, with SA_RESTART, for signal "signo
"
116 * Returns the previous handler.
118 * NB: If called within a signal handler, race conditions may lead to bogus
119 * return values. You should either avoid calling this within signal handlers
120 * or ignore the return value.
122 * XXX: Since no in-tree callers use the return value, and there is little
123 * reason to do so, it would be nice if we could convert this to a void
124 * function instead of providing potentially-bogus return values.
125 * Unfortunately, that requires modifying the pqsignal() in legacy-pqsignal.c,
126 * which in turn requires an SONAME bump, which is probably not worth it.
129 pqsignal(int signo, pqsigfunc func)
131 pqsigfunc orig_func = pqsignal_handlers[signo]; /* assumed atomic */
132 #if !(defined(WIN32) && defined(FRONTEND))
133 struct sigaction act,
139 Assert(signo < PG_NSIG);
141 if (func != SIG_IGN && func != SIG_DFL)
143 pqsignal_handlers[signo] = func; /* assumed atomic */
144 func = wrapper_handler;
147 #if !(defined(WIN32) && defined(FRONTEND))
148 act.sa_handler = func;
149 sigemptyset(&act.sa_mask);
150 act.sa_flags = SA_RESTART;
152 if (signo == SIGCHLD)
153 act.sa_flags |= SA_NOCLDSTOP;
155 if (sigaction(signo, &act, &oact) < 0)
157 else if (oact.sa_handler == wrapper_handler)
160 return oact.sa_handler;
162 /* Forward to Windows native signal system. */
163 if ((ret = signal(signo, func)) == wrapper_handler)
StaticAssertDecl(SIGUSR2< PG_NSIG, "SIGUSR2 >= PG_NSIG")