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