PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-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"
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;
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 */
121
122 /*
123 * Set up locale information
124 */
125 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 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 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 init_locale("LC_MESSAGES", LC_MESSAGES, "");
147#endif
148
149 /* We keep these set to "C" always. See pg_locale.c for explanation. */
150 init_locale("LC_MONETARY", LC_MONETARY, "C");
151 init_locale("LC_NUMERIC", LC_NUMERIC, "C");
152 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 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 if (argc > 1)
166 {
167 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
168 {
169 help(progname);
170 exit(0);
171 }
172 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
173 {
175 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 if (strcmp(argv[1], "--describe-config") == 0)
189 do_check_root = false;
190 else if (argc > 2 && strcmp(argv[1], "-C") == 0)
191 do_check_root = false;
192 }
193
194 /*
195 * Make sure we are not running as root, unless it's safe for the selected
196 * option.
197 */
198 if (do_check_root)
200
201 /*
202 * Dispatch to one of various subprograms depending on first argument.
203 */
204
205 if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-')
207
208 switch (dispatch_option)
209 {
210 case DISPATCH_CHECK:
211 BootstrapModeMain(argc, argv, true);
212 break;
213 case DISPATCH_BOOT:
214 BootstrapModeMain(argc, argv, false);
215 break;
217#ifdef EXEC_BACKEND
218 SubPostmasterMain(argc, argv);
219#else
220 Assert(false); /* should never happen */
221#endif
222 break;
224 GucInfoMain();
225 break;
226 case DISPATCH_SINGLE:
227 PostgresSingleUserMain(argc, argv,
229 break;
231 PostmasterMain(argc, argv);
232 break;
233 }
234
235 /* the functions above should not return */
236 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 */
245{
246 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 if (i == DISPATCH_FORKCHILD)
255 {
256#ifdef EXEC_BACKEND
259 return DISPATCH_FORKCHILD;
260#endif
261 continue;
262 }
263
264 if (strcmp(DispatchOptionNames[i], name) == 0)
265 return (DispatchOption) i;
266 }
267
268 /* no match means this is a postmaster */
269 return DISPATCH_POSTMASTER;
270}
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 */
283static void
285{
286 /*
287 * Windows-specific execution environment hacking.
288 */
289#ifdef WIN32
290 {
292 int err;
293
294 /* Make output streams unbuffered by default */
295 setvbuf(stdout, 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__)
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 */
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 */
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 */
356 }
357#endif /* WIN32 */
358}
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 */
368static void
369init_locale(const char *categoryname, int category, const char *locale)
370{
371 if (pg_perm_setlocale(category, locale) == NULL &&
372 pg_perm_setlocale(category, "C") == NULL)
373 elog(FATAL, "could not adopt \"%s\" locale nor C locale for %s",
374 locale, categoryname);
375}
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 */
387static void
388help(const char *progname)
389{
390 printf(_("%s is the PostgreSQL server.\n\n"), progname);
391 printf(_("Usage:\n %s [OPTION]...\n\n"), progname);
392 printf(_("Options:\n"));
393 printf(_(" -B NBUFFERS number of shared buffers\n"));
394 printf(_(" -c NAME=VALUE set run-time parameter\n"));
395 printf(_(" -C NAME print value of run-time parameter, then exit\n"));
396 printf(_(" -d 1-5 debugging level\n"));
397 printf(_(" -D DATADIR database directory\n"));
398 printf(_(" -e use European date input format (DMY)\n"));
399 printf(_(" -F turn fsync off\n"));
400 printf(_(" -h HOSTNAME host name or IP address to listen on\n"));
401 printf(_(" -i enable TCP/IP connections (deprecated)\n"));
402 printf(_(" -k DIRECTORY Unix-domain socket location\n"));
403#ifdef USE_SSL
404 printf(_(" -l enable SSL connections\n"));
405#endif
406 printf(_(" -N MAX-CONNECT maximum number of allowed connections\n"));
407 printf(_(" -p PORT port number to listen on\n"));
408 printf(_(" -s show statistics after each query\n"));
409 printf(_(" -S WORK-MEM set amount of memory for sorts (in kB)\n"));
410 printf(_(" -V, --version output version information, then exit\n"));
411 printf(_(" --NAME=VALUE set run-time parameter\n"));
412 printf(_(" --describe-config describe configuration parameters, then exit\n"));
413 printf(_(" -?, --help show this help, then exit\n"));
414
415 printf(_("\nDeveloper options:\n"));
416 printf(_(" -f s|i|o|b|t|n|m|h forbid use of some plan types\n"));
417 printf(_(" -O allow system table structure changes\n"));
418 printf(_(" -P disable system indexes\n"));
419 printf(_(" -t pa|pl|ex show timings after each query\n"));
420 printf(_(" -T send SIGABRT to all backend processes if one dies\n"));
421 printf(_(" -W NUM wait NUM seconds to allow attach from a debugger\n"));
422
423 printf(_("\nOptions for single-user mode:\n"));
424 printf(_(" --single selects single-user mode (must be first argument)\n"));
425 printf(_(" DBNAME database name (defaults to user name)\n"));
426 printf(_(" -d 0-5 override debugging level\n"));
427 printf(_(" -E echo statement before execution\n"));
428 printf(_(" -j do not use newline as interactive query delimiter\n"));
429 printf(_(" -r FILENAME send stdout and stderr to given file\n"));
430
431 printf(_("\nOptions for bootstrapping mode:\n"));
432 printf(_(" --boot selects bootstrapping mode (must be first argument)\n"));
433 printf(_(" --check selects check mode (must be first argument)\n"));
434 printf(_(" DBNAME database name (mandatory argument in bootstrapping mode)\n"));
435 printf(_(" -r FILENAME send stdout and stderr to given file\n"));
436
437 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 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
442}
443
444
445
446static void
448{
449#ifndef WIN32
450 if (geteuid() == 0)
451 {
452 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 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 if (getuid() != geteuid())
468 {
469 write_stderr("%s: real and effective user IDs must match\n",
470 progname);
471 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}
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 */
507const char *__ubsan_default_options(void);
508
509#if __has_attribute(disable_sanitizer_instrumentation)
511#endif
512const char *
514{
515 /* don't call libc before it's guaranteed to be initialized */
516 if (!reached_main)
517 return "";
518
519 return getenv("UBSAN_OPTIONS");
520}
static void help(void)
Definition pg_config.c:71
#define write_stderr(str)
Definition parallel.c:186
void BootstrapModeMain(int argc, char *argv[], bool check_only)
Definition bootstrap.c:202
#define Assert(condition)
Definition c.h:873
#define PG_TEXTDOMAIN(domain)
Definition c.h:1203
#define lengthof(array)
Definition c.h:803
#define StaticAssertDecl(condition, errmessage)
Definition c.h:942
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition exec.c:430
int main(void)
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:47
void GucInfoMain(void)
Definition help_config.c:31
int i
Definition isn.c:77
static void init_locale(const char *categoryname, int category, const char *locale)
Definition main.c:369
static void check_root(const char *progname)
Definition main.c:447
const char * __ubsan_default_options(void)
Definition main.c:513
static bool reached_main
Definition main.c:45
static void startup_hacks(const char *progname)
Definition main.c:284
static const char *const DispatchOptionNames[]
Definition main.c:48
DispatchOption parse_dispatch_option(const char *name)
Definition main.c:244
const char * progname
Definition main.c:44
void MemoryContextInit(void)
Definition mcxt.c:359
char * pg_perm_setlocale(int category, const char *locale)
Definition pg_locale.c:172
#define PG_BACKEND_VERSIONSTR
Definition port.h:144
const char * get_progname(const char *argv0)
Definition path.c:652
#define printf(...)
Definition port.h:266
void PostgresSingleUserMain(int argc, char *argv[], const char *username)
Definition postgres.c:4064
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
static int fb(int x)
char ** save_ps_display_args(int argc, char **argv)
Definition ps_status.c:130
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:543
int pgwin32_is_admin(void)