PostgreSQL Source Code git master
main.c File Reference
#include "postgres.h"
#include <unistd.h>
#include "bootstrap/bootstrap.h"
#include "common/username.h"
#include "miscadmin.h"
#include "postmaster/postmaster.h"
#include "tcop/tcopprot.h"
#include "utils/help_config.h"
#include "utils/memutils.h"
#include "utils/pg_locale.h"
#include "utils/ps_status.h"
Include dependency graph for main.c:

Go to the source code of this file.

Functions

 StaticAssertDecl (lengthof(DispatchOptionNames)==DISPATCH_POSTMASTER, "array length mismatch")
 
static void startup_hacks (const char *progname)
 
static void init_locale (const char *categoryname, int category, const char *locale)
 
static void help (const char *progname)
 
static void check_root (const char *progname)
 
int main (int argc, char *argv[])
 
DispatchOption parse_dispatch_option (const char *name)
 
const char * __ubsan_default_options (void)
 

Variables

const char * progname
 
static bool reached_main = false
 
static const char *const DispatchOptionNames []
 

Function Documentation

◆ __ubsan_default_options()

const char * __ubsan_default_options ( void  )

Definition at line 503 of file main.c.

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}
static bool reached_main
Definition: main.c:45

References reached_main.

◆ check_root()

static void check_root ( const char *  progname)
static

Definition at line 446 of file main.c.

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}
#define write_stderr(str)
Definition: parallel.c:186
exit(1)
const char * progname
Definition: main.c:44
int pgwin32_is_admin(void)
Definition: win32security.c:49

References exit(), pgwin32_is_admin(), progname, and write_stderr.

Referenced by main().

◆ help()

static void help ( const char *  progname)
static

Definition at line 387 of file main.c.

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}
#define _(x)
Definition: elog.c:90
#define printf(...)
Definition: port.h:244

References _, printf, and progname.

Referenced by main().

◆ init_locale()

static void init_locale ( const char *  categoryname,
int  category,
const char *  locale 
)
static

Definition at line 368 of file main.c.

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}
#define FATAL
Definition: elog.h:41
#define elog(elevel,...)
Definition: elog.h:225
static char * locale
Definition: initdb.c:140
char * pg_perm_setlocale(int category, const char *locale)
Definition: pg_locale.c:207

References elog, FATAL, locale, and pg_perm_setlocale().

Referenced by main().

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 71 of file main.c.

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}
void BootstrapModeMain(int argc, char *argv[], bool check_only)
Definition: bootstrap.c:198
#define Assert(condition)
Definition: c.h:815
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1171
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:429
void pgwin32_install_crashdump_handler(void)
Definition: crashdump.c:178
int MyProcPid
Definition: globals.c:46
void GucInfoMain(void)
Definition: help_config.c:46
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
static void help(const char *progname)
Definition: main.c:387
static void startup_hacks(const char *progname)
Definition: main.c:283
DispatchOption parse_dispatch_option(const char *name)
Definition: main.c:243
void MemoryContextInit(void)
Definition: mcxt.c:339
#define PG_BACKEND_VERSIONSTR
Definition: port.h:143
const char * get_progname(const char *argv0)
Definition: path.c:575
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
#define unsetenv(x)
Definition: win32_port.h:546

References Assert, BootstrapModeMain(), check_root(), DISPATCH_BOOT, DISPATCH_CHECK, DISPATCH_DESCRIBE_CONFIG, DISPATCH_FORKCHILD, DISPATCH_POSTMASTER, DISPATCH_SINGLE, exit(), get_progname(), get_user_name_or_exit(), GucInfoMain(), help(), init_locale(), MemoryContextInit(), MyProcPid, parse_dispatch_option(), PG_BACKEND_VERSIONSTR, PG_TEXTDOMAIN, pgwin32_install_crashdump_handler(), PostgresSingleUserMain(), PostmasterMain(), progname, reached_main, save_ps_display_args(), set_pglocale_pgservice(), set_stack_base(), startup_hacks(), generate_unaccent_rules::stdout, and unsetenv.

◆ parse_dispatch_option()

DispatchOption parse_dispatch_option ( const char *  name)

Definition at line 243 of file main.c.

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}
#define lengthof(array)
Definition: c.h:745
int i
Definition: isn.c:72
static const char *const DispatchOptionNames[]
Definition: main.c:48
const char * name

References DISPATCH_FORKCHILD, DISPATCH_POSTMASTER, DispatchOptionNames, i, lengthof, and name.

Referenced by BootstrapModeMain(), main(), PostmasterMain(), and process_postgres_switches().

◆ startup_hacks()

static void startup_hacks ( const char *  progname)
static

Definition at line 283 of file main.c.

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}
void err(int eval, const char *fmt,...)
Definition: err.c:43

References err(), exit(), progname, generate_unaccent_rules::stdout, and write_stderr.

Referenced by main().

◆ StaticAssertDecl()

StaticAssertDecl ( lengthof(DispatchOptionNames = =DISPATCH_POSTMASTER,
"array length mismatch"   
)

Variable Documentation

◆ DispatchOptionNames

const char* const DispatchOptionNames[]
static
Initial value:
=
{
[DISPATCH_CHECK] = "check",
[DISPATCH_BOOT] = "boot",
[DISPATCH_FORKCHILD] = "forkchild",
[DISPATCH_DESCRIBE_CONFIG] = "describe-config",
[DISPATCH_SINGLE] = "single",
}

Definition at line 48 of file main.c.

Referenced by parse_dispatch_option().

◆ progname

◆ reached_main

bool reached_main = false
static

Definition at line 45 of file main.c.

Referenced by __ubsan_default_options(), and main().