LCOV - differential code coverage report
Current view: top level - src/port - pqsignal.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 85.2 % 27 23 3 1 16 7 1
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 2 2 2
Baseline: 16@8cea358b128 Branches: 75.0 % 20 15 4 1 12 3
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed [..60] days: 84.2 % 19 16 3 16
(240..) days: 87.5 % 8 7 1 7
Function coverage date bins:
[..60] days: 100.0 % 1 1 1
(240..) days: 100.0 % 1 1 1
Branch coverage date bins:
[..60] days: 75.0 % 16 12 4 12
(240..) days: 75.0 % 4 3 1 3

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  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-2024, PostgreSQL Global Development Group
                                  8                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :                :  *
                                 10                 :                :  *
                                 11                 :                :  * IDENTIFICATION
                                 12                 :                :  *    src/port/pqsignal.c
                                 13                 :                :  *
                                 14                 :                :  *  This is the signal() implementation from "Advanced Programming in the UNIX
                                 15                 :                :  *  Environment", with minor changes.  It was originally a replacement needed
                                 16                 :                :  *  for old SVR4 systems whose signal() behaved as if sa_flags = SA_RESETHAND |
                                 17                 :                :  *  SA_NODEFER, also known as "unreliable" signals due to races when the
                                 18                 :                :  *  handler was reset.
                                 19                 :                :  *
                                 20                 :                :  *  By now, all known modern Unix systems have a "reliable" signal() call.
                                 21                 :                :  *  We still don't want to use it though, because it remains
                                 22                 :                :  *  implementation-defined by both C99 and POSIX whether the handler is reset
                                 23                 :                :  *  or signals are blocked when the handler runs, and default restart behavior
                                 24                 :                :  *  is also unspecified.  Therefore we take POSIX's advice and call sigaction()
                                 25                 :                :  *  so we can provide explicit sa_flags, but wrap it in this more convenient
                                 26                 :                :  *  traditional interface style.  It also provides a place to set any extra
                                 27                 :                :  *  flags we want everywhere, such as SA_NOCLDSTOP.
                                 28                 :                :  *
                                 29                 :                :  *  Windows, of course, is resolutely in a class by itself.  In the backend,
                                 30                 :                :  *  this relies on pqsigaction() in src/backend/port/win32/signal.c, which
                                 31                 :                :  *  provides limited emulation of reliable signals.
                                 32                 :                :  *
                                 33                 :                :  *  Frontend programs can use this version of pqsignal() to forward to the
                                 34                 :                :  *  native Windows signal() call if they wish, but beware that Windows signals
                                 35                 :                :  *  behave quite differently.  Only the 6 signals required by C are supported.
                                 36                 :                :  *  SIGINT handlers run in another thread instead of interrupting an existing
                                 37                 :                :  *  thread, and the others don't interrupt system calls either, so SA_RESTART
                                 38                 :                :  *  is moot.  All except SIGFPE have SA_RESETHAND semantics, meaning the
                                 39                 :                :  *  handler is reset to SIG_DFL each time it runs.  The set of things you are
                                 40                 :                :  *  allowed to do in a handler is also much more restricted than on Unix,
                                 41                 :                :  *  according to the documentation.
                                 42                 :                :  *
                                 43                 :                :  * ------------------------------------------------------------------------
                                 44                 :                :  */
                                 45                 :                : 
                                 46                 :                : #include "c.h"
                                 47                 :                : 
                                 48                 :                : #include <signal.h>
                                 49                 :                : #ifndef FRONTEND
                                 50                 :                : #include <unistd.h>
                                 51                 :                : #endif
                                 52                 :                : 
                                 53                 :                : #ifndef FRONTEND
                                 54                 :                : #include "libpq/pqsignal.h"
                                 55                 :                : #include "miscadmin.h"
                                 56                 :                : #endif
                                 57                 :                : 
                                 58                 :                : #ifdef PG_SIGNAL_COUNT          /* Windows */
                                 59                 :                : #define PG_NSIG (PG_SIGNAL_COUNT)
                                 60                 :                : #elif defined(NSIG)
                                 61                 :                : #define PG_NSIG (NSIG)
                                 62                 :                : #else
                                 63                 :                : #define PG_NSIG (64)            /* XXX: wild guess */
                                 64                 :                : #endif
                                 65                 :                : 
                                 66                 :                : /* Check a couple of common signals to make sure PG_NSIG is accurate. */
                                 67                 :                : StaticAssertDecl(SIGUSR2 < PG_NSIG, "SIGUSR2 >= PG_NSIG");
                                 68                 :                : StaticAssertDecl(SIGHUP < PG_NSIG, "SIGHUP >= PG_NSIG");
                                 69                 :                : StaticAssertDecl(SIGTERM < PG_NSIG, "SIGTERM >= PG_NSIG");
                                 70                 :                : StaticAssertDecl(SIGALRM < PG_NSIG, "SIGALRM >= PG_NSIG");
                                 71                 :                : 
                                 72                 :                : static volatile pqsigfunc pqsignal_handlers[PG_NSIG];
                                 73                 :                : 
                                 74                 :                : /*
                                 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.
                                 83                 :                :  *
                                 84                 :                :  * This wrapper also handles restoring the value of errno.
                                 85                 :                :  */
                                 86                 :                : static void
   60 nathan@postgresql.or       87                 :GNC      127227 : wrapper_handler(SIGNAL_ARGS)
                                 88                 :                : {
                                 89                 :         127227 :     int         save_errno = errno;
                                 90                 :                : 
                                 91                 :                : #ifndef FRONTEND
                                 92                 :                : 
                                 93                 :                :     /*
                                 94                 :                :      * We expect processes to set MyProcPid before calling pqsignal() or
                                 95                 :                :      * before accepting signals.
                                 96                 :                :      */
                                 97         [ -  + ]:         127101 :     Assert(MyProcPid);
                                 98   [ +  +  -  + ]:         127101 :     Assert(MyProcPid != PostmasterPid || !IsUnderPostmaster);
                                 99                 :                : 
                                100         [ -  + ]:         127101 :     if (unlikely(MyProcPid != (int) getpid()))
                                101                 :                :     {
   60 nathan@postgresql.or      102                 :UNC           0 :         pqsignal(postgres_signal_arg, SIG_DFL);
                                103                 :              0 :         raise(postgres_signal_arg);
                                104                 :              0 :         return;
                                105                 :                :     }
                                106                 :                : #endif
                                107                 :                : 
   60 nathan@postgresql.or      108                 :GNC      127227 :     (*pqsignal_handlers[postgres_signal_arg]) (postgres_signal_arg);
                                109                 :                : 
                                110                 :         125697 :     errno = save_errno;
                                111                 :            126 : }
                                112                 :                : 
                                113                 :                : /*
                                114                 :                :  * Set up a signal handler, with SA_RESTART, for signal "signo"
                                115                 :                :  *
                                116                 :                :  * Returns the previous handler.
                                117                 :                :  *
                                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.
                                121                 :                :  *
                                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.
                                127                 :                :  */
                                128                 :                : pqsigfunc
 4046 tgl@sss.pgh.pa.us         129                 :CBC      292914 : pqsignal(int signo, pqsigfunc func)
                                130                 :                : {
   60 nathan@postgresql.or      131                 :GNC      292914 :     pqsigfunc   orig_func = pqsignal_handlers[signo];   /* assumed atomic */
                                132                 :                : #if !(defined(WIN32) && defined(FRONTEND))
                                133                 :                :     struct sigaction act,
                                134                 :                :                 oact;
                                135                 :                : #else
                                136                 :                :     pqsigfunc   ret;
                                137                 :                : #endif
                                138                 :                : 
                                139         [ -  + ]:         292914 :     Assert(signo < PG_NSIG);
                                140                 :                : 
                                141   [ +  +  +  + ]:         292914 :     if (func != SIG_IGN && func != SIG_DFL)
                                142                 :                :     {
                                143                 :         218825 :         pqsignal_handlers[signo] = func;    /* assumed atomic */
                                144                 :         218825 :         func = wrapper_handler;
                                145                 :                :     }
                                146                 :                : 
                                147                 :                : #if !(defined(WIN32) && defined(FRONTEND))
 4046 tgl@sss.pgh.pa.us         148                 :CBC      292914 :     act.sa_handler = func;
                                149                 :         292914 :     sigemptyset(&act.sa_mask);
 3956                           150                 :         292914 :     act.sa_flags = SA_RESTART;
                                151                 :                : #ifdef SA_NOCLDSTOP
 4046                           152         [ +  + ]:         292914 :     if (signo == SIGCHLD)
                                153                 :          28537 :         act.sa_flags |= SA_NOCLDSTOP;
                                154                 :                : #endif
                                155         [ -  + ]:         292914 :     if (sigaction(signo, &act, &oact) < 0)
 4046 tgl@sss.pgh.pa.us         156                 :UBC           0 :         return SIG_ERR;
   60 nathan@postgresql.or      157         [ +  + ]:GNC      292914 :     else if (oact.sa_handler == wrapper_handler)
                                158                 :         173284 :         return orig_func;
                                159                 :                :     else
                                160                 :         119630 :         return oact.sa_handler;
                                161                 :                : #else
                                162                 :                :     /* Forward to Windows native signal system. */
                                163                 :                :     if ((ret = signal(signo, func)) == wrapper_handler)
                                164                 :                :         return orig_func;
                                165                 :                :     else
                                166                 :                :         return ret;
                                167                 :                : #endif
                                168                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622