PostgreSQL Source Code  git master
main.c File Reference
#include "postgres.h"
#include <unistd.h>
#include "bootstrap/bootstrap.h"
#include "common/username.h"
#include "port/atomics.h"
#include "postmaster/postmaster.h"
#include "storage/spin.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

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[])
 
const char * __ubsan_default_options (void)
 

Variables

const char * progname
 
static bool reached_main = false
 

Function Documentation

◆ __ubsan_default_options()

const char * __ubsan_default_options ( void  )

Definition at line 443 of file main.c.

444 {
445  /* don't call libc before it's guaranteed to be initialized */
446  if (!reached_main)
447  return "";
448 
449  return getenv("UBSAN_OPTIONS");
450 }
static bool reached_main
Definition: main.c:46

References reached_main.

◆ check_root()

static void check_root ( const char *  progname)
static

Definition at line 386 of file main.c.

387 {
388 #ifndef WIN32
389  if (geteuid() == 0)
390  {
391  write_stderr("\"root\" execution of the PostgreSQL server is not permitted.\n"
392  "The server must be started under an unprivileged user ID to prevent\n"
393  "possible system security compromise. See the documentation for\n"
394  "more information on how to properly start the server.\n");
395  exit(1);
396  }
397 
398  /*
399  * Also make sure that real and effective uids are the same. Executing as
400  * a setuid program from a root shell is a security hole, since on many
401  * platforms a nefarious subroutine could setuid back to root if real uid
402  * is root. (Since nobody actually uses postgres as a setuid program,
403  * trying to actively fix this situation seems more trouble than it's
404  * worth; we'll just expend the effort to check for it.)
405  */
406  if (getuid() != geteuid())
407  {
408  write_stderr("%s: real and effective user IDs must match\n",
409  progname);
410  exit(1);
411  }
412 #else /* WIN32 */
413  if (pgwin32_is_admin())
414  {
415  write_stderr("Execution of PostgreSQL by a user with administrative permissions is not\n"
416  "permitted.\n"
417  "The server must be started under an unprivileged user ID to prevent\n"
418  "possible system security compromises. See the documentation for\n"
419  "more information on how to properly start the server.\n");
420  exit(1);
421  }
422 #endif /* WIN32 */
423 }
#define write_stderr(str)
Definition: parallel.c:184
exit(1)
const char * progname
Definition: main.c:45
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 327 of file main.c.

328 {
329  printf(_("%s is the PostgreSQL server.\n\n"), progname);
330  printf(_("Usage:\n %s [OPTION]...\n\n"), progname);
331  printf(_("Options:\n"));
332  printf(_(" -B NBUFFERS number of shared buffers\n"));
333  printf(_(" -c NAME=VALUE set run-time parameter\n"));
334  printf(_(" -C NAME print value of run-time parameter, then exit\n"));
335  printf(_(" -d 1-5 debugging level\n"));
336  printf(_(" -D DATADIR database directory\n"));
337  printf(_(" -e use European date input format (DMY)\n"));
338  printf(_(" -F turn fsync off\n"));
339  printf(_(" -h HOSTNAME host name or IP address to listen on\n"));
340  printf(_(" -i enable TCP/IP connections (deprecated)\n"));
341  printf(_(" -k DIRECTORY Unix-domain socket location\n"));
342 #ifdef USE_SSL
343  printf(_(" -l enable SSL connections\n"));
344 #endif
345  printf(_(" -N MAX-CONNECT maximum number of allowed connections\n"));
346  printf(_(" -p PORT port number to listen on\n"));
347  printf(_(" -s show statistics after each query\n"));
348  printf(_(" -S WORK-MEM set amount of memory for sorts (in kB)\n"));
349  printf(_(" -V, --version output version information, then exit\n"));
350  printf(_(" --NAME=VALUE set run-time parameter\n"));
351  printf(_(" --describe-config describe configuration parameters, then exit\n"));
352  printf(_(" -?, --help show this help, then exit\n"));
353 
354  printf(_("\nDeveloper options:\n"));
355  printf(_(" -f s|i|o|b|t|n|m|h forbid use of some plan types\n"));
356  printf(_(" -O allow system table structure changes\n"));
357  printf(_(" -P disable system indexes\n"));
358  printf(_(" -t pa|pl|ex show timings after each query\n"));
359  printf(_(" -T send SIGABRT to all backend processes if one dies\n"));
360  printf(_(" -W NUM wait NUM seconds to allow attach from a debugger\n"));
361 
362  printf(_("\nOptions for single-user mode:\n"));
363  printf(_(" --single selects single-user mode (must be first argument)\n"));
364  printf(_(" DBNAME database name (defaults to user name)\n"));
365  printf(_(" -d 0-5 override debugging level\n"));
366  printf(_(" -E echo statement before execution\n"));
367  printf(_(" -j do not use newline as interactive query delimiter\n"));
368  printf(_(" -r FILENAME send stdout and stderr to given file\n"));
369 
370  printf(_("\nOptions for bootstrapping mode:\n"));
371  printf(_(" --boot selects bootstrapping mode (must be first argument)\n"));
372  printf(_(" --check selects check mode (must be first argument)\n"));
373  printf(_(" DBNAME database name (mandatory argument in bootstrapping mode)\n"));
374  printf(_(" -r FILENAME send stdout and stderr to given file\n"));
375 
376  printf(_("\nPlease read the documentation for the complete list of run-time\n"
377  "configuration settings and how to set them on the command line or in\n"
378  "the configuration file.\n\n"
379  "Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
380  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
381 }
#define _(x)
Definition: elog.c:91
#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 308 of file main.c.

309 {
310  if (pg_perm_setlocale(category, locale) == NULL &&
311  pg_perm_setlocale(category, "C") == NULL)
312  elog(FATAL, "could not adopt \"%s\" locale nor C locale for %s",
313  locale, categoryname);
314 }
#define FATAL
Definition: elog.h:41
static char * locale
Definition: initdb.c:140
char * pg_perm_setlocale(int category, const char *locale)
Definition: pg_locale.c:213

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

Referenced by main().

◆ main()

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

Definition at line 59 of file main.c.

60 {
61  bool do_check_root = true;
62 
63  reached_main = true;
64 
65  /*
66  * If supported on the current platform, set up a handler to be called if
67  * the backend/postmaster crashes with a fatal signal or exception.
68  */
69 #if defined(WIN32)
71 #endif
72 
73  progname = get_progname(argv[0]);
74 
75  /*
76  * Platform-specific startup hacks
77  */
79 
80  /*
81  * Remember the physical location of the initially given argv[] array for
82  * possible use by ps display. On some platforms, the argv[] storage must
83  * be overwritten in order to set the process title for ps. In such cases
84  * save_ps_display_args makes and returns a new copy of the argv[] array.
85  *
86  * save_ps_display_args may also move the environment strings to make
87  * extra room. Therefore this should be done as early as possible during
88  * startup, to avoid entanglements with code that might save a getenv()
89  * result pointer.
90  */
91  argv = save_ps_display_args(argc, argv);
92 
93  /*
94  * Fire up essential subsystems: error and memory management
95  *
96  * Code after this point is allowed to use elog/ereport, though
97  * localization of messages may not work right away, and messages won't go
98  * anywhere but stderr until GUC settings get loaded.
99  */
101 
102  /*
103  * Set up locale information
104  */
105  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
106 
107  /*
108  * In the postmaster, absorb the environment values for LC_COLLATE and
109  * LC_CTYPE. Individual backends will change these later to settings
110  * taken from pg_database, but the postmaster cannot do that. If we leave
111  * these set to "C" then message localization might not work well in the
112  * postmaster.
113  */
114  init_locale("LC_COLLATE", LC_COLLATE, "");
115  init_locale("LC_CTYPE", LC_CTYPE, "");
116 
117  /*
118  * LC_MESSAGES will get set later during GUC option processing, but we set
119  * it here to allow startup error messages to be localized.
120  */
121 #ifdef LC_MESSAGES
122  init_locale("LC_MESSAGES", LC_MESSAGES, "");
123 #endif
124 
125  /*
126  * We keep these set to "C" always, except transiently in pg_locale.c; see
127  * that file for explanations.
128  */
129  init_locale("LC_MONETARY", LC_MONETARY, "C");
130  init_locale("LC_NUMERIC", LC_NUMERIC, "C");
131  init_locale("LC_TIME", LC_TIME, "C");
132 
133  /*
134  * Now that we have absorbed as much as we wish to from the locale
135  * environment, remove any LC_ALL setting, so that the environment
136  * variables installed by pg_perm_setlocale have force.
137  */
138  unsetenv("LC_ALL");
139 
140  /*
141  * Catch standard options before doing much else, in particular before we
142  * insist on not being root.
143  */
144  if (argc > 1)
145  {
146  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
147  {
148  help(progname);
149  exit(0);
150  }
151  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
152  {
154  exit(0);
155  }
156 
157  /*
158  * In addition to the above, we allow "--describe-config" and "-C var"
159  * to be called by root. This is reasonably safe since these are
160  * read-only activities. The -C case is important because pg_ctl may
161  * try to invoke it while still holding administrator privileges on
162  * Windows. Note that while -C can normally be in any argv position,
163  * if you want to bypass the root check you must put it first. This
164  * reduces the risk that we might misinterpret some other mode's -C
165  * switch as being the postmaster/postgres one.
166  */
167  if (strcmp(argv[1], "--describe-config") == 0)
168  do_check_root = false;
169  else if (argc > 2 && strcmp(argv[1], "-C") == 0)
170  do_check_root = false;
171  }
172 
173  /*
174  * Make sure we are not running as root, unless it's safe for the selected
175  * option.
176  */
177  if (do_check_root)
179 
180  /*
181  * Dispatch to one of various subprograms depending on first argument.
182  */
183 
184  if (argc > 1 && strcmp(argv[1], "--check") == 0)
185  BootstrapModeMain(argc, argv, true);
186  else if (argc > 1 && strcmp(argv[1], "--boot") == 0)
187  BootstrapModeMain(argc, argv, false);
188 #ifdef EXEC_BACKEND
189  else if (argc > 1 && strncmp(argv[1], "--fork", 6) == 0)
190  SubPostmasterMain(argc, argv);
191 #endif
192  else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
193  GucInfoMain();
194  else if (argc > 1 && strcmp(argv[1], "--single") == 0)
195  PostgresSingleUserMain(argc, argv,
197  else
198  PostmasterMain(argc, argv);
199  /* the functions above should not return */
200  abort();
201 }
void BootstrapModeMain(int argc, char *argv[], bool check_only)
Definition: bootstrap.c:203
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1227
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:436
void pgwin32_install_crashdump_handler(void)
Definition: crashdump.c:178
void GucInfoMain(void)
Definition: help_config.c:46
static void init_locale(const char *categoryname, int category, const char *locale)
Definition: main.c:308
static void check_root(const char *progname)
Definition: main.c:386
static void help(const char *progname)
Definition: main.c:327
static void startup_hacks(const char *progname)
Definition: main.c:217
void MemoryContextInit(void)
Definition: mcxt.c:286
const char * get_progname(const char *argv0)
Definition: path.c:574
#define PG_BACKEND_VERSIONSTR
Definition: port.h:143
void PostgresSingleUserMain(int argc, char *argv[], const char *username)
Definition: postgres.c:4014
void PostmasterMain(int argc, char *argv[])
Definition: postmaster.c:591
char ** save_ps_display_args(int argc, char **argv)
Definition: ps_status.c:118
const char * get_user_name_or_exit(const char *progname)
Definition: username.c:74
#define unsetenv(x)
Definition: win32_port.h:538

References BootstrapModeMain(), check_root(), exit(), get_progname(), get_user_name_or_exit(), GucInfoMain(), help(), init_locale(), MemoryContextInit(), PG_BACKEND_VERSIONSTR, PG_TEXTDOMAIN, pgwin32_install_crashdump_handler(), PostgresSingleUserMain(), PostmasterMain(), progname, reached_main, save_ps_display_args(), set_pglocale_pgservice(), startup_hacks(), generate_unaccent_rules::stdout, and unsetenv.

◆ startup_hacks()

static void startup_hacks ( const char *  progname)
static

Definition at line 217 of file main.c.

218 {
219  /*
220  * Windows-specific execution environment hacking.
221  */
222 #ifdef WIN32
223  {
224  WSADATA wsaData;
225  int err;
226 
227  /* Make output streams unbuffered by default */
228  setvbuf(stdout, NULL, _IONBF, 0);
229  setvbuf(stderr, NULL, _IONBF, 0);
230 
231  /* Prepare Winsock */
232  err = WSAStartup(MAKEWORD(2, 2), &wsaData);
233  if (err != 0)
234  {
235  write_stderr("%s: WSAStartup failed: %d\n",
236  progname, err);
237  exit(1);
238  }
239 
240  /*
241  * By default abort() only generates a crash-dump in *non* debug
242  * builds. As our Assert() / ExceptionalCondition() uses abort(),
243  * leaving the default in place would make debugging harder.
244  *
245  * MINGW's own C runtime doesn't have _set_abort_behavior(). When
246  * targeting Microsoft's UCRT with mingw, it never links to the debug
247  * version of the library and thus doesn't need the call to
248  * _set_abort_behavior() either.
249  */
250 #if !defined(__MINGW32__) && !defined(__MINGW64__)
251  _set_abort_behavior(_CALL_REPORTFAULT | _WRITE_ABORT_MSG,
252  _CALL_REPORTFAULT | _WRITE_ABORT_MSG);
253 #endif /* !defined(__MINGW32__) &&
254  * !defined(__MINGW64__) */
255 
256  /*
257  * SEM_FAILCRITICALERRORS causes more errors to be reported to
258  * callers.
259  *
260  * We used to also specify SEM_NOGPFAULTERRORBOX, but that prevents
261  * windows crash reporting from working. Which includes registered
262  * just-in-time debuggers, making it unnecessarily hard to debug
263  * problems on windows. Now we try to disable sources of popups
264  * separately below (note that SEM_NOGPFAULTERRORBOX did not actually
265  * prevent all sources of such popups).
266  */
267  SetErrorMode(SEM_FAILCRITICALERRORS);
268 
269  /*
270  * Show errors on stderr instead of popup box (note this doesn't
271  * affect errors originating in the C runtime, see below).
272  */
273  _set_error_mode(_OUT_TO_STDERR);
274 
275  /*
276  * In DEBUG builds, errors, including assertions, C runtime errors are
277  * reported via _CrtDbgReport. By default such errors are displayed
278  * with a popup (even with NOGPFAULTERRORBOX), preventing forward
279  * progress. Instead report such errors stderr (and the debugger).
280  * This is C runtime specific and thus the above incantations aren't
281  * sufficient to suppress these popups.
282  */
283  _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
284  _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
285  _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
286  _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
287  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
288  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
289  }
290 #endif /* WIN32 */
291 
292  /*
293  * Initialize dummy_spinlock, in case we are on a platform where we have
294  * to use the fallback implementation of pg_memory_barrier().
295  */
297 }
void err(int eval, const char *fmt,...)
Definition: err.c:43
slock_t dummy_spinlock
Definition: s_lock.c:65
#define SpinLockInit(lock)
Definition: spin.h:60

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

Referenced by main().

Variable Documentation

◆ progname

◆ reached_main

bool reached_main = false
static

Definition at line 46 of file main.c.

Referenced by __ubsan_default_options(), and main().