LCOV - differential code coverage report
Current view: top level - src/port - pqsignal.c (source / functions) Coverage Total Hit UIC GIC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 85.2 % 27 23 4 23
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 3 3 3
Baseline: lcov-20250906-005545-baseline Branches: 66.7 % 24 16 8 16
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 80.0 % 5 4 1 4
(360..) days: 86.4 % 22 19 3 19
Function coverage date bins:
(360..) days: 100.0 % 3 3 3
Branch coverage date bins:
(30,360] days: 50.0 % 8 4 4 4
(360..) days: 75.0 % 16 12 4 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-2025, 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 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.
                                 82                 :                :  *
                                 83                 :                :  * This wrapper also handles restoring the value of errno.
                                 84                 :                :  */
                                 85                 :                : static void
  570 nathan@postgresql.or       86                 :GIC       38886 : wrapper_handler(SIGNAL_ARGS)
                                 87                 :                : {
                                 88                 :          38886 :     int         save_errno = errno;
                                 89                 :                : 
  183                            90         [ -  + ]:          38886 :     Assert(postgres_signal_arg > 0);
                                 91         [ -  + ]:          38886 :     Assert(postgres_signal_arg < PG_NSIG);
                                 92                 :                : 
                                 93                 :                : #ifndef FRONTEND
                                 94                 :                : 
                                 95                 :                :     /*
                                 96                 :                :      * We expect processes to set MyProcPid before calling pqsignal() or
                                 97                 :                :      * before accepting signals.
                                 98                 :                :      */
  570                            99         [ -  + ]:          38749 :     Assert(MyProcPid);
                                100   [ +  +  -  + ]:          38749 :     Assert(MyProcPid != PostmasterPid || !IsUnderPostmaster);
                                101                 :                : 
                                102         [ -  + ]:          38749 :     if (unlikely(MyProcPid != (int) getpid()))
                                103                 :                :     {
  570 nathan@postgresql.or      104                 :UIC           0 :         pqsignal(postgres_signal_arg, SIG_DFL);
                                105                 :              0 :         raise(postgres_signal_arg);
                                106                 :              0 :         return;
                                107                 :                :     }
                                108                 :                : #endif
                                109                 :                : 
  570 nathan@postgresql.or      110                 :GIC       38886 :     (*pqsignal_handlers[postgres_signal_arg]) (postgres_signal_arg);
                                111                 :                : 
                                112                 :          38886 :     errno = save_errno;
                                113                 :            137 : }
                                114                 :                : 
                                115                 :                : /*
                                116                 :                :  * Set up a signal handler, with SA_RESTART, for signal "signo"
                                117                 :                :  *
                                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.
                                121                 :                :  */
                                122                 :                : void
 4556 tgl@sss.pgh.pa.us         123                 :         286379 : pqsignal(int signo, pqsigfunc func)
                                124                 :                : {
                                125                 :                : #if !(defined(WIN32) && defined(FRONTEND))
                                126                 :                :     struct sigaction act;
                                127                 :                : #endif
                                128                 :                : 
  183 nathan@postgresql.or      129         [ -  + ]:         286379 :     Assert(signo > 0);
  570                           130         [ -  + ]:         286379 :     Assert(signo < PG_NSIG);
                                131                 :                : 
                                132   [ +  +  +  + ]:         286379 :     if (func != SIG_IGN && func != SIG_DFL)
                                133                 :                :     {
                                134                 :         213843 :         pqsignal_handlers[signo] = func;    /* assumed atomic */
                                135                 :         213843 :         func = wrapper_handler;
                                136                 :                :     }
                                137                 :                : 
                                138                 :                : #if !(defined(WIN32) && defined(FRONTEND))
 4556 tgl@sss.pgh.pa.us         139                 :         286379 :     act.sa_handler = func;
                                140                 :         286379 :     sigemptyset(&act.sa_mask);
 4466                           141                 :         286379 :     act.sa_flags = SA_RESTART;
                                142                 :                : #ifdef SA_NOCLDSTOP
 4556                           143         [ +  + ]:         286379 :     if (signo == SIGCHLD)
                                144                 :          26542 :         act.sa_flags |= SA_NOCLDSTOP;
                                145                 :                : #endif
  233 nathan@postgresql.or      146         [ -  + ]:         286379 :     if (sigaction(signo, &act, NULL) < 0)
  233 nathan@postgresql.or      147                 :UIC           0 :         Assert(false);          /* probably indicates coding error */
                                148                 :                : #else
                                149                 :                :     /* Forward to Windows native signal system. */
                                150                 :                :     if (signal(signo, func) == SIG_ERR)
                                151                 :                :         Assert(false);          /* probably indicates coding error */
                                152                 :                : #endif
 4556 tgl@sss.pgh.pa.us         153                 :GIC      286379 : }
        

Generated by: LCOV version 2.4-beta