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