LCOV - code coverage report
Current view: top level - src/backend/main - main.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 45.4 % 119 54
Test Date: 2026-01-26 10:56:24 Functions: 71.4 % 7 5
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 53.7 % 54 29

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * main.c
       4                 :             :  *        Stub main() routine for the postgres executable.
       5                 :             :  *
       6                 :             :  * This does some essential startup tasks for any incarnation of postgres
       7                 :             :  * (postmaster, standalone backend, standalone bootstrap process, or a
       8                 :             :  * separately exec'd child of a postmaster) and then dispatches to the
       9                 :             :  * proper FooMain() routine for the incarnation.
      10                 :             :  *
      11                 :             :  *
      12                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      13                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
      14                 :             :  *
      15                 :             :  *
      16                 :             :  * IDENTIFICATION
      17                 :             :  *        src/backend/main/main.c
      18                 :             :  *
      19                 :             :  *-------------------------------------------------------------------------
      20                 :             :  */
      21                 :             : #include "postgres.h"
      22                 :             : 
      23                 :             : #include <unistd.h>
      24                 :             : 
      25                 :             : #if defined(WIN32)
      26                 :             : #include <crtdbg.h>
      27                 :             : #endif
      28                 :             : 
      29                 :             : #if defined(__NetBSD__)
      30                 :             : #include <sys/param.h>
      31                 :             : #endif
      32                 :             : 
      33                 :             : #include "bootstrap/bootstrap.h"
      34                 :             : #include "common/username.h"
      35                 :             : #include "miscadmin.h"
      36                 :             : #include "postmaster/postmaster.h"
      37                 :             : #include "tcop/tcopprot.h"
      38                 :             : #include "utils/help_config.h"
      39                 :             : #include "utils/memutils.h"
      40                 :             : #include "utils/pg_locale.h"
      41                 :             : #include "utils/ps_status.h"
      42                 :             : 
      43                 :             : 
      44                 :             : const char *progname;
      45                 :             : static bool reached_main = false;
      46                 :             : 
      47                 :             : /* names of special must-be-first options for dispatching to subprograms */
      48                 :             : static const char *const DispatchOptionNames[] =
      49                 :             : {
      50                 :             :         [DISPATCH_CHECK] = "check",
      51                 :             :         [DISPATCH_BOOT] = "boot",
      52                 :             :         [DISPATCH_FORKCHILD] = "forkchild",
      53                 :             :         [DISPATCH_DESCRIBE_CONFIG] = "describe-config",
      54                 :             :         [DISPATCH_SINGLE] = "single",
      55                 :             :         /* DISPATCH_POSTMASTER has no name */
      56                 :             : };
      57                 :             : 
      58                 :             : StaticAssertDecl(lengthof(DispatchOptionNames) == DISPATCH_POSTMASTER,
      59                 :             :                                  "array length mismatch");
      60                 :             : 
      61                 :             : static void startup_hacks(const char *progname);
      62                 :             : static void init_locale(const char *categoryname, int category, const char *locale);
      63                 :             : static void help(const char *progname);
      64                 :             : static void check_root(const char *progname);
      65                 :             : 
      66                 :             : 
      67                 :             : /*
      68                 :             :  * Any Postgres server process begins execution here.
      69                 :             :  */
      70                 :             : int
      71                 :           8 : main(int argc, char *argv[])
      72                 :             : {
      73                 :           8 :         bool            do_check_root = true;
      74                 :           8 :         DispatchOption dispatch_option = DISPATCH_POSTMASTER;
      75                 :             : 
      76                 :           8 :         reached_main = true;
      77                 :             : 
      78                 :             :         /*
      79                 :             :          * If supported on the current platform, set up a handler to be called if
      80                 :             :          * the backend/postmaster crashes with a fatal signal or exception.
      81                 :             :          */
      82                 :             : #if defined(WIN32)
      83                 :             :         pgwin32_install_crashdump_handler();
      84                 :             : #endif
      85                 :             : 
      86                 :           8 :         progname = get_progname(argv[0]);
      87                 :             : 
      88                 :             :         /*
      89                 :             :          * Platform-specific startup hacks
      90                 :             :          */
      91                 :           8 :         startup_hacks(progname);
      92                 :             : 
      93                 :             :         /*
      94                 :             :          * Remember the physical location of the initially given argv[] array for
      95                 :             :          * possible use by ps display.  On some platforms, the argv[] storage must
      96                 :             :          * be overwritten in order to set the process title for ps. In such cases
      97                 :             :          * save_ps_display_args makes and returns a new copy of the argv[] array.
      98                 :             :          *
      99                 :             :          * save_ps_display_args may also move the environment strings to make
     100                 :             :          * extra room. Therefore this should be done as early as possible during
     101                 :             :          * startup, to avoid entanglements with code that might save a getenv()
     102                 :             :          * result pointer.
     103                 :             :          */
     104                 :           8 :         argv = save_ps_display_args(argc, argv);
     105                 :             : 
     106                 :             :         /*
     107                 :             :          * Fire up essential subsystems: error and memory management
     108                 :             :          *
     109                 :             :          * Code after this point is allowed to use elog/ereport, though
     110                 :             :          * localization of messages may not work right away, and messages won't go
     111                 :             :          * anywhere but stderr until GUC settings get loaded.
     112                 :             :          */
     113                 :           8 :         MyProcPid = getpid();
     114                 :           8 :         MemoryContextInit();
     115                 :             : 
     116                 :             :         /*
     117                 :             :          * Set reference point for stack-depth checking.  (There's no point in
     118                 :             :          * enabling this before error reporting works.)
     119                 :             :          */
     120                 :           8 :         (void) set_stack_base();
     121                 :             : 
     122                 :             :         /*
     123                 :             :          * Set up locale information
     124                 :             :          */
     125                 :           8 :         set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
     126                 :             : 
     127                 :             :         /*
     128                 :             :          * Collation is handled by pg_locale.c, and the behavior is dependent on
     129                 :             :          * the provider. strcoll(), etc., should not be called directly.
     130                 :             :          */
     131                 :           8 :         init_locale("LC_COLLATE", LC_COLLATE, "C");
     132                 :             : 
     133                 :             :         /*
     134                 :             :          * In the postmaster, absorb the environment value for LC_CTYPE.
     135                 :             :          * Individual backends will change it later to pg_database.datctype, but
     136                 :             :          * the postmaster cannot do that.  If we leave it set to "C" then message
     137                 :             :          * localization might not work well in the postmaster.
     138                 :             :          */
     139                 :           8 :         init_locale("LC_CTYPE", LC_CTYPE, "");
     140                 :             : 
     141                 :             :         /*
     142                 :             :          * LC_MESSAGES will get set later during GUC option processing, but we set
     143                 :             :          * it here to allow startup error messages to be localized.
     144                 :             :          */
     145                 :             : #ifdef LC_MESSAGES
     146                 :           8 :         init_locale("LC_MESSAGES", LC_MESSAGES, "");
     147                 :             : #endif
     148                 :             : 
     149                 :             :         /* We keep these set to "C" always.  See pg_locale.c for explanation. */
     150                 :           8 :         init_locale("LC_MONETARY", LC_MONETARY, "C");
     151                 :           8 :         init_locale("LC_NUMERIC", LC_NUMERIC, "C");
     152                 :           8 :         init_locale("LC_TIME", LC_TIME, "C");
     153                 :             : 
     154                 :             :         /*
     155                 :             :          * Now that we have absorbed as much as we wish to from the locale
     156                 :             :          * environment, remove any LC_ALL setting, so that the environment
     157                 :             :          * variables installed by pg_perm_setlocale have force.
     158                 :             :          */
     159                 :           8 :         unsetenv("LC_ALL");
     160                 :             : 
     161                 :             :         /*
     162                 :             :          * Catch standard options before doing much else, in particular before we
     163                 :             :          * insist on not being root.
     164                 :             :          */
     165         [ -  + ]:           8 :         if (argc > 1)
     166                 :             :         {
     167   [ +  -  -  + ]:           8 :                 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
     168                 :             :                 {
     169                 :           0 :                         help(progname);
     170                 :           0 :                         exit(0);
     171                 :             :                 }
     172   [ +  -  +  + ]:           8 :                 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
     173                 :             :                 {
     174                 :           2 :                         fputs(PG_BACKEND_VERSIONSTR, stdout);
     175                 :           2 :                         exit(0);
     176                 :             :                 }
     177                 :             : 
     178                 :             :                 /*
     179                 :             :                  * In addition to the above, we allow "--describe-config" and "-C var"
     180                 :             :                  * to be called by root.  This is reasonably safe since these are
     181                 :             :                  * read-only activities.  The -C case is important because pg_ctl may
     182                 :             :                  * try to invoke it while still holding administrator privileges on
     183                 :             :                  * Windows.  Note that while -C can normally be in any argv position,
     184                 :             :                  * if you want to bypass the root check you must put it first.  This
     185                 :             :                  * reduces the risk that we might misinterpret some other mode's -C
     186                 :             :                  * switch as being the postmaster/postgres one.
     187                 :             :                  */
     188         [ -  + ]:           6 :                 if (strcmp(argv[1], "--describe-config") == 0)
     189                 :           0 :                         do_check_root = false;
     190   [ +  -  +  - ]:           6 :                 else if (argc > 2 && strcmp(argv[1], "-C") == 0)
     191                 :           0 :                         do_check_root = false;
     192                 :           6 :         }
     193                 :             : 
     194                 :             :         /*
     195                 :             :          * Make sure we are not running as root, unless it's safe for the selected
     196                 :             :          * option.
     197                 :             :          */
     198         [ -  + ]:           6 :         if (do_check_root)
     199                 :           6 :                 check_root(progname);
     200                 :             : 
     201                 :             :         /*
     202                 :             :          * Dispatch to one of various subprograms depending on first argument.
     203                 :             :          */
     204                 :             : 
     205   [ +  -  +  -  :           6 :         if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-')
                   +  + ]
     206                 :           4 :                 dispatch_option = parse_dispatch_option(&argv[1][2]);
     207                 :             : 
     208   [ +  +  -  -  :           6 :         switch (dispatch_option)
                +  -  + ]
     209                 :             :         {
     210                 :             :                 case DISPATCH_CHECK:
     211                 :           2 :                         BootstrapModeMain(argc, argv, true);
     212                 :             :                         break;
     213                 :             :                 case DISPATCH_BOOT:
     214                 :           1 :                         BootstrapModeMain(argc, argv, false);
     215                 :             :                         break;
     216                 :             :                 case DISPATCH_FORKCHILD:
     217                 :             : #ifdef EXEC_BACKEND
     218                 :             :                         SubPostmasterMain(argc, argv);
     219                 :             : #else
     220                 :           0 :                         Assert(false);          /* should never happen */
     221                 :             : #endif
     222                 :           0 :                         break;
     223                 :             :                 case DISPATCH_DESCRIBE_CONFIG:
     224                 :           0 :                         GucInfoMain();
     225                 :             :                         break;
     226                 :             :                 case DISPATCH_SINGLE:
     227                 :           2 :                         PostgresSingleUserMain(argc, argv,
     228                 :           1 :                                                                    strdup(get_user_name_or_exit(progname)));
     229                 :             :                         break;
     230                 :             :                 case DISPATCH_POSTMASTER:
     231                 :           2 :                         PostmasterMain(argc, argv);
     232                 :             :                         break;
     233                 :             :         }
     234                 :             : 
     235                 :             :         /* the functions above should not return */
     236                 :           0 :         abort();
     237                 :             : }
     238                 :             : 
     239                 :             : /*
     240                 :             :  * Returns the matching DispatchOption value for the given option name.  If no
     241                 :             :  * match is found, DISPATCH_POSTMASTER is returned.
     242                 :             :  */
     243                 :             : DispatchOption
     244                 :           5 : parse_dispatch_option(const char *name)
     245                 :             : {
     246   [ +  +  -  +  :          19 :         for (int i = 0; i < lengthof(DispatchOptionNames); i++)
                      + ]
     247                 :             :         {
     248                 :             :                 /*
     249                 :             :                  * Unlike the other dispatch options, "forkchild" takes an argument,
     250                 :             :                  * so we just look for the prefix for that one.  For non-EXEC_BACKEND
     251                 :             :                  * builds, we never want to return DISPATCH_FORKCHILD, so skip over it
     252                 :             :                  * in that case.
     253                 :             :                  */
     254         [ +  + ]:          14 :                 if (i == DISPATCH_FORKCHILD)
     255                 :             :                 {
     256                 :             : #ifdef EXEC_BACKEND
     257                 :             :                         if (strncmp(DispatchOptionNames[DISPATCH_FORKCHILD], name,
     258                 :             :                                                 strlen(DispatchOptionNames[DISPATCH_FORKCHILD])) == 0)
     259                 :             :                                 return DISPATCH_FORKCHILD;
     260                 :             : #endif
     261                 :           2 :                         continue;
     262                 :             :                 }
     263                 :             : 
     264         [ +  + ]:          12 :                 if (strcmp(DispatchOptionNames[i], name) == 0)
     265                 :           4 :                         return (DispatchOption) i;
     266                 :           8 :         }
     267                 :             : 
     268                 :             :         /* no match means this is a postmaster */
     269                 :           1 :         return DISPATCH_POSTMASTER;
     270                 :           5 : }
     271                 :             : 
     272                 :             : /*
     273                 :             :  * Place platform-specific startup hacks here.  This is the right
     274                 :             :  * place to put code that must be executed early in the launch of any new
     275                 :             :  * server process.  Note that this code will NOT be executed when a backend
     276                 :             :  * or sub-bootstrap process is forked, unless we are in a fork/exec
     277                 :             :  * environment (ie EXEC_BACKEND is defined).
     278                 :             :  *
     279                 :             :  * XXX The need for code here is proof that the platform in question
     280                 :             :  * is too brain-dead to provide a standard C execution environment
     281                 :             :  * without help.  Avoid adding more here, if you can.
     282                 :             :  */
     283                 :             : static void
     284                 :           8 : startup_hacks(const char *progname)
     285                 :             : {
     286                 :             :         /*
     287                 :             :          * Windows-specific execution environment hacking.
     288                 :             :          */
     289                 :             : #ifdef WIN32
     290                 :             :         {
     291                 :             :                 WSADATA         wsaData;
     292                 :             :                 int                     err;
     293                 :             : 
     294                 :             :                 /* Make output streams unbuffered by default */
     295                 :             :                 setvbuf(stdout, NULL, _IONBF, 0);
     296                 :             :                 setvbuf(stderr, NULL, _IONBF, 0);
     297                 :             : 
     298                 :             :                 /* Prepare Winsock */
     299                 :             :                 err = WSAStartup(MAKEWORD(2, 2), &wsaData);
     300                 :             :                 if (err != 0)
     301                 :             :                 {
     302                 :             :                         write_stderr("%s: WSAStartup failed: %d\n",
     303                 :             :                                                  progname, err);
     304                 :             :                         exit(1);
     305                 :             :                 }
     306                 :             : 
     307                 :             :                 /*
     308                 :             :                  * By default abort() only generates a crash-dump in *non* debug
     309                 :             :                  * builds. As our Assert() / ExceptionalCondition() uses abort(),
     310                 :             :                  * leaving the default in place would make debugging harder.
     311                 :             :                  *
     312                 :             :                  * MINGW's own C runtime doesn't have _set_abort_behavior(). When
     313                 :             :                  * targeting Microsoft's UCRT with mingw, it never links to the debug
     314                 :             :                  * version of the library and thus doesn't need the call to
     315                 :             :                  * _set_abort_behavior() either.
     316                 :             :                  */
     317                 :             : #if !defined(__MINGW32__) && !defined(__MINGW64__)
     318                 :             :                 _set_abort_behavior(_CALL_REPORTFAULT | _WRITE_ABORT_MSG,
     319                 :             :                                                         _CALL_REPORTFAULT | _WRITE_ABORT_MSG);
     320                 :             : #endif                                                  /* !defined(__MINGW32__) &&
     321                 :             :                                                                  * !defined(__MINGW64__) */
     322                 :             : 
     323                 :             :                 /*
     324                 :             :                  * SEM_FAILCRITICALERRORS causes more errors to be reported to
     325                 :             :                  * callers.
     326                 :             :                  *
     327                 :             :                  * We used to also specify SEM_NOGPFAULTERRORBOX, but that prevents
     328                 :             :                  * windows crash reporting from working. Which includes registered
     329                 :             :                  * just-in-time debuggers, making it unnecessarily hard to debug
     330                 :             :                  * problems on windows. Now we try to disable sources of popups
     331                 :             :                  * separately below (note that SEM_NOGPFAULTERRORBOX did not actually
     332                 :             :                  * prevent all sources of such popups).
     333                 :             :                  */
     334                 :             :                 SetErrorMode(SEM_FAILCRITICALERRORS);
     335                 :             : 
     336                 :             :                 /*
     337                 :             :                  * Show errors on stderr instead of popup box (note this doesn't
     338                 :             :                  * affect errors originating in the C runtime, see below).
     339                 :             :                  */
     340                 :             :                 _set_error_mode(_OUT_TO_STDERR);
     341                 :             : 
     342                 :             :                 /*
     343                 :             :                  * In DEBUG builds, errors, including assertions, C runtime errors are
     344                 :             :                  * reported via _CrtDbgReport. By default such errors are displayed
     345                 :             :                  * with a popup (even with NOGPFAULTERRORBOX), preventing forward
     346                 :             :                  * progress. Instead report such errors stderr (and the debugger).
     347                 :             :                  * This is C runtime specific and thus the above incantations aren't
     348                 :             :                  * sufficient to suppress these popups.
     349                 :             :                  */
     350                 :             :                 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
     351                 :             :                 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
     352                 :             :                 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
     353                 :             :                 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
     354                 :             :                 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
     355                 :             :                 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
     356                 :             :         }
     357                 :             : #endif                                                  /* WIN32 */
     358                 :           8 : }
     359                 :             : 
     360                 :             : 
     361                 :             : /*
     362                 :             :  * Make the initial permanent setting for a locale category.  If that fails,
     363                 :             :  * perhaps due to LC_foo=invalid in the environment, use locale C.  If even
     364                 :             :  * that fails, perhaps due to out-of-memory, the entire startup fails with it.
     365                 :             :  * When this returns, we are guaranteed to have a setting for the given
     366                 :             :  * category's environment variable.
     367                 :             :  */
     368                 :             : static void
     369                 :          48 : init_locale(const char *categoryname, int category, const char *locale)
     370                 :             : {
     371   [ -  +  #  # ]:          48 :         if (pg_perm_setlocale(category, locale) == NULL &&
     372                 :           0 :                 pg_perm_setlocale(category, "C") == NULL)
     373   [ #  #  #  # ]:           0 :                 elog(FATAL, "could not adopt \"%s\" locale nor C locale for %s",
     374                 :             :                          locale, categoryname);
     375                 :          48 : }
     376                 :             : 
     377                 :             : 
     378                 :             : 
     379                 :             : /*
     380                 :             :  * Help display should match the options accepted by PostmasterMain()
     381                 :             :  * and PostgresMain().
     382                 :             :  *
     383                 :             :  * XXX On Windows, non-ASCII localizations of these messages only display
     384                 :             :  * correctly if the console output code page covers the necessary characters.
     385                 :             :  * Messages emitted in write_console() do not exhibit this problem.
     386                 :             :  */
     387                 :             : static void
     388                 :           0 : help(const char *progname)
     389                 :             : {
     390                 :           0 :         printf(_("%s is the PostgreSQL server.\n\n"), progname);
     391                 :           0 :         printf(_("Usage:\n  %s [OPTION]...\n\n"), progname);
     392                 :           0 :         printf(_("Options:\n"));
     393                 :           0 :         printf(_("  -B NBUFFERS        number of shared buffers\n"));
     394                 :           0 :         printf(_("  -c NAME=VALUE      set run-time parameter\n"));
     395                 :           0 :         printf(_("  -C NAME            print value of run-time parameter, then exit\n"));
     396                 :           0 :         printf(_("  -d 1-5             debugging level\n"));
     397                 :           0 :         printf(_("  -D DATADIR         database directory\n"));
     398                 :           0 :         printf(_("  -e                 use European date input format (DMY)\n"));
     399                 :           0 :         printf(_("  -F                 turn fsync off\n"));
     400                 :           0 :         printf(_("  -h HOSTNAME        host name or IP address to listen on\n"));
     401                 :           0 :         printf(_("  -i                 enable TCP/IP connections (deprecated)\n"));
     402                 :           0 :         printf(_("  -k DIRECTORY       Unix-domain socket location\n"));
     403                 :             : #ifdef USE_SSL
     404                 :           0 :         printf(_("  -l                 enable SSL connections\n"));
     405                 :             : #endif
     406                 :           0 :         printf(_("  -N MAX-CONNECT     maximum number of allowed connections\n"));
     407                 :           0 :         printf(_("  -p PORT            port number to listen on\n"));
     408                 :           0 :         printf(_("  -s                 show statistics after each query\n"));
     409                 :           0 :         printf(_("  -S WORK-MEM        set amount of memory for sorts (in kB)\n"));
     410                 :           0 :         printf(_("  -V, --version      output version information, then exit\n"));
     411                 :           0 :         printf(_("  --NAME=VALUE       set run-time parameter\n"));
     412                 :           0 :         printf(_("  --describe-config  describe configuration parameters, then exit\n"));
     413                 :           0 :         printf(_("  -?, --help         show this help, then exit\n"));
     414                 :             : 
     415                 :           0 :         printf(_("\nDeveloper options:\n"));
     416                 :           0 :         printf(_("  -f s|i|o|b|t|n|m|h forbid use of some plan types\n"));
     417                 :           0 :         printf(_("  -O                 allow system table structure changes\n"));
     418                 :           0 :         printf(_("  -P                 disable system indexes\n"));
     419                 :           0 :         printf(_("  -t pa|pl|ex        show timings after each query\n"));
     420                 :           0 :         printf(_("  -T                 send SIGABRT to all backend processes if one dies\n"));
     421                 :           0 :         printf(_("  -W NUM             wait NUM seconds to allow attach from a debugger\n"));
     422                 :             : 
     423                 :           0 :         printf(_("\nOptions for single-user mode:\n"));
     424                 :           0 :         printf(_("  --single           selects single-user mode (must be first argument)\n"));
     425                 :           0 :         printf(_("  DBNAME             database name (defaults to user name)\n"));
     426                 :           0 :         printf(_("  -d 0-5             override debugging level\n"));
     427                 :           0 :         printf(_("  -E                 echo statement before execution\n"));
     428                 :           0 :         printf(_("  -j                 do not use newline as interactive query delimiter\n"));
     429                 :           0 :         printf(_("  -r FILENAME        send stdout and stderr to given file\n"));
     430                 :             : 
     431                 :           0 :         printf(_("\nOptions for bootstrapping mode:\n"));
     432                 :           0 :         printf(_("  --boot             selects bootstrapping mode (must be first argument)\n"));
     433                 :           0 :         printf(_("  --check            selects check mode (must be first argument)\n"));
     434                 :           0 :         printf(_("  DBNAME             database name (mandatory argument in bootstrapping mode)\n"));
     435                 :           0 :         printf(_("  -r FILENAME        send stdout and stderr to given file\n"));
     436                 :             : 
     437                 :           0 :         printf(_("\nPlease read the documentation for the complete list of run-time\n"
     438                 :             :                          "configuration settings and how to set them on the command line or in\n"
     439                 :             :                          "the configuration file.\n\n"
     440                 :             :                          "Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
     441                 :           0 :         printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
     442                 :           0 : }
     443                 :             : 
     444                 :             : 
     445                 :             : 
     446                 :             : static void
     447                 :           6 : check_root(const char *progname)
     448                 :             : {
     449                 :             : #ifndef WIN32
     450         [ +  - ]:           6 :         if (geteuid() == 0)
     451                 :             :         {
     452                 :           0 :                 write_stderr("\"root\" execution of the PostgreSQL server is not permitted.\n"
     453                 :             :                                          "The server must be started under an unprivileged user ID to prevent\n"
     454                 :             :                                          "possible system security compromise.  See the documentation for\n"
     455                 :             :                                          "more information on how to properly start the server.\n");
     456                 :           0 :                 exit(1);
     457                 :             :         }
     458                 :             : 
     459                 :             :         /*
     460                 :             :          * Also make sure that real and effective uids are the same. Executing as
     461                 :             :          * a setuid program from a root shell is a security hole, since on many
     462                 :             :          * platforms a nefarious subroutine could setuid back to root if real uid
     463                 :             :          * is root.  (Since nobody actually uses postgres as a setuid program,
     464                 :             :          * trying to actively fix this situation seems more trouble than it's
     465                 :             :          * worth; we'll just expend the effort to check for it.)
     466                 :             :          */
     467         [ +  - ]:           6 :         if (getuid() != geteuid())
     468                 :             :         {
     469                 :           0 :                 write_stderr("%s: real and effective user IDs must match\n",
     470                 :           0 :                                          progname);
     471                 :           0 :                 exit(1);
     472                 :             :         }
     473                 :             : #else                                                   /* WIN32 */
     474                 :             :         if (pgwin32_is_admin())
     475                 :             :         {
     476                 :             :                 write_stderr("Execution of PostgreSQL by a user with administrative permissions is not\n"
     477                 :             :                                          "permitted.\n"
     478                 :             :                                          "The server must be started under an unprivileged user ID to prevent\n"
     479                 :             :                                          "possible system security compromises.  See the documentation for\n"
     480                 :             :                                          "more information on how to properly start the server.\n");
     481                 :             :                 exit(1);
     482                 :             :         }
     483                 :             : #endif                                                  /* WIN32 */
     484                 :           6 : }
     485                 :             : 
     486                 :             : /*
     487                 :             :  * At least on linux, set_ps_display() breaks /proc/$pid/environ. The
     488                 :             :  * sanitizer library uses /proc/$pid/environ to implement getenv() as it wants
     489                 :             :  * to work independent of libc. Depending on which sanitizers are enabled,
     490                 :             :  * the sanitizer library may not get initialized until after we've called
     491                 :             :  * set_ps_display(), preventing the sanitizer from seeing environment-supplied
     492                 :             :  * options.
     493                 :             :  *
     494                 :             :  * We can work around that by defining __ubsan_default_options, a weak symbol
     495                 :             :  * libsanitizer uses to get defaults from the application, and return
     496                 :             :  * getenv("UBSAN_OPTIONS"). But only if main already was reached, so that we
     497                 :             :  * don't end up relying on a not-yet-working getenv().
     498                 :             :  *
     499                 :             :  * On the other hand, with different sanitizers enabled, libsanitizer can
     500                 :             :  * call this so early that it's not fully initialized itself, resulting in
     501                 :             :  * recursion and a core dump within libsanitizer.  To prevent that, ensure
     502                 :             :  * that this function is built without any sanitizer callbacks in it.
     503                 :             :  *
     504                 :             :  * As this function won't get called when not running a sanitizer, it doesn't
     505                 :             :  * seem necessary to only compile it conditionally.
     506                 :             :  */
     507                 :             : const char *__ubsan_default_options(void);
     508                 :             : 
     509                 :             : #if __has_attribute(disable_sanitizer_instrumentation)
     510                 :             : __attribute__((disable_sanitizer_instrumentation))
     511                 :             : #endif
     512                 :             : const char *
     513                 :           0 : __ubsan_default_options(void)
     514                 :             : {
     515                 :             :         /* don't call libc before it's guaranteed to be initialized */
     516         [ #  # ]:           0 :         if (!reached_main)
     517                 :           0 :                 return "";
     518                 :             : 
     519                 :           0 :         return getenv("UBSAN_OPTIONS");
     520                 :           0 : }
        

Generated by: LCOV version 2.3.2-1