1
/*-------------------------------------------------------------------------
4
* Stub main() routine for the postgres executable.
6
* This does some essential startup tasks for any incarnation of postgres
7
* (postmaster, standalone backend, or standalone bootstrap mode) and then
8
* dispatches to the proper FooMain() routine for the incarnation.
11
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
12
* Portions Copyright (c) 1994, Regents of the University of California
16
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.94 2004-12-31 21:59:53 pgsql Exp $
18
*-------------------------------------------------------------------------
26
#if defined(__alpha) && defined(__osf__) /* no __alpha__ ? */
27
#include <sys/sysinfo.h>
28
#include "machine/hal_sysinfo.h"
33
#if defined(__NetBSD__)
34
#include <sys/param.h>
37
#include "bootstrap/bootstrap.h"
38
#include "miscadmin.h"
40
#include "postmaster/postmaster.h"
41
#include "tcop/tcopprot.h"
42
#include "utils/help_config.h"
43
#include "utils/ps_status.h"
45
#include "libpq/pqsignal.h"
51
main(int argc, char *argv[])
58
char *pw_name_persist;
61
* Place platform-specific startup hacks here. This is the right
62
* place to put code that must be executed early in launch of either a
63
* postmaster, a standalone backend, or a standalone bootstrap run.
64
* Note that this code will NOT be executed when a backend or
65
* sub-bootstrap run is forked by the postmaster.
67
* XXX The need for code here is proof that the platform in question is
68
* too brain-dead to provide a standard C execution environment
69
* without help. Avoid adding more here, if you can.
72
#if defined(__alpha) /* no __alpha__ ? */
74
int buffer[] = {SSIN_UACPROC, UAC_SIGBUS | UAC_NOPRINT};
83
* On some platforms, unaligned memory accesses result in a kernel
84
* trap; the default kernel behavior is to emulate the memory
85
* access, but this results in a significant performance
86
* penalty. We ought to fix PG not to make such unaligned memory
87
* accesses, so this code disables the kernel emulation: unaligned
88
* accesses will result in SIGBUS instead.
93
syscall(SYS_sysmips, MIPS_FIXADE, 0, NULL, NULL, NULL);
96
#if defined(__alpha) /* no __alpha__ ? */
97
if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
98
(unsigned long) NULL) < 0)
99
write_stderr("%s: setsysinfo failed: %s\n",
100
argv[0], strerror(errno));
102
#endif /* NOFIXADE */
109
/* Make output streams unbuffered by default */
110
setvbuf(stdout, NULL, _IONBF, 0);
111
setvbuf(stderr, NULL, _IONBF, 0);
113
/* Prepare Winsock */
114
err = WSAStartup(MAKEWORD(2, 2), &wsaData);
117
write_stderr("%s: WSAStartup failed: %d\n",
125
/* BeOS-specific actions on startup */
126
beos_startup(argc, argv);
130
* Not-quite-so-platform-specific startup environment checks. Still
131
* best to minimize these.
135
* Remember the physical location of the initially given argv[] array
136
* for possible use by ps display. On some platforms, the argv[]
137
* storage must be overwritten in order to set the process title for
138
* ps. In such cases save_ps_display_args makes and returns a new copy
139
* of the argv[] array.
141
* save_ps_display_args may also move the environment strings to make
142
* extra room. Therefore this should be done as early as possible
143
* during startup, to avoid entanglements with code that might save a
144
* getenv() result pointer.
146
argv = save_ps_display_args(argc, argv);
149
* Set up locale information from environment. Note that LC_CTYPE and
150
* LC_COLLATE will be overridden later from pg_control if we are in an
151
* already-initialized database. We set them here so that they will
152
* be available to fill pg_control during initdb. LC_MESSAGES will
153
* get set later during GUC option processing, but we set it here to
154
* allow startup error messages to be localized.
157
set_pglocale_pgservice(argv[0], "postgres");
162
* Windows uses codepages rather than the environment, so we work
163
* around that by querying the environment explicitly first for
164
* LC_COLLATE and LC_CTYPE. We have to do this because initdb passes
165
* those values in the environment. If there is nothing there we fall
166
* back on the codepage.
169
if ((env_locale = getenv("LC_COLLATE")) != NULL)
170
setlocale(LC_COLLATE, env_locale);
172
setlocale(LC_COLLATE, "");
174
if ((env_locale = getenv("LC_CTYPE")) != NULL)
175
setlocale(LC_CTYPE, env_locale);
177
setlocale(LC_CTYPE, "");
179
setlocale(LC_COLLATE, "");
180
setlocale(LC_CTYPE, "");
184
setlocale(LC_MESSAGES, "");
188
* We keep these set to "C" always, except transiently in pg_locale.c;
189
* see that file for explanations.
191
setlocale(LC_MONETARY, "C");
192
setlocale(LC_NUMERIC, "C");
193
setlocale(LC_TIME, "C");
196
* Skip permission checks if we're just trying to do --help or
197
* --version; otherwise root will get unhelpful failure messages from
201
&& (strcmp(argv[1], "--help") == 0 ||
202
strcmp(argv[1], "-?") == 0 ||
203
strcmp(argv[1], "--version") == 0 ||
204
strcmp(argv[1], "-V") == 0)))
210
* Make sure we are not running as root.
212
* BeOS currently runs everything as root :-(, so this check must be
213
* temporarily disabled there...
217
write_stderr("\"root\" execution of the PostgreSQL server is not permitted.\n"
218
"The server must be started under an unprivileged user ID to prevent\n"
219
"possible system security compromise. See the documentation for\n"
220
"more information on how to properly start the server.\n");
223
#endif /* !__BEOS__ */
226
* Also make sure that real and effective uids are the same.
227
* Executing Postgres as a setuid program from a root shell is a
228
* security hole, since on many platforms a nefarious subroutine
229
* could setuid back to root if real uid is root. (Since nobody
230
* actually uses Postgres as a setuid program, trying to actively
231
* fix this situation seems more trouble than it's worth; we'll
232
* just expend the effort to check for it.)
234
if (getuid() != geteuid())
236
write_stderr("%s: real and effective user IDs must match\n",
241
if (pgwin32_is_admin())
243
write_stderr("Execution of PostgreSQL by a user with administrative permissions is not\n"
245
"The server must be started under an unprivileged user ID to prevent\n"
246
"possible system security compromises. See the documentation for\n"
247
"more information on how to properly start the server.\n");
254
* Now dispatch to one of PostmasterMain, PostgresMain, GucInfoMain,
255
* SubPostmasterMain, or BootstrapMain depending on the program name
256
* (and possibly first argument) we were called with. The lack of
257
* consistency here is historical.
259
len = strlen(argv[0]);
261
if ((len >= 10 && strcmp(argv[0] + len - 10, "postmaster") == 0)
263
|| (len >= 14 && strcmp(argv[0] + len - 14, "postmaster.exe") == 0)
267
/* Called as "postmaster" */
268
exit(PostmasterMain(argc, argv));
272
* If the first argument begins with "-fork", then invoke
273
* SubPostmasterMain. This is used for forking postmaster child
274
* processes on systems where we can't simply fork.
277
if (argc > 1 && strncmp(argv[1], "-fork", 5) == 0)
278
exit(SubPostmasterMain(argc, argv));
283
* Start our win32 signal implementation
285
* SubPostmasterMain() will do this for itself, but the remaining
288
pgwin32_signal_initialize();
292
* If the first argument is "-boot", then invoke bootstrap mode. (This
293
* path is taken only for a standalone bootstrap process.)
295
if (argc > 1 && strcmp(argv[1], "-boot") == 0)
296
exit(BootstrapMain(argc, argv));
299
* If the first argument is "--describe-config", then invoke runtime
300
* configuration option display mode.
302
if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
306
* Otherwise we're a standalone backend. Invoke PostgresMain,
307
* specifying current userid as the "authenticated" Postgres user
311
pw = getpwuid(geteuid());
314
write_stderr("%s: invalid effective UID: %d\n",
315
argv[0], (int) geteuid());
318
/* Allocate new memory because later getpwuid() calls can overwrite it */
319
pw_name_persist = strdup(pw->pw_name);
322
long namesize = 256 /* UNLEN */ + 1;
324
pw_name_persist = malloc(namesize);
325
if (!GetUserName(pw_name_persist, &namesize))
327
write_stderr("%s: could not determine user name (GetUserName failed)\n",
334
exit(PostgresMain(argc, argv, pw_name_persist));