LCOV - differential code coverage report
Current view: top level - src/port - pqsignal.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB DCB
Current: bed3ffbf9d952be6c7d739d068cdce44c046dfb7 vs 574581b50ac9c63dd9e4abebb731a3b67e5b50f6 Lines: 88.6 % 35 31 1 3 13 18 1 5
Current Date: 2026-05-05 10:23:31 +0900 Functions: 100.0 % 3 3 3 1
Baseline: lcov-20260505-025707-baseline Branches: 71.4 % 28 20 8 8 12 4
Baseline Date: 2026-05-05 10:27:06 +0900 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 92.9 % 14 13 1 13
(360..) days: 85.7 % 21 18 3 18
Function coverage date bins:
(7,30] days: 100.0 % 1 1 1
(360..) days: 100.0 % 2 2 2
Branch coverage date bins:
(7,30] days: 100.0 % 8 8 8
(360..) days: 60.0 % 20 12 8 12

 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-2026, 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                 :                : #if !(defined(WIN32) && defined(FRONTEND))
                                 67                 :                : #define USE_SIGACTION
                                 68                 :                : #endif
                                 69                 :                : 
                                 70                 :                : #if defined(USE_SIGACTION) && defined(HAVE_SA_SIGINFO)
                                 71                 :                : #define USE_SIGINFO
                                 72                 :                : #endif
                                 73                 :                : 
                                 74                 :                : /* Check a couple of common signals to make sure PG_NSIG is accurate. */
                                 75                 :                : StaticAssertDecl(SIGUSR2 < PG_NSIG, "SIGUSR2 >= PG_NSIG");
                                 76                 :                : StaticAssertDecl(SIGHUP < PG_NSIG, "SIGHUP >= PG_NSIG");
                                 77                 :                : StaticAssertDecl(SIGTERM < PG_NSIG, "SIGTERM >= PG_NSIG");
                                 78                 :                : StaticAssertDecl(SIGALRM < PG_NSIG, "SIGALRM >= PG_NSIG");
                                 79                 :                : 
                                 80                 :                : static volatile pqsigfunc pqsignal_handlers[PG_NSIG];
                                 81                 :                : 
                                 82                 :                : /*
                                 83                 :                :  * Except when called with SIG_IGN or SIG_DFL, pqsignal() sets up this function
                                 84                 :                :  * as the handler for all signals.  This wrapper handler function checks that
                                 85                 :                :  * it is called within a process that knew to maintain MyProcPid, and not a
                                 86                 :                :  * child process forked by system(3), etc.  This check ensures that such child
                                 87                 :                :  * processes do not modify shared memory, which is often detrimental.  If the
                                 88                 :                :  * check succeeds, the function originally provided to pqsignal() is called.
                                 89                 :                :  * Otherwise, the default signal handler is installed and then called.
                                 90                 :                :  *
                                 91                 :                :  * This wrapper also handles restoring the value of errno.
                                 92                 :                :  */
                                 93                 :                : #if defined(USE_SIGACTION) && defined(USE_SIGINFO)
                                 94                 :                : static void
   21 andrew@dunslane.net        95                 :GNC       49737 : wrapper_handler(int postgres_signal_arg, siginfo_t * info, void *context)
                                 96                 :                : #else                           /* no USE_SIGINFO */
                                 97                 :                : static void
                                 98                 :                : wrapper_handler(int postgres_signal_arg)
                                 99                 :                : #endif
                                100                 :                : {
  811 nathan@postgresql.or      101                 :CBC       49737 :     int         save_errno = errno;
                                102                 :                :     pg_signal_info pg_info;
                                103                 :                : 
  424                           104         [ -  + ]:          49737 :     Assert(postgres_signal_arg > 0);
                                105         [ -  + ]:          49737 :     Assert(postgres_signal_arg < PG_NSIG);
                                106                 :                : 
                                107                 :                : #ifndef FRONTEND
                                108                 :                : 
                                109                 :                :     /*
                                110                 :                :      * We expect processes to set MyProcPid before calling pqsignal() or
                                111                 :                :      * before accepting signals.
                                112                 :                :      */
  811                           113         [ -  + ]:          49579 :     Assert(MyProcPid);
                                114   [ +  +  -  + ]:          49579 :     Assert(MyProcPid != PostmasterPid || !IsUnderPostmaster);
                                115                 :                : 
                                116         [ -  + ]:          49579 :     if (unlikely(MyProcPid != (int) getpid()))
                                117                 :                :     {
   21 andrew@dunslane.net       118                 :UNC           0 :         pqsignal(postgres_signal_arg, PG_SIG_DFL);
  811 nathan@postgresql.or      119                 :UBC           0 :         raise(postgres_signal_arg);
                                120                 :              0 :         return;
                                121                 :                :     }
                                122                 :                : #endif
                                123                 :                : 
                                124                 :                : #ifdef HAVE_SA_SIGINFO
                                125                 :                : 
                                126                 :                :     /*
                                127                 :                :      * If supported by the system, forward interesting information from the
                                128                 :                :      * system's extended signal information to our platform independent
                                129                 :                :      * format.
                                130                 :                :      */
   21 andrew@dunslane.net       131                 :GNC       49737 :     pg_info.pid = info->si_pid;
                                132                 :          49737 :     pg_info.uid = info->si_uid;
                                133                 :                : #else
                                134                 :                : 
                                135                 :                :     /*
                                136                 :                :      * Otherwise forward values indicating that we do not have the
                                137                 :                :      * information.
                                138                 :                :      */
                                139                 :                :     pg_info.pid = 0;
                                140                 :                :     pg_info.uid = 0;
                                141                 :                : #endif
                                142                 :                : 
                                143                 :          49737 :     (*pqsignal_handlers[postgres_signal_arg]) (postgres_signal_arg, &pg_info);
                                144                 :                : 
  811 nathan@postgresql.or      145                 :CBC       49736 :     errno = save_errno;
                                146                 :            158 : }
                                147                 :                : 
                                148                 :                : /*
                                149                 :                :  * Set up a signal handler, with SA_RESTART, for signal "signo"
                                150                 :                :  *
                                151                 :                :  * Note: the actual name of this function is either pqsignal_fe when
                                152                 :                :  * compiled with -DFRONTEND, or pqsignal_be when compiled without that.
                                153                 :                :  * This is to avoid a name collision with libpq's legacy-pqsignal.c.
                                154                 :                :  */
                                155                 :                : void
 4797 tgl@sss.pgh.pa.us         156                 :         350188 : pqsignal(int signo, pqsigfunc func)
                                157                 :                : {
                                158                 :                : #ifdef USE_SIGACTION
                                159                 :                :     struct sigaction act;
                                160                 :                : #else
                                161                 :                :     void        (*wrapper_func_ptr) (int);
                                162                 :                : #endif
   21 andrew@dunslane.net       163                 :GNC      350188 :     bool        is_ign = func == PG_SIG_IGN;
                                164                 :         350188 :     bool        is_dfl = func == PG_SIG_DFL;
                                165                 :                : 
  424 nathan@postgresql.or      166         [ -  + ]:CBC      350188 :     Assert(signo > 0);
  811                           167         [ -  + ]:         350188 :     Assert(signo < PG_NSIG);
                                168                 :                : 
                                169                 :                :     /* set up indirection handler */
   21 andrew@dunslane.net       170   [ +  +  +  + ]:GNC      350188 :     if (!(is_ign || is_dfl))
                                171                 :                :     {
  811 nathan@postgresql.or      172                 :CBC      260022 :         pqsignal_handlers[signo] = func;    /* assumed atomic */
                                173                 :                :     }
                                174                 :                : 
                                175                 :                :     /*
                                176                 :                :      * Configure system to either ignore/reset the signal handler, or to
                                177                 :                :      * forward it to wrapper_handler.
                                178                 :                :      */
                                179                 :                : #ifdef USE_SIGACTION
 4797 tgl@sss.pgh.pa.us         180                 :         350188 :     sigemptyset(&act.sa_mask);
 4707                           181                 :         350188 :     act.sa_flags = SA_RESTART;
                                182                 :                : 
   21 andrew@dunslane.net       183         [ +  + ]:GNC      350188 :     if (is_ign)
                                184                 :          57731 :         act.sa_handler = SIG_IGN;
                                185         [ +  + ]:         292457 :     else if (is_dfl)
                                186                 :          32435 :         act.sa_handler = SIG_DFL;
                                187                 :                : #ifdef USE_SIGINFO
                                188                 :                :     else
                                189                 :                :     {
   29                           190                 :         260022 :         act.sa_sigaction = wrapper_handler;
                                191                 :         260022 :         act.sa_flags |= SA_SIGINFO;
                                192                 :                :     }
                                193                 :                : #else
                                194                 :                :     else
                                195                 :                :         act.sa_handler = wrapper_handler;
                                196                 :                : #endif
                                197                 :                : 
                                198                 :                : #ifdef SA_NOCLDSTOP
 4797 tgl@sss.pgh.pa.us         199         [ +  + ]:CBC      350188 :     if (signo == SIGCHLD)
                                200                 :          33332 :         act.sa_flags |= SA_NOCLDSTOP;
                                201                 :                : #endif
  474 nathan@postgresql.or      202         [ -  + ]:         350188 :     if (sigaction(signo, &act, NULL) < 0)
  474 nathan@postgresql.or      203                 :UBC           0 :         Assert(false);          /* probably indicates coding error */
                                204                 :                : #else                           /* no USE_SIGACTION */
                                205                 :                : 
                                206                 :                :     /*
                                207                 :                :      * Forward to Windows native signal system, we need to send this though
                                208                 :                :      * wrapper handler as it it needs to take single argument only.
                                209                 :                :      */
                                210                 :                :     if (is_ign)
                                211                 :                :         wrapper_func_ptr = SIG_IGN;
                                212                 :                :     else if (is_dfl)
                                213                 :                :         wrapper_func_ptr = SIG_DFL;
                                214                 :                :     else
                                215                 :                :         wrapper_func_ptr = wrapper_handler;
                                216                 :                : 
                                217                 :                :     if (signal(signo, wrapper_func_ptr) == SIG_ERR)
                                218                 :                :         Assert(false);          /* probably indicates coding error */
                                219                 :                : #endif
 4797 tgl@sss.pgh.pa.us         220                 :CBC      350188 : }
        

Generated by: LCOV version 2.5.0-beta