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/s_lock.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[])
 

Variables

const char * progname
 

Function Documentation

◆ check_root()

static void check_root ( const char *  progname)
static

Definition at line 368 of file main.c.

References pgwin32_is_admin(), and write_stderr.

Referenced by main().

369 {
370 #ifndef WIN32
371  if (geteuid() == 0)
372  {
373  write_stderr("\"root\" execution of the PostgreSQL server is not permitted.\n"
374  "The server must be started under an unprivileged user ID to prevent\n"
375  "possible system security compromise. See the documentation for\n"
376  "more information on how to properly start the server.\n");
377  exit(1);
378  }
379 
380  /*
381  * Also make sure that real and effective uids are the same. Executing as
382  * a setuid program from a root shell is a security hole, since on many
383  * platforms a nefarious subroutine could setuid back to root if real uid
384  * is root. (Since nobody actually uses postgres as a setuid program,
385  * trying to actively fix this situation seems more trouble than it's
386  * worth; we'll just expend the effort to check for it.)
387  */
388  if (getuid() != geteuid())
389  {
390  write_stderr("%s: real and effective user IDs must match\n",
391  progname);
392  exit(1);
393  }
394 #else /* WIN32 */
395  if (pgwin32_is_admin())
396  {
397  write_stderr("Execution of PostgreSQL by a user with administrative permissions is not\n"
398  "permitted.\n"
399  "The server must be started under an unprivileged user ID to prevent\n"
400  "possible system security compromises. See the documentation for\n"
401  "more information on how to properly start the server.\n");
402  exit(1);
403  }
404 #endif /* WIN32 */
405 }
const char * progname
Definition: main.c:47
#define write_stderr(str)
Definition: parallel.c:181
int pgwin32_is_admin(void)
Definition: win32security.c:49

◆ help()

static void help ( const char *  progname)
static

Definition at line 308 of file main.c.

References _, and printf.

Referenced by main().

309 {
310  printf(_("%s is the PostgreSQL server.\n\n"), progname);
311  printf(_("Usage:\n %s [OPTION]...\n\n"), progname);
312  printf(_("Options:\n"));
313  printf(_(" -B NBUFFERS number of shared buffers\n"));
314  printf(_(" -c NAME=VALUE set run-time parameter\n"));
315  printf(_(" -C NAME print value of run-time parameter, then exit\n"));
316  printf(_(" -d 1-5 debugging level\n"));
317  printf(_(" -D DATADIR database directory\n"));
318  printf(_(" -e use European date input format (DMY)\n"));
319  printf(_(" -F turn fsync off\n"));
320  printf(_(" -h HOSTNAME host name or IP address to listen on\n"));
321  printf(_(" -i enable TCP/IP connections\n"));
322  printf(_(" -k DIRECTORY Unix-domain socket location\n"));
323 #ifdef USE_SSL
324  printf(_(" -l enable SSL connections\n"));
325 #endif
326  printf(_(" -N MAX-CONNECT maximum number of allowed connections\n"));
327  printf(_(" -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n"));
328  printf(_(" -p PORT port number to listen on\n"));
329  printf(_(" -s show statistics after each query\n"));
330  printf(_(" -S WORK-MEM set amount of memory for sorts (in kB)\n"));
331  printf(_(" -V, --version output version information, then exit\n"));
332  printf(_(" --NAME=VALUE set run-time parameter\n"));
333  printf(_(" --describe-config describe configuration parameters, then exit\n"));
334  printf(_(" -?, --help show this help, then exit\n"));
335 
336  printf(_("\nDeveloper options:\n"));
337  printf(_(" -f s|i|n|m|h forbid use of some plan types\n"));
338  printf(_(" -n do not reinitialize shared memory after abnormal exit\n"));
339  printf(_(" -O allow system table structure changes\n"));
340  printf(_(" -P disable system indexes\n"));
341  printf(_(" -t pa|pl|ex show timings after each query\n"));
342  printf(_(" -T send SIGSTOP to all backend processes if one dies\n"));
343  printf(_(" -W NUM wait NUM seconds to allow attach from a debugger\n"));
344 
345  printf(_("\nOptions for single-user mode:\n"));
346  printf(_(" --single selects single-user mode (must be first argument)\n"));
347  printf(_(" DBNAME database name (defaults to user name)\n"));
348  printf(_(" -d 0-5 override debugging level\n"));
349  printf(_(" -E echo statement before execution\n"));
350  printf(_(" -j do not use newline as interactive query delimiter\n"));
351  printf(_(" -r FILENAME send stdout and stderr to given file\n"));
352 
353  printf(_("\nOptions for bootstrapping mode:\n"));
354  printf(_(" --boot selects bootstrapping mode (must be first argument)\n"));
355  printf(_(" DBNAME database name (mandatory argument in bootstrapping mode)\n"));
356  printf(_(" -r FILENAME send stdout and stderr to given file\n"));
357  printf(_(" -x NUM internal use\n"));
358 
359  printf(_("\nPlease read the documentation for the complete list of run-time\n"
360  "configuration settings and how to set them on the command line or in\n"
361  "the configuration file.\n\n"
362  "Report bugs to <pgsql-bugs@lists.postgresql.org>.\n"));
363 }
const char * progname
Definition: main.c:47
#define printf(...)
Definition: port.h:198
#define _(x)
Definition: elog.c:87

◆ init_locale()

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

Definition at line 289 of file main.c.

References elog, FATAL, and pg_perm_setlocale().

Referenced by main().

290 {
291  if (pg_perm_setlocale(category, locale) == NULL &&
292  pg_perm_setlocale(category, "C") == NULL)
293  elog(FATAL, "could not adopt \"%s\" locale nor C locale for %s",
294  locale, categoryname);
295 }
char * pg_perm_setlocale(int category, const char *locale)
Definition: pg_locale.c:160
#define FATAL
Definition: elog.h:52
#define elog(elevel,...)
Definition: elog.h:228
static char * locale
Definition: initdb.c:125

◆ main()

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

Definition at line 60 of file main.c.

References AuxiliaryProcessMain(), check_root(), check_strxfrm_bug(), get_progname(), get_user_name_or_exit(), GucInfoMain(), help(), init_locale(), MemoryContextInit(), PG_BACKEND_VERSIONSTR, PG_TEXTDOMAIN, pgwin32_install_crashdump_handler(), pgwin32_signal_initialize(), PostgresMain(), PostmasterMain(), progname, save_ps_display_args(), set_pglocale_pgservice(), startup_hacks(), generate_unaccent_rules::stdout, and unsetenv.

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

◆ startup_hacks()

static void startup_hacks ( const char *  progname)
static

Definition at line 228 of file main.c.

References dummy_spinlock, SpinLockInit, generate_unaccent_rules::stdout, and write_stderr.

Referenced by main().

229 {
230  /*
231  * Windows-specific execution environment hacking.
232  */
233 #ifdef WIN32
234  {
235  WSADATA wsaData;
236  int err;
237 
238  /* Make output streams unbuffered by default */
239  setvbuf(stdout, NULL, _IONBF, 0);
240  setvbuf(stderr, NULL, _IONBF, 0);
241 
242  /* Prepare Winsock */
243  err = WSAStartup(MAKEWORD(2, 2), &wsaData);
244  if (err != 0)
245  {
246  write_stderr("%s: WSAStartup failed: %d\n",
247  progname, err);
248  exit(1);
249  }
250 
251  /* In case of general protection fault, don't show GUI popup box */
252  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
253 
254 #if defined(_M_AMD64) && _MSC_VER == 1800
255 
256  /*----------
257  * Avoid crashing in certain floating-point operations if we were
258  * compiled for x64 with MS Visual Studio 2013 and are running on
259  * Windows prior to 7/2008R2 SP1 on an AVX2-capable CPU.
260  *
261  * Ref: https://connect.microsoft.com/VisualStudio/feedback/details/811093/visual-studio-2013-rtm-c-x64-code-generation-bug-for-avx2-instructions
262  *----------
263  */
264  if (!IsWindows7SP1OrGreater())
265  {
266  _set_FMA3_enable(0);
267  }
268 #endif /* defined(_M_AMD64) && _MSC_VER == 1800 */
269 
270  }
271 #endif /* WIN32 */
272 
273  /*
274  * Initialize dummy_spinlock, in case we are on a platform where we have
275  * to use the fallback implementation of pg_memory_barrier().
276  */
278 }
const char * progname
Definition: main.c:47
#define SpinLockInit(lock)
Definition: spin.h:60
#define write_stderr(str)
Definition: parallel.c:181
slock_t dummy_spinlock
Definition: s_lock.c:63

Variable Documentation

◆ progname

const char* progname

Definition at line 47 of file main.c.

Referenced by main().