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[])
 

Variables

const char * progname
 

Function Documentation

◆ check_root()

static void check_root ( const char *  progname)
static

Definition at line 357 of file main.c.

References pgwin32_is_admin(), and write_stderr.

Referenced by main().

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

◆ help()

static void help ( const char *  progname)
static

Definition at line 297 of file main.c.

References _, and printf.

Referenced by main().

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

◆ init_locale()

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

Definition at line 278 of file main.c.

References elog, FATAL, and pg_perm_setlocale().

Referenced by main().

279 {
280  if (pg_perm_setlocale(category, locale) == NULL &&
281  pg_perm_setlocale(category, "C") == NULL)
282  elog(FATAL, "could not adopt \"%s\" locale nor C locale for %s",
283  locale, categoryname);
284 }
char * pg_perm_setlocale(int category, const char *locale)
Definition: pg_locale.c:143
#define FATAL
Definition: elog.h:49
#define elog(elevel,...)
Definition: elog.h:232
static char * locale
Definition: initdb.c:126

◆ main()

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

Definition at line 59 of file main.c.

References BootstrapModeMain(), 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(), PostgresSingleUserMain(), PostmasterMain(), progname, save_ps_display_args(), set_pglocale_pgservice(), startup_hacks(), generate_unaccent_rules::stdout, and unsetenv.

60 {
61  bool do_check_root = true;
62 
63  /*
64  * If supported on the current platform, set up a handler to be called if
65  * the backend/postmaster crashes with a fatal signal or exception.
66  */
67 #if defined(WIN32) && defined(HAVE_MINIDUMP_TYPE)
69 #endif
70 
71  progname = get_progname(argv[0]);
72 
73  /*
74  * Platform-specific startup hacks
75  */
77 
78  /*
79  * Remember the physical location of the initially given argv[] array for
80  * possible use by ps display. On some platforms, the argv[] storage must
81  * be overwritten in order to set the process title for ps. In such cases
82  * save_ps_display_args makes and returns a new copy of the argv[] array.
83  *
84  * save_ps_display_args may also move the environment strings to make
85  * extra room. Therefore this should be done as early as possible during
86  * startup, to avoid entanglements with code that might save a getenv()
87  * result pointer.
88  */
89  argv = save_ps_display_args(argc, argv);
90 
91  /*
92  * Fire up essential subsystems: error and memory management
93  *
94  * Code after this point is allowed to use elog/ereport, though
95  * localization of messages may not work right away, and messages won't go
96  * anywhere but stderr until GUC settings get loaded.
97  */
99 
100  /*
101  * Set up locale information
102  */
103  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
104 
105  /*
106  * In the postmaster, absorb the environment values for LC_COLLATE and
107  * LC_CTYPE. Individual backends will change these later to settings
108  * taken from pg_database, but the postmaster cannot do that. If we leave
109  * these set to "C" then message localization might not work well in the
110  * postmaster.
111  */
112  init_locale("LC_COLLATE", LC_COLLATE, "");
113  init_locale("LC_CTYPE", LC_CTYPE, "");
114 
115  /*
116  * LC_MESSAGES will get set later during GUC option processing, but we set
117  * it here to allow startup error messages to be localized.
118  */
119 #ifdef LC_MESSAGES
120  init_locale("LC_MESSAGES", LC_MESSAGES, "");
121 #endif
122 
123  /*
124  * We keep these set to "C" always, except transiently in pg_locale.c; see
125  * that file for explanations.
126  */
127  init_locale("LC_MONETARY", LC_MONETARY, "C");
128  init_locale("LC_NUMERIC", LC_NUMERIC, "C");
129  init_locale("LC_TIME", LC_TIME, "C");
130 
131  /*
132  * Now that we have absorbed as much as we wish to from the locale
133  * environment, remove any LC_ALL setting, so that the environment
134  * variables installed by pg_perm_setlocale have force.
135  */
136  unsetenv("LC_ALL");
137 
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 pgwin32_install_crashdump_handler(void)
Definition: crashdump.c:180
const char * progname
Definition: main.c:46
void MemoryContextInit(void)
Definition: mcxt.c:99
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:297
char ** save_ps_display_args(int argc, char **argv)
Definition: ps_status.c:131
void check_strxfrm_bug(void)
Definition: pg_locale.c:1187
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1215
#define PG_BACKEND_VERSIONSTR
Definition: port.h:135
static void check_root(const char *progname)
Definition: main.c:357
void PostgresSingleUserMain(int argc, char *argv[], const char *username)
Definition: postgres.c:3928
void PostmasterMain(int argc, char *argv[])
Definition: postmaster.c:581
static void init_locale(const char *categoryname, int category, const char *locale)
Definition: main.c:278
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:433
void BootstrapModeMain(int argc, char *argv[], bool check_only)
Definition: bootstrap.c:203
#define unsetenv(x)
Definition: win32_port.h:498
static void startup_hacks(const char *progname)
Definition: main.c:217
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 217 of file main.c.

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

Referenced by main().

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  /* In case of general protection fault, don't show GUI popup box */
241  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
242 
243 #if defined(_M_AMD64) && _MSC_VER == 1800
244 
245  /*----------
246  * Avoid crashing in certain floating-point operations if we were
247  * compiled for x64 with MS Visual Studio 2013 and are running on
248  * Windows prior to 7/2008R2 SP1 on an AVX2-capable CPU.
249  *
250  * Ref: https://connect.microsoft.com/VisualStudio/feedback/details/811093/visual-studio-2013-rtm-c-x64-code-generation-bug-for-avx2-instructions
251  *----------
252  */
253  if (!IsWindows7SP1OrGreater())
254  {
255  _set_FMA3_enable(0);
256  }
257 #endif /* defined(_M_AMD64) && _MSC_VER == 1800 */
258 
259  }
260 #endif /* WIN32 */
261 
262  /*
263  * Initialize dummy_spinlock, in case we are on a platform where we have
264  * to use the fallback implementation of pg_memory_barrier().
265  */
267 }
const char * progname
Definition: main.c:46
#define SpinLockInit(lock)
Definition: spin.h:60
#define write_stderr(str)
Definition: parallel.c:186
slock_t dummy_spinlock
Definition: s_lock.c:63

Variable Documentation

◆ progname