Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / src / bin / pg_ctl / pg_ctl.c
blobc9ca5edd846d4b2c5b232c89d370e2904e359b7b
1 /*-------------------------------------------------------------------------
3 * pg_ctl --- start/stops/restarts the PostgreSQL server
5 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
7 * $PostgreSQL$
9 *-------------------------------------------------------------------------
12 #ifdef WIN32
14 * Need this to get defines for restricted tokens and jobs. And it
15 * has to be set before any header from the Win32 API is loaded.
17 #define _WIN32_WINNT 0x0500
18 #endif
20 #include "postgres_fe.h"
21 #include "libpq-fe.h"
23 #include <locale.h>
24 #include <signal.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
29 #ifdef HAVE_SYS_RESOURCE_H
30 #include <sys/time.h>
31 #include <sys/resource.h>
32 #endif
34 #include "libpq/pqsignal.h"
35 #include "getopt_long.h"
36 #include "miscadmin.h"
38 #if defined(__CYGWIN__)
39 #include <sys/cygwin.h>
40 #include <windows.h>
41 /* Cygwin defines WIN32 in windows.h, but we don't want it. */
42 #undef WIN32
43 #endif
45 /* PID can be negative for standalone backend */
46 typedef long pgpid_t;
49 typedef enum
51 SMART_MODE,
52 FAST_MODE,
53 IMMEDIATE_MODE
54 } ShutdownMode;
57 typedef enum
59 NO_COMMAND = 0,
60 START_COMMAND,
61 STOP_COMMAND,
62 RESTART_COMMAND,
63 RELOAD_COMMAND,
64 STATUS_COMMAND,
65 KILL_COMMAND,
66 REGISTER_COMMAND,
67 UNREGISTER_COMMAND,
68 RUN_AS_SERVICE_COMMAND
69 } CtlCommand;
71 #define DEFAULT_WAIT 60
73 static bool do_wait = false;
74 static bool wait_set = false;
75 static int wait_seconds = DEFAULT_WAIT;
76 static bool silent_mode = false;
77 static ShutdownMode shutdown_mode = SMART_MODE;
78 static int sig = SIGTERM; /* default */
79 static CtlCommand ctl_command = NO_COMMAND;
80 static char *pg_data = NULL;
81 static char *pgdata_opt = NULL;
82 static char *post_opts = NULL;
83 static const char *progname;
84 static char *log_file = NULL;
85 static char *postgres_path = NULL;
86 static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
87 static char *register_username = NULL;
88 static char *register_password = NULL;
89 static char *argv0 = NULL;
90 static bool allow_core_files = false;
92 static void
93 write_stderr(const char *fmt,...)
94 /* This extension allows gcc to check the format string for consistency with
95 the supplied arguments. */
96 __attribute__((format(printf, 1, 2)));
97 static void *pg_malloc(size_t size);
98 static char *xstrdup(const char *s);
99 static void do_advice(void);
100 static void do_help(void);
101 static void set_mode(char *modeopt);
102 static void set_sig(char *signame);
103 static void do_start(void);
104 static void do_stop(void);
105 static void do_restart(void);
106 static void do_reload(void);
107 static void do_status(void);
108 static void do_kill(pgpid_t pid);
109 static void print_msg(const char *msg);
111 #if defined(WIN32) || defined(__CYGWIN__)
112 static bool pgwin32_IsInstalled(SC_HANDLE);
113 static char *pgwin32_CommandLine(bool);
114 static void pgwin32_doRegister(void);
115 static void pgwin32_doUnregister(void);
116 static void pgwin32_SetServiceStatus(DWORD);
117 static void WINAPI pgwin32_ServiceHandler(DWORD);
118 static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
119 static void pgwin32_doRunAsService(void);
120 static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service);
122 static SERVICE_STATUS status;
123 static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
124 static HANDLE shutdownHandles[2];
125 static pid_t postmasterPID = -1;
127 #define shutdownEvent shutdownHandles[0]
128 #define postmasterProcess shutdownHandles[1]
129 #endif
131 static pgpid_t get_pgpid(void);
132 static char **readfile(const char *path);
133 static int start_postmaster(void);
134 static void read_post_opts(void);
136 static bool test_postmaster_connection(bool);
137 static bool postmaster_is_alive(pid_t pid);
139 static char postopts_file[MAXPGPATH];
140 static char pid_file[MAXPGPATH];
141 static char conf_file[MAXPGPATH];
142 static char backup_file[MAXPGPATH];
144 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
145 static void unlimit_core_size(void);
146 #endif
149 #if defined(WIN32) || defined(__CYGWIN__)
150 static void
151 write_eventlog(int level, const char *line)
153 static HANDLE evtHandle = INVALID_HANDLE_VALUE;
155 if (evtHandle == INVALID_HANDLE_VALUE)
157 evtHandle = RegisterEventSource(NULL, "PostgreSQL");
158 if (evtHandle == NULL)
160 evtHandle = INVALID_HANDLE_VALUE;
161 return;
165 ReportEvent(evtHandle,
166 level,
168 0, /* All events are Id 0 */
169 NULL,
172 &line,
173 NULL);
175 #endif
178 * Write errors to stderr (or by equal means when stderr is
179 * not available).
181 static void
182 write_stderr(const char *fmt,...)
184 va_list ap;
186 va_start(ap, fmt);
187 #if !defined(WIN32) && !defined(__CYGWIN__)
188 /* On Unix, we just fprintf to stderr */
189 vfprintf(stderr, fmt, ap);
190 #else
193 * On Win32, we print to stderr if running on a console, or write to
194 * eventlog if running as a service
196 if (!isatty(fileno(stderr))) /* Running as a service */
198 char errbuf[2048]; /* Arbitrary size? */
200 vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
202 write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
204 else
205 /* Not running as service, write to stderr */
206 vfprintf(stderr, fmt, ap);
207 #endif
208 va_end(ap);
212 * routines to check memory allocations and fail noisily.
215 static void *
216 pg_malloc(size_t size)
218 void *result;
220 result = malloc(size);
221 if (!result)
223 write_stderr(_("%s: out of memory\n"), progname);
224 exit(1);
226 return result;
230 static char *
231 xstrdup(const char *s)
233 char *result;
235 result = strdup(s);
236 if (!result)
238 write_stderr(_("%s: out of memory\n"), progname);
239 exit(1);
241 return result;
245 * Given an already-localized string, print it to stdout unless the
246 * user has specified that no messages should be printed.
248 static void
249 print_msg(const char *msg)
251 if (!silent_mode)
253 fputs(msg, stdout);
254 fflush(stdout);
258 static pgpid_t
259 get_pgpid(void)
261 FILE *pidf;
262 long pid;
264 pidf = fopen(pid_file, "r");
265 if (pidf == NULL)
267 /* No pid file, not an error on startup */
268 if (errno == ENOENT)
269 return 0;
270 else
272 write_stderr(_("%s: could not open PID file \"%s\": %s\n"),
273 progname, pid_file, strerror(errno));
274 exit(1);
277 if (fscanf(pidf, "%ld", &pid) != 1)
279 write_stderr(_("%s: invalid data in PID file \"%s\"\n"),
280 progname, pid_file);
281 exit(1);
283 fclose(pidf);
284 return (pgpid_t) pid;
289 * get the lines from a text file - return NULL if file can't be opened
291 static char **
292 readfile(const char *path)
294 FILE *infile;
295 int maxlength = 0,
296 linelen = 0;
297 int nlines = 0;
298 char **result;
299 char *buffer;
300 int c;
302 if ((infile = fopen(path, "r")) == NULL)
303 return NULL;
305 /* pass over the file twice - the first time to size the result */
307 while ((c = fgetc(infile)) != EOF)
309 linelen++;
310 if (c == '\n')
312 nlines++;
313 if (linelen > maxlength)
314 maxlength = linelen;
315 linelen = 0;
319 /* handle last line without a terminating newline (yuck) */
320 if (linelen)
321 nlines++;
322 if (linelen > maxlength)
323 maxlength = linelen;
325 /* set up the result and the line buffer */
326 result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
327 buffer = (char *) pg_malloc(maxlength + 1);
329 /* now reprocess the file and store the lines */
330 rewind(infile);
331 nlines = 0;
332 while (fgets(buffer, maxlength + 1, infile) != NULL)
333 result[nlines++] = xstrdup(buffer);
335 fclose(infile);
336 free(buffer);
337 result[nlines] = NULL;
339 return result;
345 * start/test/stop routines
348 static int
349 start_postmaster(void)
351 char cmd[MAXPGPATH];
353 #ifndef WIN32
356 * Since there might be quotes to handle here, it is easier simply to pass
357 * everything to a shell to process them.
359 if (log_file != NULL)
360 snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1 &" SYSTEMQUOTE,
361 postgres_path, pgdata_opt, post_opts,
362 DEVNULL, log_file);
363 else
364 snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s < \"%s\" 2>&1 &" SYSTEMQUOTE,
365 postgres_path, pgdata_opt, post_opts, DEVNULL);
367 return system(cmd);
368 #else /* WIN32 */
371 * On win32 we don't use system(). So we don't need to use & (which would
372 * be START /B on win32). However, we still call the shell (CMD.EXE) with
373 * it to handle redirection etc.
375 PROCESS_INFORMATION pi;
377 if (log_file != NULL)
378 snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1" SYSTEMQUOTE,
379 postgres_path, pgdata_opt, post_opts, DEVNULL, log_file);
380 else
381 snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < \"%s\" 2>&1" SYSTEMQUOTE,
382 postgres_path, pgdata_opt, post_opts, DEVNULL);
384 if (!CreateRestrictedProcess(cmd, &pi, false))
385 return GetLastError();
386 CloseHandle(pi.hProcess);
387 CloseHandle(pi.hThread);
388 return 0;
389 #endif /* WIN32 */
395 * Find the pgport and try a connection
396 * Note that the checkpoint parameter enables a Windows service control
397 * manager checkpoint, it's got nothing to do with database checkpoints!!
399 static bool
400 test_postmaster_connection(bool do_checkpoint)
402 PGconn *conn;
403 bool success = false;
404 int i;
405 char portstr[32];
406 char *p;
407 char *q;
408 char connstr[128]; /* Should be way more than enough! */
410 *portstr = '\0';
413 * Look in post_opts for a -p switch.
415 * This parsing code is not amazingly bright; it could for instance get
416 * fooled if ' -p' occurs within a quoted argument value. Given that few
417 * people pass complicated settings in post_opts, it's probably good
418 * enough.
420 for (p = post_opts; *p;)
422 /* advance past whitespace */
423 while (isspace((unsigned char) *p))
424 p++;
426 if (strncmp(p, "-p", 2) == 0)
428 p += 2;
429 /* advance past any whitespace/quoting */
430 while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
431 p++;
432 /* find end of value (not including any ending quote!) */
433 q = p;
434 while (*q &&
435 !(isspace((unsigned char) *q) || *q == '\'' || *q == '"'))
436 q++;
437 /* and save the argument value */
438 strlcpy(portstr, p, Min((q - p) + 1, sizeof(portstr)));
439 /* keep looking, maybe there is another -p */
440 p = q;
442 /* Advance to next whitespace */
443 while (*p && !isspace((unsigned char) *p))
444 p++;
448 * Search config file for a 'port' option.
450 * This parsing code isn't amazingly bright either, but it should be okay
451 * for valid port settings.
453 if (!*portstr)
455 char **optlines;
457 optlines = readfile(conf_file);
458 if (optlines != NULL)
460 for (; *optlines != NULL; optlines++)
462 p = *optlines;
464 while (isspace((unsigned char) *p))
465 p++;
466 if (strncmp(p, "port", 4) != 0)
467 continue;
468 p += 4;
469 while (isspace((unsigned char) *p))
470 p++;
471 if (*p != '=')
472 continue;
473 p++;
474 /* advance past any whitespace/quoting */
475 while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
476 p++;
477 /* find end of value (not including any ending quote/comment!) */
478 q = p;
479 while (*q &&
480 !(isspace((unsigned char) *q) ||
481 *q == '\'' || *q == '"' || *q == '#'))
482 q++;
483 /* and save the argument value */
484 strlcpy(portstr, p, Min((q - p) + 1, sizeof(portstr)));
485 /* keep looking, maybe there is another */
490 /* Check environment */
491 if (!*portstr && getenv("PGPORT") != NULL)
492 strlcpy(portstr, getenv("PGPORT"), sizeof(portstr));
494 /* Else use compiled-in default */
495 if (!*portstr)
496 snprintf(portstr, sizeof(portstr), "%d", DEF_PGPORT);
499 * We need to set a connect timeout otherwise on Windows the SCM will
500 * probably timeout first
502 snprintf(connstr, sizeof(connstr),
503 "dbname=postgres port=%s connect_timeout=5", portstr);
505 for (i = 0; i < wait_seconds; i++)
507 if ((conn = PQconnectdb(connstr)) != NULL &&
508 (PQstatus(conn) == CONNECTION_OK ||
509 PQconnectionNeedsPassword(conn)))
511 PQfinish(conn);
512 success = true;
513 break;
515 else
517 PQfinish(conn);
519 #if defined(WIN32)
520 if (do_checkpoint)
523 * Increment the wait hint by 6 secs (connection timeout +
524 * sleep) We must do this to indicate to the SCM that our
525 * startup time is changing, otherwise it'll usually send a
526 * stop signal after 20 seconds, despite incrementing the
527 * checkpoint counter.
529 status.dwWaitHint += 6000;
530 status.dwCheckPoint++;
531 SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
534 else
535 #endif
536 print_msg(".");
538 pg_usleep(1000000); /* 1 sec */
542 return success;
546 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
547 static void
548 unlimit_core_size(void)
550 struct rlimit lim;
552 getrlimit(RLIMIT_CORE, &lim);
553 if (lim.rlim_max == 0)
555 write_stderr(_("%s: cannot set core file size limit; disallowed by hard limit\n"),
556 progname);
557 return;
559 else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
561 lim.rlim_cur = lim.rlim_max;
562 setrlimit(RLIMIT_CORE, &lim);
565 #endif
567 static void
568 read_post_opts(void)
570 if (post_opts == NULL)
572 post_opts = ""; /* default */
573 if (ctl_command == RESTART_COMMAND)
575 char **optlines;
577 optlines = readfile(postopts_file);
578 if (optlines == NULL)
580 write_stderr(_("%s: could not read file \"%s\"\n"), progname, postopts_file);
581 exit(1);
583 else if (optlines[0] == NULL || optlines[1] != NULL)
585 write_stderr(_("%s: option file \"%s\" must have exactly one line\n"),
586 progname, postopts_file);
587 exit(1);
589 else
591 int len;
592 char *optline;
593 char *arg1;
595 optline = optlines[0];
596 /* trim off line endings */
597 len = strcspn(optline, "\r\n");
598 optline[len] = '\0';
601 * Are we at the first option, as defined by space and
602 * double-quote?
604 if ((arg1 = strstr(optline, " \"")) != NULL)
606 *arg1 = '\0'; /* terminate so we get only program
607 * name */
608 post_opts = arg1 + 1; /* point past whitespace */
610 if (postgres_path == NULL)
611 postgres_path = optline;
617 static void
618 do_start(void)
620 pgpid_t pid;
621 pgpid_t old_pid = 0;
622 int exitcode;
624 if (ctl_command != RESTART_COMMAND)
626 old_pid = get_pgpid();
627 if (old_pid != 0)
628 write_stderr(_("%s: another server might be running; "
629 "trying to start server anyway\n"),
630 progname);
633 read_post_opts();
635 /* No -D or -D already added during server start */
636 if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
637 pgdata_opt = "";
639 if (postgres_path == NULL)
641 char *postmaster_path;
642 int ret;
644 postmaster_path = pg_malloc(MAXPGPATH);
646 if ((ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
647 postmaster_path)) < 0)
649 char full_path[MAXPGPATH];
651 if (find_my_exec(argv0, full_path) < 0)
652 strlcpy(full_path, progname, sizeof(full_path));
654 if (ret == -1)
655 write_stderr(_("The program \"postgres\" is needed by %s "
656 "but was not found in the\n"
657 "same directory as \"%s\".\n"
658 "Check your installation.\n"),
659 progname, full_path);
660 else
661 write_stderr(_("The program \"postgres\" was found by \"%s\"\n"
662 "but was not the same version as %s.\n"
663 "Check your installation.\n"),
664 full_path, progname);
665 exit(1);
667 postgres_path = postmaster_path;
670 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
671 if (allow_core_files)
672 unlimit_core_size();
673 #endif
675 exitcode = start_postmaster();
676 if (exitcode != 0)
678 write_stderr(_("%s: could not start server: exit code was %d\n"),
679 progname, exitcode);
680 exit(1);
683 if (old_pid != 0)
685 pg_usleep(1000000);
686 pid = get_pgpid();
687 if (pid == old_pid)
689 write_stderr(_("%s: could not start server\n"
690 "Examine the log output.\n"),
691 progname);
692 exit(1);
696 if (do_wait)
698 print_msg(_("waiting for server to start..."));
700 if (test_postmaster_connection(false) == false)
702 printf(_("could not start server\n"));
703 exit(1);
705 else
707 print_msg(_(" done\n"));
708 print_msg(_("server started\n"));
711 else
712 print_msg(_("server starting\n"));
716 static void
717 do_stop(void)
719 int cnt;
720 pgpid_t pid;
721 struct stat statbuf;
723 pid = get_pgpid();
725 if (pid == 0) /* no pid file */
727 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
728 write_stderr(_("Is server running?\n"));
729 exit(1);
731 else if (pid < 0) /* standalone backend, not postmaster */
733 pid = -pid;
734 write_stderr(_("%s: cannot stop server; "
735 "single-user server is running (PID: %ld)\n"),
736 progname, pid);
737 exit(1);
740 if (kill((pid_t) pid, sig) != 0)
742 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
743 strerror(errno));
744 exit(1);
747 if (!do_wait)
749 print_msg(_("server shutting down\n"));
750 return;
752 else
754 if ((shutdown_mode == SMART_MODE) && (stat(backup_file, &statbuf) == 0))
756 print_msg(_("WARNING: online backup mode is active\n"
757 "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
760 print_msg(_("waiting for server to shut down..."));
762 for (cnt = 0; cnt < wait_seconds; cnt++)
764 if ((pid = get_pgpid()) != 0)
766 print_msg(".");
767 pg_usleep(1000000); /* 1 sec */
769 else
770 break;
773 if (pid != 0) /* pid file still exists */
775 print_msg(_(" failed\n"));
777 write_stderr(_("%s: server does not shut down\n"), progname);
778 exit(1);
780 print_msg(_(" done\n"));
782 printf(_("server stopped\n"));
788 * restart/reload routines
791 static void
792 do_restart(void)
794 int cnt;
795 pgpid_t pid;
796 struct stat statbuf;
798 pid = get_pgpid();
800 if (pid == 0) /* no pid file */
802 write_stderr(_("%s: PID file \"%s\" does not exist\n"),
803 progname, pid_file);
804 write_stderr(_("Is server running?\n"));
805 write_stderr(_("starting server anyway\n"));
806 do_start();
807 return;
809 else if (pid < 0) /* standalone backend, not postmaster */
811 pid = -pid;
812 if (postmaster_is_alive((pid_t) pid))
814 write_stderr(_("%s: cannot restart server; "
815 "single-user server is running (PID: %ld)\n"),
816 progname, pid);
817 write_stderr(_("Please terminate the single-user server and try again.\n"));
818 exit(1);
822 if (postmaster_is_alive((pid_t) pid))
824 if (kill((pid_t) pid, sig) != 0)
826 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
827 strerror(errno));
828 exit(1);
831 if ((shutdown_mode == SMART_MODE) && (stat(backup_file, &statbuf) == 0))
833 print_msg(_("WARNING: online backup mode is active\n"
834 "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
837 print_msg(_("waiting for server to shut down..."));
839 /* always wait for restart */
841 for (cnt = 0; cnt < wait_seconds; cnt++)
843 if ((pid = get_pgpid()) != 0)
845 print_msg(".");
846 pg_usleep(1000000); /* 1 sec */
848 else
849 break;
852 if (pid != 0) /* pid file still exists */
854 print_msg(_(" failed\n"));
856 write_stderr(_("%s: server does not shut down\n"), progname);
857 exit(1);
860 print_msg(_(" done\n"));
861 printf(_("server stopped\n"));
863 else
865 write_stderr(_("%s: old server process (PID: %ld) seems to be gone\n"),
866 progname, pid);
867 write_stderr(_("starting server anyway\n"));
870 do_start();
874 static void
875 do_reload(void)
877 pgpid_t pid;
879 pid = get_pgpid();
880 if (pid == 0) /* no pid file */
882 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
883 write_stderr(_("Is server running?\n"));
884 exit(1);
886 else if (pid < 0) /* standalone backend, not postmaster */
888 pid = -pid;
889 write_stderr(_("%s: cannot reload server; "
890 "single-user server is running (PID: %ld)\n"),
891 progname, pid);
892 write_stderr(_("Please terminate the single-user server and try again.\n"));
893 exit(1);
896 if (kill((pid_t) pid, sig) != 0)
898 write_stderr(_("%s: could not send reload signal (PID: %ld): %s\n"),
899 progname, pid, strerror(errno));
900 exit(1);
903 print_msg(_("server signaled\n"));
907 * utility routines
910 static bool
911 postmaster_is_alive(pid_t pid)
914 * Test to see if the process is still there. Note that we do not
915 * consider an EPERM failure to mean that the process is still there;
916 * EPERM must mean that the given PID belongs to some other userid, and
917 * considering the permissions on $PGDATA, that means it's not the
918 * postmaster we are after.
920 * Don't believe that our own PID or parent shell's PID is the postmaster,
921 * either. (Windows hasn't got getppid(), though.)
923 if (pid == getpid())
924 return false;
925 #ifndef WIN32
926 if (pid == getppid())
927 return false;
928 #endif
929 if (kill(pid, 0) == 0)
930 return true;
931 return false;
934 static void
935 do_status(void)
937 pgpid_t pid;
939 pid = get_pgpid();
940 if (pid != 0) /* 0 means no pid file */
942 if (pid < 0) /* standalone backend */
944 pid = -pid;
945 if (postmaster_is_alive((pid_t) pid))
947 printf(_("%s: single-user server is running (PID: %ld)\n"),
948 progname, pid);
949 return;
952 else
953 /* postmaster */
955 if (postmaster_is_alive((pid_t) pid))
957 char **optlines;
959 printf(_("%s: server is running (PID: %ld)\n"),
960 progname, pid);
962 optlines = readfile(postopts_file);
963 if (optlines != NULL)
964 for (; *optlines != NULL; optlines++)
965 fputs(*optlines, stdout);
966 return;
970 printf(_("%s: no server running\n"), progname);
971 exit(1);
976 static void
977 do_kill(pgpid_t pid)
979 if (kill((pid_t) pid, sig) != 0)
981 write_stderr(_("%s: could not send signal %d (PID: %ld): %s\n"),
982 progname, sig, pid, strerror(errno));
983 exit(1);
987 #if defined(WIN32) || defined(__CYGWIN__)
989 static bool
990 pgwin32_IsInstalled(SC_HANDLE hSCM)
992 SC_HANDLE hService = OpenService(hSCM, register_servicename, SERVICE_QUERY_CONFIG);
993 bool bResult = (hService != NULL);
995 if (bResult)
996 CloseServiceHandle(hService);
997 return bResult;
1000 static char *
1001 pgwin32_CommandLine(bool registration)
1003 static char cmdLine[MAXPGPATH];
1004 int ret;
1006 #ifdef __CYGWIN__
1007 char buf[MAXPGPATH];
1008 #endif
1010 if (registration)
1012 ret = find_my_exec(argv0, cmdLine);
1013 if (ret != 0)
1015 write_stderr(_("%s: could not find own program executable\n"), progname);
1016 exit(1);
1019 else
1021 ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
1022 cmdLine);
1023 if (ret != 0)
1025 write_stderr(_("%s: could not find postgres program executable\n"), progname);
1026 exit(1);
1030 #ifdef __CYGWIN__
1031 /* need to convert to windows path */
1032 cygwin_conv_to_full_win32_path(cmdLine, buf);
1033 strcpy(cmdLine, buf);
1034 #endif
1036 if (registration)
1038 if (pg_strcasecmp(cmdLine + strlen(cmdLine) - 4, ".exe"))
1040 /* If commandline does not end in .exe, append it */
1041 strcat(cmdLine, ".exe");
1043 strcat(cmdLine, " runservice -N \"");
1044 strcat(cmdLine, register_servicename);
1045 strcat(cmdLine, "\"");
1048 if (pg_data)
1050 strcat(cmdLine, " -D \"");
1051 strcat(cmdLine, pg_data);
1052 strcat(cmdLine, "\"");
1055 if (registration && do_wait)
1056 strcat(cmdLine, " -w");
1058 if (registration && wait_seconds != DEFAULT_WAIT)
1059 /* concatenate */
1060 sprintf(cmdLine + strlen(cmdLine), " -t %d", wait_seconds);
1062 if (post_opts)
1064 strcat(cmdLine, " ");
1065 if (registration)
1066 strcat(cmdLine, " -o \"");
1067 strcat(cmdLine, post_opts);
1068 if (registration)
1069 strcat(cmdLine, "\"");
1072 return cmdLine;
1075 static void
1076 pgwin32_doRegister(void)
1078 SC_HANDLE hService;
1079 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1081 if (hSCM == NULL)
1083 write_stderr(_("%s: could not open service manager\n"), progname);
1084 exit(1);
1086 if (pgwin32_IsInstalled(hSCM))
1088 CloseServiceHandle(hSCM);
1089 write_stderr(_("%s: service \"%s\" already registered\n"), progname, register_servicename);
1090 exit(1);
1093 if ((hService = CreateService(hSCM, register_servicename, register_servicename,
1094 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
1095 SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
1096 pgwin32_CommandLine(true),
1097 NULL, NULL, "RPCSS\0", register_username, register_password)) == NULL)
1099 CloseServiceHandle(hSCM);
1100 write_stderr(_("%s: could not register service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1101 exit(1);
1103 CloseServiceHandle(hService);
1104 CloseServiceHandle(hSCM);
1107 static void
1108 pgwin32_doUnregister(void)
1110 SC_HANDLE hService;
1111 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1113 if (hSCM == NULL)
1115 write_stderr(_("%s: could not open service manager\n"), progname);
1116 exit(1);
1118 if (!pgwin32_IsInstalled(hSCM))
1120 CloseServiceHandle(hSCM);
1121 write_stderr(_("%s: service \"%s\" not registered\n"), progname, register_servicename);
1122 exit(1);
1125 if ((hService = OpenService(hSCM, register_servicename, DELETE)) == NULL)
1127 CloseServiceHandle(hSCM);
1128 write_stderr(_("%s: could not open service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1129 exit(1);
1131 if (!DeleteService(hService))
1133 CloseServiceHandle(hService);
1134 CloseServiceHandle(hSCM);
1135 write_stderr(_("%s: could not unregister service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1136 exit(1);
1138 CloseServiceHandle(hService);
1139 CloseServiceHandle(hSCM);
1142 static void
1143 pgwin32_SetServiceStatus(DWORD currentState)
1145 status.dwCurrentState = currentState;
1146 SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
1149 static void WINAPI
1150 pgwin32_ServiceHandler(DWORD request)
1152 switch (request)
1154 case SERVICE_CONTROL_STOP:
1155 case SERVICE_CONTROL_SHUTDOWN:
1158 * We only need a short wait hint here as it just needs to wait
1159 * for the next checkpoint. They occur every 5 seconds during
1160 * shutdown
1162 status.dwWaitHint = 10000;
1163 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1164 SetEvent(shutdownEvent);
1165 return;
1167 case SERVICE_CONTROL_PAUSE:
1168 /* Win32 config reloading */
1169 status.dwWaitHint = 5000;
1170 kill(postmasterPID, SIGHUP);
1171 return;
1173 /* FIXME: These could be used to replace other signals etc */
1174 case SERVICE_CONTROL_CONTINUE:
1175 case SERVICE_CONTROL_INTERROGATE:
1176 default:
1177 break;
1181 static void WINAPI
1182 pgwin32_ServiceMain(DWORD argc, LPTSTR *argv)
1184 PROCESS_INFORMATION pi;
1185 DWORD ret;
1186 DWORD check_point_start;
1188 /* Initialize variables */
1189 status.dwWin32ExitCode = S_OK;
1190 status.dwCheckPoint = 0;
1191 status.dwWaitHint = 60000;
1192 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
1193 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
1194 status.dwServiceSpecificExitCode = 0;
1195 status.dwCurrentState = SERVICE_START_PENDING;
1197 memset(&pi, 0, sizeof(pi));
1199 read_post_opts();
1201 /* Register the control request handler */
1202 if ((hStatus = RegisterServiceCtrlHandler(register_servicename, pgwin32_ServiceHandler)) == (SERVICE_STATUS_HANDLE) 0)
1203 return;
1205 if ((shutdownEvent = CreateEvent(NULL, true, false, NULL)) == NULL)
1206 return;
1208 /* Start the postmaster */
1209 pgwin32_SetServiceStatus(SERVICE_START_PENDING);
1210 if (!CreateRestrictedProcess(pgwin32_CommandLine(false), &pi, true))
1212 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1213 return;
1215 postmasterPID = pi.dwProcessId;
1216 postmasterProcess = pi.hProcess;
1217 CloseHandle(pi.hThread);
1219 if (do_wait)
1221 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Waiting for server startup...\n"));
1222 if (test_postmaster_connection(true) == false)
1224 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Timed out waiting for server startup\n"));
1225 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1226 return;
1228 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Server started and accepting connections\n"));
1232 * Save the checkpoint value as it might have been incremented in
1233 * test_postmaster_connection
1235 check_point_start = status.dwCheckPoint;
1237 pgwin32_SetServiceStatus(SERVICE_RUNNING);
1239 /* Wait for quit... */
1240 ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);
1242 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1243 switch (ret)
1245 case WAIT_OBJECT_0: /* shutdown event */
1246 kill(postmasterPID, SIGINT);
1249 * Increment the checkpoint and try again Abort after 12
1250 * checkpoints as the postmaster has probably hung
1252 while (WaitForSingleObject(postmasterProcess, 5000) == WAIT_TIMEOUT && status.dwCheckPoint < 12)
1253 status.dwCheckPoint++;
1254 break;
1256 case (WAIT_OBJECT_0 + 1): /* postmaster went down */
1257 break;
1259 default:
1260 /* shouldn't get here? */
1261 break;
1264 CloseHandle(shutdownEvent);
1265 CloseHandle(postmasterProcess);
1267 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1270 static void
1271 pgwin32_doRunAsService(void)
1273 SERVICE_TABLE_ENTRY st[] = {{register_servicename, pgwin32_ServiceMain},
1274 {NULL, NULL}};
1276 if (StartServiceCtrlDispatcher(st) == 0)
1278 write_stderr(_("%s: could not start service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1279 exit(1);
1285 * Mingw headers are incomplete, and so are the libraries. So we have to load
1286 * a whole lot of API functions dynamically. Since we have to do this anyway,
1287 * also load the couple of functions that *do* exist in minwg headers but not
1288 * on NT4. That way, we don't break on NT4.
1290 typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
1291 typedef BOOL (WINAPI * __IsProcessInJob) (HANDLE, HANDLE, PBOOL);
1292 typedef HANDLE (WINAPI * __CreateJobObject) (LPSECURITY_ATTRIBUTES, LPCTSTR);
1293 typedef BOOL (WINAPI * __SetInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD);
1294 typedef BOOL (WINAPI * __AssignProcessToJobObject) (HANDLE, HANDLE);
1295 typedef BOOL (WINAPI * __QueryInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD);
1297 /* Windows API define missing from MingW headers */
1298 #define DISABLE_MAX_PRIVILEGE 0x1
1301 * Create a restricted token, a job object sandbox, and execute the specified
1302 * process with it.
1304 * Returns 0 on success, non-zero on failure, same as CreateProcess().
1306 * On NT4, or any other system not containing the required functions, will
1307 * launch the process under the current token without doing any modifications.
1309 * NOTE! Job object will only work when running as a service, because it's
1310 * automatically destroyed when pg_ctl exits.
1312 static int
1313 CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service)
1315 int r;
1316 BOOL b;
1317 STARTUPINFO si;
1318 HANDLE origToken;
1319 HANDLE restrictedToken;
1320 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
1321 SID_AND_ATTRIBUTES dropSids[2];
1323 /* Functions loaded dynamically */
1324 __CreateRestrictedToken _CreateRestrictedToken = NULL;
1325 __IsProcessInJob _IsProcessInJob = NULL;
1326 __CreateJobObject _CreateJobObject = NULL;
1327 __SetInformationJobObject _SetInformationJobObject = NULL;
1328 __AssignProcessToJobObject _AssignProcessToJobObject = NULL;
1329 __QueryInformationJobObject _QueryInformationJobObject = NULL;
1330 HANDLE Kernel32Handle;
1331 HANDLE Advapi32Handle;
1333 ZeroMemory(&si, sizeof(si));
1334 si.cb = sizeof(si);
1336 Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
1337 if (Advapi32Handle != NULL)
1339 _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
1342 if (_CreateRestrictedToken == NULL)
1345 * NT4 doesn't have CreateRestrictedToken, so just call ordinary
1346 * CreateProcess
1348 write_stderr("WARNING: cannot create restricted tokens on this platform\n");
1349 if (Advapi32Handle != NULL)
1350 FreeLibrary(Advapi32Handle);
1351 return CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, processInfo);
1354 /* Open the current token to use as a base for the restricted one */
1355 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
1357 write_stderr("Failed to open process token: %lu\n", GetLastError());
1358 return 0;
1361 /* Allocate list of SIDs to remove */
1362 ZeroMemory(&dropSids, sizeof(dropSids));
1363 if (!AllocateAndInitializeSid(&NtAuthority, 2,
1364 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
1365 0, &dropSids[0].Sid) ||
1366 !AllocateAndInitializeSid(&NtAuthority, 2,
1367 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
1368 0, &dropSids[1].Sid))
1370 write_stderr("Failed to allocate SIDs: %lu\n", GetLastError());
1371 return 0;
1374 b = _CreateRestrictedToken(origToken,
1375 DISABLE_MAX_PRIVILEGE,
1376 sizeof(dropSids) / sizeof(dropSids[0]),
1377 dropSids,
1378 0, NULL,
1379 0, NULL,
1380 &restrictedToken);
1382 FreeSid(dropSids[1].Sid);
1383 FreeSid(dropSids[0].Sid);
1384 CloseHandle(origToken);
1385 FreeLibrary(Advapi32Handle);
1387 if (!b)
1389 write_stderr("Failed to create restricted token: %lu\n", GetLastError());
1390 return 0;
1393 r = CreateProcessAsUser(restrictedToken, NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, processInfo);
1395 Kernel32Handle = LoadLibrary("KERNEL32.DLL");
1396 if (Kernel32Handle != NULL)
1398 _IsProcessInJob = (__IsProcessInJob) GetProcAddress(Kernel32Handle, "IsProcessInJob");
1399 _CreateJobObject = (__CreateJobObject) GetProcAddress(Kernel32Handle, "CreateJobObjectA");
1400 _SetInformationJobObject = (__SetInformationJobObject) GetProcAddress(Kernel32Handle, "SetInformationJobObject");
1401 _AssignProcessToJobObject = (__AssignProcessToJobObject) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject");
1402 _QueryInformationJobObject = (__QueryInformationJobObject) GetProcAddress(Kernel32Handle, "QueryInformationJobObject");
1405 /* Verify that we found all functions */
1406 if (_IsProcessInJob == NULL || _CreateJobObject == NULL || _SetInformationJobObject == NULL || _AssignProcessToJobObject == NULL || _QueryInformationJobObject == NULL)
1409 * IsProcessInJob() is not available on < WinXP, so there is no need
1410 * to log the error every time in that case
1412 OSVERSIONINFO osv;
1414 osv.dwOSVersionInfoSize = sizeof(osv);
1415 if (!GetVersionEx(&osv) || /* could not get version */
1416 (osv.dwMajorVersion == 5 && osv.dwMinorVersion > 0) || /* 5.1=xp, 5.2=2003, etc */
1417 osv.dwMajorVersion > 5) /* anything newer should have the API */
1420 * Log error if we can't get version, or if we're on WinXP/2003 or
1421 * newer
1423 write_stderr("WARNING: could not locate all job object functions in system API\n");
1425 else
1427 BOOL inJob;
1429 if (_IsProcessInJob(processInfo->hProcess, NULL, &inJob))
1431 if (!inJob)
1434 * Job objects are working, and the new process isn't in one,
1435 * so we can create one safely. If any problems show up when
1436 * setting it, we're going to ignore them.
1438 HANDLE job;
1439 char jobname[128];
1441 sprintf(jobname, "PostgreSQL_%lu", processInfo->dwProcessId);
1443 job = _CreateJobObject(NULL, jobname);
1444 if (job)
1446 JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
1447 JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
1448 JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
1449 OSVERSIONINFO osv;
1451 ZeroMemory(&basicLimit, sizeof(basicLimit));
1452 ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
1453 ZeroMemory(&securityLimit, sizeof(securityLimit));
1455 basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
1456 basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
1457 _SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));
1459 uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
1460 JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
1461 JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
1463 if (as_service)
1465 osv.dwOSVersionInfoSize = sizeof(osv);
1466 if (!GetVersionEx(&osv) ||
1467 osv.dwMajorVersion < 6 ||
1468 (osv.dwMajorVersion == 6 && osv.dwMinorVersion == 0))
1471 * On Windows 7 (and presumably later),
1472 * JOB_OBJECT_UILIMIT_HANDLES prevents us from
1473 * starting as a service. So we only enable it on
1474 * Vista and earlier (version <= 6.0)
1476 uiRestrictions.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
1479 _SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));
1481 securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
1482 securityLimit.JobToken = restrictedToken;
1483 _SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));
1485 _AssignProcessToJobObject(job, processInfo->hProcess);
1491 #ifndef __CYGWIN__
1492 AddUserToDacl(processInfo->hProcess);
1493 #endif
1495 CloseHandle(restrictedToken);
1497 ResumeThread(processInfo->hThread);
1499 FreeLibrary(Kernel32Handle);
1502 * We intentionally don't close the job object handle, because we want the
1503 * object to live on until pg_ctl shuts down.
1505 return r;
1507 #endif
1509 static void
1510 do_advice(void)
1512 write_stderr(_("Try \"%s --help\" for more information.\n"), progname);
1517 static void
1518 do_help(void)
1520 printf(_("%s is a utility to start, stop, restart, reload configuration files,\n"
1521 "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n\n"), progname);
1522 printf(_("Usage:\n"));
1523 printf(_(" %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n"), progname);
1524 printf(_(" %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"), progname);
1525 printf(_(" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"
1526 " [-o \"OPTIONS\"]\n"), progname);
1527 printf(_(" %s reload [-D DATADIR] [-s]\n"), progname);
1528 printf(_(" %s status [-D DATADIR]\n"), progname);
1529 printf(_(" %s kill SIGNALNAME PID\n"), progname);
1530 #if defined(WIN32) || defined(__CYGWIN__)
1531 printf(_(" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n"
1532 " [-w] [-t SECS] [-o \"OPTIONS\"]\n"), progname);
1533 printf(_(" %s unregister [-N SERVICENAME]\n"), progname);
1534 #endif
1536 printf(_("\nCommon options:\n"));
1537 printf(_(" -D, --pgdata DATADIR location of the database storage area\n"));
1538 printf(_(" -s, --silent only print errors, no informational messages\n"));
1539 printf(_(" -t SECS seconds to wait when using -w option\n"));
1540 printf(_(" -w wait until operation completes\n"));
1541 printf(_(" -W do not wait until operation completes\n"));
1542 printf(_(" --help show this help, then exit\n"));
1543 printf(_(" --version output version information, then exit\n"));
1544 printf(_("(The default is to wait for shutdown, but not for start or restart.)\n\n"));
1545 printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
1547 printf(_("\nOptions for start or restart:\n"));
1548 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
1549 printf(_(" -c, --core-files allow postgres to produce core files\n"));
1550 #else
1551 printf(_(" -c, --core-files not applicable on this platform\n"));
1552 #endif
1553 printf(_(" -l, --log FILENAME write (or append) server log to FILENAME\n"));
1554 printf(_(" -o OPTIONS command line options to pass to postgres\n"
1555 " (PostgreSQL server executable)\n"));
1556 printf(_(" -p PATH-TO-POSTGRES normally not necessary\n"));
1557 printf(_("\nOptions for stop or restart:\n"));
1558 printf(_(" -m SHUTDOWN-MODE can be \"smart\", \"fast\", or \"immediate\"\n"));
1560 printf(_("\nShutdown modes are:\n"));
1561 printf(_(" smart quit after all clients have disconnected\n"));
1562 printf(_(" fast quit directly, with proper shutdown\n"));
1563 printf(_(" immediate quit without complete shutdown; will lead to recovery on restart\n"));
1565 printf(_("\nAllowed signal names for kill:\n"));
1566 printf(" HUP INT QUIT ABRT TERM USR1 USR2\n");
1568 #if defined(WIN32) || defined(__CYGWIN__)
1569 printf(_("\nOptions for register and unregister:\n"));
1570 printf(_(" -N SERVICENAME service name with which to register PostgreSQL server\n"));
1571 printf(_(" -P PASSWORD password of account to register PostgreSQL server\n"));
1572 printf(_(" -U USERNAME user name of account to register PostgreSQL server\n"));
1573 #endif
1575 printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
1580 static void
1581 set_mode(char *modeopt)
1583 if (strcmp(modeopt, "s") == 0 || strcmp(modeopt, "smart") == 0)
1585 shutdown_mode = SMART_MODE;
1586 sig = SIGTERM;
1588 else if (strcmp(modeopt, "f") == 0 || strcmp(modeopt, "fast") == 0)
1590 shutdown_mode = FAST_MODE;
1591 sig = SIGINT;
1593 else if (strcmp(modeopt, "i") == 0 || strcmp(modeopt, "immediate") == 0)
1595 shutdown_mode = IMMEDIATE_MODE;
1596 sig = SIGQUIT;
1598 else
1600 write_stderr(_("%s: unrecognized shutdown mode \"%s\"\n"), progname, modeopt);
1601 do_advice();
1602 exit(1);
1608 static void
1609 set_sig(char *signame)
1611 if (!strcmp(signame, "HUP"))
1612 sig = SIGHUP;
1613 else if (!strcmp(signame, "INT"))
1614 sig = SIGINT;
1615 else if (!strcmp(signame, "QUIT"))
1616 sig = SIGQUIT;
1617 else if (!strcmp(signame, "ABRT"))
1618 sig = SIGABRT;
1621 * probably should NOT provide SIGKILL
1623 * else if (!strcmp(signame,"KILL")) sig = SIGKILL;
1625 else if (!strcmp(signame, "TERM"))
1626 sig = SIGTERM;
1627 else if (!strcmp(signame, "USR1"))
1628 sig = SIGUSR1;
1629 else if (!strcmp(signame, "USR2"))
1630 sig = SIGUSR2;
1631 else
1633 write_stderr(_("%s: unrecognized signal name \"%s\"\n"), progname, signame);
1634 do_advice();
1635 exit(1);
1643 main(int argc, char **argv)
1645 static struct option long_options[] = {
1646 {"help", no_argument, NULL, '?'},
1647 {"version", no_argument, NULL, 'V'},
1648 {"log", required_argument, NULL, 'l'},
1649 {"mode", required_argument, NULL, 'm'},
1650 {"pgdata", required_argument, NULL, 'D'},
1651 {"silent", no_argument, NULL, 's'},
1652 {"timeout", required_argument, NULL, 't'},
1653 {"core-files", no_argument, NULL, 'c'},
1654 {NULL, 0, NULL, 0}
1657 int option_index;
1658 int c;
1659 pgpid_t killproc = 0;
1661 #if defined(WIN32) || defined(__CYGWIN__)
1662 setvbuf(stderr, NULL, _IONBF, 0);
1663 #endif
1665 progname = get_progname(argv[0]);
1666 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_ctl"));
1669 * save argv[0] so do_start() can look for the postmaster if necessary. we
1670 * don't look for postmaster here because in many cases we won't need it.
1672 argv0 = argv[0];
1674 umask(077);
1676 /* support --help and --version even if invoked as root */
1677 if (argc > 1)
1679 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 ||
1680 strcmp(argv[1], "-?") == 0)
1682 do_help();
1683 exit(0);
1685 else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0)
1687 puts("pg_ctl (PostgreSQL) " PG_VERSION);
1688 exit(0);
1693 * Disallow running as root, to forestall any possible security holes.
1695 #ifndef WIN32
1696 if (geteuid() == 0)
1698 write_stderr(_("%s: cannot be run as root\n"
1699 "Please log in (using, e.g., \"su\") as the "
1700 "(unprivileged) user that will\n"
1701 "own the server process.\n"),
1702 progname);
1703 exit(1);
1705 #endif
1708 * 'Action' can be before or after args so loop over both. Some
1709 * getopt_long() implementations will reorder argv[] to place all flags
1710 * first (GNU?), but we don't rely on it. Our /port version doesn't do
1711 * that.
1713 optind = 1;
1715 /* process command-line options */
1716 while (optind < argc)
1718 while ((c = getopt_long(argc, argv, "cD:l:m:N:o:p:P:st:U:wW", long_options, &option_index)) != -1)
1720 switch (c)
1722 case 'D':
1724 char *pgdata_D;
1725 char *env_var = pg_malloc(strlen(optarg) + 8);
1727 pgdata_D = xstrdup(optarg);
1728 canonicalize_path(pgdata_D);
1729 snprintf(env_var, strlen(optarg) + 8, "PGDATA=%s",
1730 pgdata_D);
1731 putenv(env_var);
1734 * We could pass PGDATA just in an environment
1735 * variable but we do -D too for clearer postmaster
1736 * 'ps' display
1738 pgdata_opt = pg_malloc(strlen(pgdata_D) + 7);
1739 snprintf(pgdata_opt, strlen(pgdata_D) + 7,
1740 "-D \"%s\" ",
1741 pgdata_D);
1742 break;
1744 case 'l':
1745 log_file = xstrdup(optarg);
1746 break;
1747 case 'm':
1748 set_mode(optarg);
1749 break;
1750 case 'N':
1751 register_servicename = xstrdup(optarg);
1752 break;
1753 case 'o':
1754 post_opts = xstrdup(optarg);
1755 break;
1756 case 'p':
1757 postgres_path = xstrdup(optarg);
1758 break;
1759 case 'P':
1760 register_password = xstrdup(optarg);
1761 break;
1762 case 's':
1763 silent_mode = true;
1764 break;
1765 case 't':
1766 wait_seconds = atoi(optarg);
1767 break;
1768 case 'U':
1769 if (strchr(optarg, '\\'))
1770 register_username = xstrdup(optarg);
1771 else
1772 /* Prepend .\ for local accounts */
1774 register_username = malloc(strlen(optarg) + 3);
1775 if (!register_username)
1777 write_stderr(_("%s: out of memory\n"), progname);
1778 exit(1);
1780 strcpy(register_username, ".\\");
1781 strcat(register_username, optarg);
1783 break;
1784 case 'w':
1785 do_wait = true;
1786 wait_set = true;
1787 break;
1788 case 'W':
1789 do_wait = false;
1790 wait_set = true;
1791 break;
1792 case 'c':
1793 allow_core_files = true;
1794 break;
1795 default:
1796 /* getopt_long already issued a suitable error message */
1797 do_advice();
1798 exit(1);
1802 /* Process an action */
1803 if (optind < argc)
1805 if (ctl_command != NO_COMMAND)
1807 write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]);
1808 do_advice();
1809 exit(1);
1812 if (strcmp(argv[optind], "start") == 0)
1813 ctl_command = START_COMMAND;
1814 else if (strcmp(argv[optind], "stop") == 0)
1815 ctl_command = STOP_COMMAND;
1816 else if (strcmp(argv[optind], "restart") == 0)
1817 ctl_command = RESTART_COMMAND;
1818 else if (strcmp(argv[optind], "reload") == 0)
1819 ctl_command = RELOAD_COMMAND;
1820 else if (strcmp(argv[optind], "status") == 0)
1821 ctl_command = STATUS_COMMAND;
1822 else if (strcmp(argv[optind], "kill") == 0)
1824 if (argc - optind < 3)
1826 write_stderr(_("%s: missing arguments for kill mode\n"), progname);
1827 do_advice();
1828 exit(1);
1830 ctl_command = KILL_COMMAND;
1831 set_sig(argv[++optind]);
1832 killproc = atol(argv[++optind]);
1834 #if defined(WIN32) || defined(__CYGWIN__)
1835 else if (strcmp(argv[optind], "register") == 0)
1836 ctl_command = REGISTER_COMMAND;
1837 else if (strcmp(argv[optind], "unregister") == 0)
1838 ctl_command = UNREGISTER_COMMAND;
1839 else if (strcmp(argv[optind], "runservice") == 0)
1840 ctl_command = RUN_AS_SERVICE_COMMAND;
1841 #endif
1842 else
1844 write_stderr(_("%s: unrecognized operation mode \"%s\"\n"), progname, argv[optind]);
1845 do_advice();
1846 exit(1);
1848 optind++;
1852 if (ctl_command == NO_COMMAND)
1854 write_stderr(_("%s: no operation specified\n"), progname);
1855 do_advice();
1856 exit(1);
1859 /* Note we put any -D switch into the env var above */
1860 pg_data = getenv("PGDATA");
1861 if (pg_data)
1863 pg_data = xstrdup(pg_data);
1864 canonicalize_path(pg_data);
1867 if (pg_data == NULL &&
1868 ctl_command != KILL_COMMAND && ctl_command != UNREGISTER_COMMAND)
1870 write_stderr(_("%s: no database directory specified "
1871 "and environment variable PGDATA unset\n"),
1872 progname);
1873 do_advice();
1874 exit(1);
1877 if (!wait_set)
1879 switch (ctl_command)
1881 case RESTART_COMMAND:
1882 case START_COMMAND:
1883 do_wait = false;
1884 break;
1885 case STOP_COMMAND:
1886 do_wait = true;
1887 break;
1888 default:
1889 break;
1893 if (ctl_command == RELOAD_COMMAND)
1895 sig = SIGHUP;
1896 do_wait = false;
1899 if (pg_data)
1901 snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);
1902 snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
1903 snprintf(conf_file, MAXPGPATH, "%s/postgresql.conf", pg_data);
1904 snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data);
1907 switch (ctl_command)
1909 case STATUS_COMMAND:
1910 do_status();
1911 break;
1912 case START_COMMAND:
1913 do_start();
1914 break;
1915 case STOP_COMMAND:
1916 do_stop();
1917 break;
1918 case RESTART_COMMAND:
1919 do_restart();
1920 break;
1921 case RELOAD_COMMAND:
1922 do_reload();
1923 break;
1924 case KILL_COMMAND:
1925 do_kill(killproc);
1926 break;
1927 #if defined(WIN32) || defined(__CYGWIN__)
1928 case REGISTER_COMMAND:
1929 pgwin32_doRegister();
1930 break;
1931 case UNREGISTER_COMMAND:
1932 pgwin32_doUnregister();
1933 break;
1934 case RUN_AS_SERVICE_COMMAND:
1935 pgwin32_doRunAsService();
1936 break;
1937 #endif
1938 default:
1939 break;
1942 exit(0);