Sort the output of --help mostly alphabetical, make it align better, make
[PostgreSQL.git] / src / bin / pg_ctl / pg_ctl.c
blob1a8b5983be4bc510053f6ca0ba9e3788017acd92
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 #ifndef HAVE_INT_OPTRESET
46 int optreset;
47 #endif
49 /* PID can be negative for standalone backend */
50 typedef long pgpid_t;
53 typedef enum
55 SMART_MODE,
56 FAST_MODE,
57 IMMEDIATE_MODE
58 } ShutdownMode;
61 typedef enum
63 NO_COMMAND = 0,
64 START_COMMAND,
65 STOP_COMMAND,
66 RESTART_COMMAND,
67 RELOAD_COMMAND,
68 STATUS_COMMAND,
69 KILL_COMMAND,
70 REGISTER_COMMAND,
71 UNREGISTER_COMMAND,
72 RUN_AS_SERVICE_COMMAND
73 } CtlCommand;
75 #define DEFAULT_WAIT 60
77 static bool do_wait = false;
78 static bool wait_set = false;
79 static int wait_seconds = DEFAULT_WAIT;
80 static bool silent_mode = false;
81 static ShutdownMode shutdown_mode = SMART_MODE;
82 static int sig = SIGTERM; /* default */
83 static CtlCommand ctl_command = NO_COMMAND;
84 static char *pg_data = NULL;
85 static char *pgdata_opt = NULL;
86 static char *post_opts = NULL;
87 static const char *progname;
88 static char *log_file = NULL;
89 static char *postgres_path = NULL;
90 static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
91 static char *register_username = NULL;
92 static char *register_password = NULL;
93 static char *argv0 = NULL;
94 static bool allow_core_files = false;
96 static void
97 write_stderr(const char *fmt,...)
98 /* This extension allows gcc to check the format string for consistency with
99 the supplied arguments. */
100 __attribute__((format(printf, 1, 2)));
101 static void *pg_malloc(size_t size);
102 static char *xstrdup(const char *s);
103 static void do_advice(void);
104 static void do_help(void);
105 static void set_mode(char *modeopt);
106 static void set_sig(char *signame);
107 static void do_start(void);
108 static void do_stop(void);
109 static void do_restart(void);
110 static void do_reload(void);
111 static void do_status(void);
112 static void do_kill(pgpid_t pid);
113 static void print_msg(const char *msg);
115 #if defined(WIN32) || defined(__CYGWIN__)
116 static bool pgwin32_IsInstalled(SC_HANDLE);
117 static char *pgwin32_CommandLine(bool);
118 static void pgwin32_doRegister(void);
119 static void pgwin32_doUnregister(void);
120 static void pgwin32_SetServiceStatus(DWORD);
121 static void WINAPI pgwin32_ServiceHandler(DWORD);
122 static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
123 static void pgwin32_doRunAsService(void);
124 static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo, bool as_service);
126 static SERVICE_STATUS status;
127 static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
128 static HANDLE shutdownHandles[2];
129 static pid_t postmasterPID = -1;
131 #define shutdownEvent shutdownHandles[0]
132 #define postmasterProcess shutdownHandles[1]
133 #endif
135 static pgpid_t get_pgpid(void);
136 static char **readfile(const char *path);
137 static int start_postmaster(void);
138 static void read_post_opts(void);
140 static bool test_postmaster_connection(bool);
141 static bool postmaster_is_alive(pid_t pid);
143 static char postopts_file[MAXPGPATH];
144 static char pid_file[MAXPGPATH];
145 static char conf_file[MAXPGPATH];
146 static char backup_file[MAXPGPATH];
148 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
149 static void unlimit_core_size(void);
150 #endif
153 #if defined(WIN32) || defined(__CYGWIN__)
154 static void
155 write_eventlog(int level, const char *line)
157 static HANDLE evtHandle = INVALID_HANDLE_VALUE;
159 if (evtHandle == INVALID_HANDLE_VALUE)
161 evtHandle = RegisterEventSource(NULL, "PostgreSQL");
162 if (evtHandle == NULL)
164 evtHandle = INVALID_HANDLE_VALUE;
165 return;
169 ReportEvent(evtHandle,
170 level,
172 0, /* All events are Id 0 */
173 NULL,
176 &line,
177 NULL);
179 #endif
182 * Write errors to stderr (or by equal means when stderr is
183 * not available).
185 static void
186 write_stderr(const char *fmt,...)
188 va_list ap;
190 va_start(ap, fmt);
191 #if !defined(WIN32) && !defined(__CYGWIN__)
192 /* On Unix, we just fprintf to stderr */
193 vfprintf(stderr, fmt, ap);
194 #else
197 * On Win32, we print to stderr if running on a console, or write to
198 * eventlog if running as a service
200 if (!isatty(fileno(stderr))) /* Running as a service */
202 char errbuf[2048]; /* Arbitrary size? */
204 vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
206 write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
208 else
209 /* Not running as service, write to stderr */
210 vfprintf(stderr, fmt, ap);
211 #endif
212 va_end(ap);
216 * routines to check memory allocations and fail noisily.
219 static void *
220 pg_malloc(size_t size)
222 void *result;
224 result = malloc(size);
225 if (!result)
227 write_stderr(_("%s: out of memory\n"), progname);
228 exit(1);
230 return result;
234 static char *
235 xstrdup(const char *s)
237 char *result;
239 result = strdup(s);
240 if (!result)
242 write_stderr(_("%s: out of memory\n"), progname);
243 exit(1);
245 return result;
249 * Given an already-localized string, print it to stdout unless the
250 * user has specified that no messages should be printed.
252 static void
253 print_msg(const char *msg)
255 if (!silent_mode)
257 fputs(msg, stdout);
258 fflush(stdout);
262 static pgpid_t
263 get_pgpid(void)
265 FILE *pidf;
266 long pid;
268 pidf = fopen(pid_file, "r");
269 if (pidf == NULL)
271 /* No pid file, not an error on startup */
272 if (errno == ENOENT)
273 return 0;
274 else
276 write_stderr(_("%s: could not open PID file \"%s\": %s\n"),
277 progname, pid_file, strerror(errno));
278 exit(1);
281 if (fscanf(pidf, "%ld", &pid) != 1)
283 write_stderr(_("%s: invalid data in PID file \"%s\"\n"),
284 progname, pid_file);
285 exit(1);
287 fclose(pidf);
288 return (pgpid_t) pid;
293 * get the lines from a text file - return NULL if file can't be opened
295 static char **
296 readfile(const char *path)
298 FILE *infile;
299 int maxlength = 0,
300 linelen = 0;
301 int nlines = 0;
302 char **result;
303 char *buffer;
304 int c;
306 if ((infile = fopen(path, "r")) == NULL)
307 return NULL;
309 /* pass over the file twice - the first time to size the result */
311 while ((c = fgetc(infile)) != EOF)
313 linelen++;
314 if (c == '\n')
316 nlines++;
317 if (linelen > maxlength)
318 maxlength = linelen;
319 linelen = 0;
323 /* handle last line without a terminating newline (yuck) */
324 if (linelen)
325 nlines++;
326 if (linelen > maxlength)
327 maxlength = linelen;
329 /* set up the result and the line buffer */
330 result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
331 buffer = (char *) pg_malloc(maxlength + 1);
333 /* now reprocess the file and store the lines */
334 rewind(infile);
335 nlines = 0;
336 while (fgets(buffer, maxlength + 1, infile) != NULL)
337 result[nlines++] = xstrdup(buffer);
339 fclose(infile);
340 free(buffer);
341 result[nlines] = NULL;
343 return result;
349 * start/test/stop routines
352 static int
353 start_postmaster(void)
355 char cmd[MAXPGPATH];
357 #ifndef WIN32
360 * Since there might be quotes to handle here, it is easier simply to pass
361 * everything to a shell to process them.
363 if (log_file != NULL)
364 snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1 &" SYSTEMQUOTE,
365 postgres_path, pgdata_opt, post_opts,
366 DEVNULL, log_file);
367 else
368 snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s < \"%s\" 2>&1 &" SYSTEMQUOTE,
369 postgres_path, pgdata_opt, post_opts, DEVNULL);
371 return system(cmd);
372 #else /* WIN32 */
375 * On win32 we don't use system(). So we don't need to use & (which would
376 * be START /B on win32). However, we still call the shell (CMD.EXE) with
377 * it to handle redirection etc.
379 PROCESS_INFORMATION pi;
381 if (log_file != NULL)
382 snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1" SYSTEMQUOTE,
383 postgres_path, pgdata_opt, post_opts, DEVNULL, log_file);
384 else
385 snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < \"%s\" 2>&1" SYSTEMQUOTE,
386 postgres_path, pgdata_opt, post_opts, DEVNULL);
388 if (!CreateRestrictedProcess(cmd, &pi, false))
389 return GetLastError();
390 CloseHandle(pi.hProcess);
391 CloseHandle(pi.hThread);
392 return 0;
393 #endif /* WIN32 */
399 * Find the pgport and try a connection
400 * Note that the checkpoint parameter enables a Windows service control
401 * manager checkpoint, it's got nothing to do with database checkpoints!!
403 static bool
404 test_postmaster_connection(bool do_checkpoint)
406 PGconn *conn;
407 bool success = false;
408 int i;
409 char portstr[32];
410 char *p;
411 char *q;
412 char connstr[128]; /* Should be way more than enough! */
414 *portstr = '\0';
417 * Look in post_opts for a -p switch.
419 * This parsing code is not amazingly bright; it could for instance
420 * get fooled if ' -p' occurs within a quoted argument value. Given
421 * that few people pass complicated settings in post_opts, it's
422 * probably good enough.
424 for (p = post_opts; *p;)
426 /* advance past whitespace */
427 while (isspace((unsigned char) *p))
428 p++;
430 if (strncmp(p, "-p", 2) == 0)
432 p += 2;
433 /* advance past any whitespace/quoting */
434 while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
435 p++;
436 /* find end of value (not including any ending quote!) */
437 q = p;
438 while (*q &&
439 !(isspace((unsigned char) *q) || *q == '\'' || *q == '"'))
440 q++;
441 /* and save the argument value */
442 strlcpy(portstr, p, Min((q - p) + 1, sizeof(portstr)));
443 /* keep looking, maybe there is another -p */
444 p = q;
446 /* Advance to next whitespace */
447 while (*p && !isspace((unsigned char) *p))
448 p++;
452 * Search config file for a 'port' option.
454 * This parsing code isn't amazingly bright either, but it should be
455 * okay for valid port settings.
457 if (!*portstr)
459 char **optlines;
461 optlines = readfile(conf_file);
462 if (optlines != NULL)
464 for (; *optlines != NULL; optlines++)
466 p = *optlines;
468 while (isspace((unsigned char) *p))
469 p++;
470 if (strncmp(p, "port", 4) != 0)
471 continue;
472 p += 4;
473 while (isspace((unsigned char) *p))
474 p++;
475 if (*p != '=')
476 continue;
477 p++;
478 /* advance past any whitespace/quoting */
479 while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
480 p++;
481 /* find end of value (not including any ending quote/comment!) */
482 q = p;
483 while (*q &&
484 !(isspace((unsigned char) *q) ||
485 *q == '\'' || *q == '"' || *q == '#'))
486 q++;
487 /* and save the argument value */
488 strlcpy(portstr, p, Min((q - p) + 1, sizeof(portstr)));
489 /* keep looking, maybe there is another */
494 /* Check environment */
495 if (!*portstr && getenv("PGPORT") != NULL)
496 strlcpy(portstr, getenv("PGPORT"), sizeof(portstr));
498 /* Else use compiled-in default */
499 if (!*portstr)
500 snprintf(portstr, sizeof(portstr), "%d", DEF_PGPORT);
503 * We need to set a connect timeout otherwise on Windows the SCM will
504 * probably timeout first
506 snprintf(connstr, sizeof(connstr),
507 "dbname=postgres port=%s connect_timeout=5", portstr);
509 for (i = 0; i < wait_seconds; i++)
511 if ((conn = PQconnectdb(connstr)) != NULL &&
512 (PQstatus(conn) == CONNECTION_OK ||
513 PQconnectionNeedsPassword(conn)))
515 PQfinish(conn);
516 success = true;
517 break;
519 else
521 PQfinish(conn);
523 #if defined(WIN32)
524 if (do_checkpoint)
527 * Increment the wait hint by 6 secs (connection timeout +
528 * sleep) We must do this to indicate to the SCM that our
529 * startup time is changing, otherwise it'll usually send a
530 * stop signal after 20 seconds, despite incrementing the
531 * checkpoint counter.
533 status.dwWaitHint += 6000;
534 status.dwCheckPoint++;
535 SetServiceStatus(hStatus, (LPSERVICE_STATUS) & status);
538 else
539 #endif
540 print_msg(".");
542 pg_usleep(1000000); /* 1 sec */
546 return success;
550 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
551 static void
552 unlimit_core_size(void)
554 struct rlimit lim;
556 getrlimit(RLIMIT_CORE, &lim);
557 if (lim.rlim_max == 0)
559 write_stderr(_("%s: cannot set core file size limit; disallowed by hard limit\n"),
560 progname);
561 return;
563 else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
565 lim.rlim_cur = lim.rlim_max;
566 setrlimit(RLIMIT_CORE, &lim);
569 #endif
571 static void
572 read_post_opts(void)
574 if (post_opts == NULL)
576 post_opts = ""; /* default */
577 if (ctl_command == RESTART_COMMAND)
579 char **optlines;
581 optlines = readfile(postopts_file);
582 if (optlines == NULL)
584 write_stderr(_("%s: could not read file \"%s\"\n"), progname, postopts_file);
585 exit(1);
587 else if (optlines[0] == NULL || optlines[1] != NULL)
589 write_stderr(_("%s: option file \"%s\" must have exactly one line\n"),
590 progname, postopts_file);
591 exit(1);
593 else
595 int len;
596 char *optline;
597 char *arg1;
599 optline = optlines[0];
600 /* trim off line endings */
601 len = strcspn(optline, "\r\n");
602 optline[len] = '\0';
605 * Are we at the first option, as defined by space and
606 * double-quote?
608 if ((arg1 = strstr(optline, " \"")) != NULL)
610 *arg1 = '\0'; /* terminate so we get only program name */
611 post_opts = arg1 + 1; /* point past whitespace */
613 if (postgres_path == NULL)
614 postgres_path = optline;
620 static void
621 do_start(void)
623 pgpid_t pid;
624 pgpid_t old_pid = 0;
625 int exitcode;
627 if (ctl_command != RESTART_COMMAND)
629 old_pid = get_pgpid();
630 if (old_pid != 0)
631 write_stderr(_("%s: another server might be running; "
632 "trying to start server anyway\n"),
633 progname);
636 read_post_opts();
638 /* No -D or -D already added during server start */
639 if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
640 pgdata_opt = "";
642 if (postgres_path == NULL)
644 char *postmaster_path;
645 int ret;
647 postmaster_path = pg_malloc(MAXPGPATH);
649 if ((ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
650 postmaster_path)) < 0)
652 char full_path[MAXPGPATH];
654 if (find_my_exec(argv0, full_path) < 0)
655 strlcpy(full_path, progname, sizeof(full_path));
657 if (ret == -1)
658 write_stderr(_("The program \"postgres\" is needed by %s "
659 "but was not found in the\n"
660 "same directory as \"%s\".\n"
661 "Check your installation.\n"),
662 progname, full_path);
663 else
664 write_stderr(_("The program \"postgres\" was found by \"%s\"\n"
665 "but was not the same version as %s.\n"
666 "Check your installation.\n"),
667 full_path, progname);
668 exit(1);
670 postgres_path = postmaster_path;
673 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
674 if (allow_core_files)
675 unlimit_core_size();
676 #endif
678 exitcode = start_postmaster();
679 if (exitcode != 0)
681 write_stderr(_("%s: could not start server: exit code was %d\n"),
682 progname, exitcode);
683 exit(1);
686 if (old_pid != 0)
688 pg_usleep(1000000);
689 pid = get_pgpid();
690 if (pid == old_pid)
692 write_stderr(_("%s: could not start server\n"
693 "Examine the log output.\n"),
694 progname);
695 exit(1);
699 if (do_wait)
701 print_msg(_("waiting for server to start..."));
703 if (test_postmaster_connection(false) == false)
705 printf(_("could not start server\n"));
706 exit(1);
708 else
710 print_msg(_(" done\n"));
711 print_msg(_("server started\n"));
714 else
715 print_msg(_("server starting\n"));
719 static void
720 do_stop(void)
722 int cnt;
723 pgpid_t pid;
724 struct stat statbuf;
726 pid = get_pgpid();
728 if (pid == 0) /* no pid file */
730 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
731 write_stderr(_("Is server running?\n"));
732 exit(1);
734 else if (pid < 0) /* standalone backend, not postmaster */
736 pid = -pid;
737 write_stderr(_("%s: cannot stop server; "
738 "single-user server is running (PID: %ld)\n"),
739 progname, pid);
740 exit(1);
743 if (kill((pid_t) pid, sig) != 0)
745 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
746 strerror(errno));
747 exit(1);
750 if (!do_wait)
752 print_msg(_("server shutting down\n"));
753 return;
755 else
757 if ((shutdown_mode == SMART_MODE) && (stat(backup_file, &statbuf) == 0))
759 print_msg(_("WARNING: online backup mode is active\n"
760 "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
763 print_msg(_("waiting for server to shut down..."));
765 for (cnt = 0; cnt < wait_seconds; cnt++)
767 if ((pid = get_pgpid()) != 0)
769 print_msg(".");
770 pg_usleep(1000000); /* 1 sec */
772 else
773 break;
776 if (pid != 0) /* pid file still exists */
778 print_msg(_(" failed\n"));
780 write_stderr(_("%s: server does not shut down\n"), progname);
781 exit(1);
783 print_msg(_(" done\n"));
785 printf(_("server stopped\n"));
791 * restart/reload routines
794 static void
795 do_restart(void)
797 int cnt;
798 pgpid_t pid;
799 struct stat statbuf;
801 pid = get_pgpid();
803 if (pid == 0) /* no pid file */
805 write_stderr(_("%s: PID file \"%s\" does not exist\n"),
806 progname, pid_file);
807 write_stderr(_("Is server running?\n"));
808 write_stderr(_("starting server anyway\n"));
809 do_start();
810 return;
812 else if (pid < 0) /* standalone backend, not postmaster */
814 pid = -pid;
815 if (postmaster_is_alive((pid_t) pid))
817 write_stderr(_("%s: cannot restart server; "
818 "single-user server is running (PID: %ld)\n"),
819 progname, pid);
820 write_stderr(_("Please terminate the single-user server and try again.\n"));
821 exit(1);
825 if (postmaster_is_alive((pid_t) pid))
827 if (kill((pid_t) pid, sig) != 0)
829 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
830 strerror(errno));
831 exit(1);
834 if ((shutdown_mode == SMART_MODE) && (stat(backup_file, &statbuf) == 0))
836 print_msg(_("WARNING: online backup mode is active\n"
837 "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
840 print_msg(_("waiting for server to shut down..."));
842 /* always wait for restart */
844 for (cnt = 0; cnt < wait_seconds; cnt++)
846 if ((pid = get_pgpid()) != 0)
848 print_msg(".");
849 pg_usleep(1000000); /* 1 sec */
851 else
852 break;
855 if (pid != 0) /* pid file still exists */
857 print_msg(_(" failed\n"));
859 write_stderr(_("%s: server does not shut down\n"), progname);
860 exit(1);
863 print_msg(_(" done\n"));
864 printf(_("server stopped\n"));
866 else
868 write_stderr(_("%s: old server process (PID: %ld) seems to be gone\n"),
869 progname, pid);
870 write_stderr(_("starting server anyway\n"));
873 do_start();
877 static void
878 do_reload(void)
880 pgpid_t pid;
882 pid = get_pgpid();
883 if (pid == 0) /* no pid file */
885 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
886 write_stderr(_("Is server running?\n"));
887 exit(1);
889 else if (pid < 0) /* standalone backend, not postmaster */
891 pid = -pid;
892 write_stderr(_("%s: cannot reload server; "
893 "single-user server is running (PID: %ld)\n"),
894 progname, pid);
895 write_stderr(_("Please terminate the single-user server and try again.\n"));
896 exit(1);
899 if (kill((pid_t) pid, sig) != 0)
901 write_stderr(_("%s: could not send reload signal (PID: %ld): %s\n"),
902 progname, pid, strerror(errno));
903 exit(1);
906 print_msg(_("server signaled\n"));
910 * utility routines
913 static bool
914 postmaster_is_alive(pid_t pid)
917 * Test to see if the process is still there. Note that we do not
918 * consider an EPERM failure to mean that the process is still there;
919 * EPERM must mean that the given PID belongs to some other userid, and
920 * considering the permissions on $PGDATA, that means it's not the
921 * postmaster we are after.
923 * Don't believe that our own PID or parent shell's PID is the postmaster,
924 * either. (Windows hasn't got getppid(), though.)
926 if (pid == getpid())
927 return false;
928 #ifndef WIN32
929 if (pid == getppid())
930 return false;
931 #endif
932 if (kill(pid, 0) == 0)
933 return true;
934 return false;
937 static void
938 do_status(void)
940 pgpid_t pid;
942 pid = get_pgpid();
943 if (pid != 0) /* 0 means no pid file */
945 if (pid < 0) /* standalone backend */
947 pid = -pid;
948 if (postmaster_is_alive((pid_t) pid))
950 printf(_("%s: single-user server is running (PID: %ld)\n"),
951 progname, pid);
952 return;
955 else
956 /* postmaster */
958 if (postmaster_is_alive((pid_t) pid))
960 char **optlines;
962 printf(_("%s: server is running (PID: %ld)\n"),
963 progname, pid);
965 optlines = readfile(postopts_file);
966 if (optlines != NULL)
967 for (; *optlines != NULL; optlines++)
968 fputs(*optlines, stdout);
969 return;
973 printf(_("%s: no server running\n"), progname);
974 exit(1);
979 static void
980 do_kill(pgpid_t pid)
982 if (kill((pid_t) pid, sig) != 0)
984 write_stderr(_("%s: could not send signal %d (PID: %ld): %s\n"),
985 progname, sig, pid, strerror(errno));
986 exit(1);
990 #if defined(WIN32) || defined(__CYGWIN__)
992 static bool
993 pgwin32_IsInstalled(SC_HANDLE hSCM)
995 SC_HANDLE hService = OpenService(hSCM, register_servicename, SERVICE_QUERY_CONFIG);
996 bool bResult = (hService != NULL);
998 if (bResult)
999 CloseServiceHandle(hService);
1000 return bResult;
1003 static char *
1004 pgwin32_CommandLine(bool registration)
1006 static char cmdLine[MAXPGPATH];
1007 int ret;
1009 #ifdef __CYGWIN__
1010 char buf[MAXPGPATH];
1011 #endif
1013 if (registration)
1015 ret = find_my_exec(argv0, cmdLine);
1016 if (ret != 0)
1018 write_stderr(_("%s: could not find own program executable\n"), progname);
1019 exit(1);
1022 else
1024 ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
1025 cmdLine);
1026 if (ret != 0)
1028 write_stderr(_("%s: could not find postgres program executable\n"), progname);
1029 exit(1);
1033 #ifdef __CYGWIN__
1034 /* need to convert to windows path */
1035 cygwin_conv_to_full_win32_path(cmdLine, buf);
1036 strcpy(cmdLine, buf);
1037 #endif
1039 if (registration)
1041 if (pg_strcasecmp(cmdLine + strlen(cmdLine) - 4, ".exe"))
1043 /* If commandline does not end in .exe, append it */
1044 strcat(cmdLine, ".exe");
1046 strcat(cmdLine, " runservice -N \"");
1047 strcat(cmdLine, register_servicename);
1048 strcat(cmdLine, "\"");
1051 if (pg_data)
1053 strcat(cmdLine, " -D \"");
1054 strcat(cmdLine, pg_data);
1055 strcat(cmdLine, "\"");
1058 if (registration && do_wait)
1059 strcat(cmdLine, " -w");
1061 if (registration && wait_seconds != DEFAULT_WAIT)
1062 /* concatenate */
1063 sprintf(cmdLine + strlen(cmdLine), " -t %d", wait_seconds);
1065 if (post_opts)
1067 strcat(cmdLine, " ");
1068 if (registration)
1069 strcat(cmdLine, " -o \"");
1070 strcat(cmdLine, post_opts);
1071 if (registration)
1072 strcat(cmdLine, "\"");
1075 return cmdLine;
1078 static void
1079 pgwin32_doRegister(void)
1081 SC_HANDLE hService;
1082 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1084 if (hSCM == NULL)
1086 write_stderr(_("%s: could not open service manager\n"), progname);
1087 exit(1);
1089 if (pgwin32_IsInstalled(hSCM))
1091 CloseServiceHandle(hSCM);
1092 write_stderr(_("%s: service \"%s\" already registered\n"), progname, register_servicename);
1093 exit(1);
1096 if ((hService = CreateService(hSCM, register_servicename, register_servicename,
1097 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
1098 SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
1099 pgwin32_CommandLine(true),
1100 NULL, NULL, "RPCSS\0", register_username, register_password)) == NULL)
1102 CloseServiceHandle(hSCM);
1103 write_stderr(_("%s: could not register service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1104 exit(1);
1106 CloseServiceHandle(hService);
1107 CloseServiceHandle(hSCM);
1110 static void
1111 pgwin32_doUnregister(void)
1113 SC_HANDLE hService;
1114 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1116 if (hSCM == NULL)
1118 write_stderr(_("%s: could not open service manager\n"), progname);
1119 exit(1);
1121 if (!pgwin32_IsInstalled(hSCM))
1123 CloseServiceHandle(hSCM);
1124 write_stderr(_("%s: service \"%s\" not registered\n"), progname, register_servicename);
1125 exit(1);
1128 if ((hService = OpenService(hSCM, register_servicename, DELETE)) == NULL)
1130 CloseServiceHandle(hSCM);
1131 write_stderr(_("%s: could not open service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1132 exit(1);
1134 if (!DeleteService(hService))
1136 CloseServiceHandle(hService);
1137 CloseServiceHandle(hSCM);
1138 write_stderr(_("%s: could not unregister service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1139 exit(1);
1141 CloseServiceHandle(hService);
1142 CloseServiceHandle(hSCM);
1145 static void
1146 pgwin32_SetServiceStatus(DWORD currentState)
1148 status.dwCurrentState = currentState;
1149 SetServiceStatus(hStatus, (LPSERVICE_STATUS) & status);
1152 static void WINAPI
1153 pgwin32_ServiceHandler(DWORD request)
1155 switch (request)
1157 case SERVICE_CONTROL_STOP:
1158 case SERVICE_CONTROL_SHUTDOWN:
1161 * We only need a short wait hint here as it just needs to wait
1162 * for the next checkpoint. They occur every 5 seconds during
1163 * shutdown
1165 status.dwWaitHint = 10000;
1166 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1167 SetEvent(shutdownEvent);
1168 return;
1170 case SERVICE_CONTROL_PAUSE:
1171 /* Win32 config reloading */
1172 status.dwWaitHint = 5000;
1173 kill(postmasterPID, SIGHUP);
1174 return;
1176 /* FIXME: These could be used to replace other signals etc */
1177 case SERVICE_CONTROL_CONTINUE:
1178 case SERVICE_CONTROL_INTERROGATE:
1179 default:
1180 break;
1184 static void WINAPI
1185 pgwin32_ServiceMain(DWORD argc, LPTSTR * argv)
1187 PROCESS_INFORMATION pi;
1188 DWORD ret;
1189 DWORD check_point_start;
1191 /* Initialize variables */
1192 status.dwWin32ExitCode = S_OK;
1193 status.dwCheckPoint = 0;
1194 status.dwWaitHint = 60000;
1195 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
1196 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
1197 status.dwServiceSpecificExitCode = 0;
1198 status.dwCurrentState = SERVICE_START_PENDING;
1200 memset(&pi, 0, sizeof(pi));
1202 read_post_opts();
1204 /* Register the control request handler */
1205 if ((hStatus = RegisterServiceCtrlHandler(register_servicename, pgwin32_ServiceHandler)) == (SERVICE_STATUS_HANDLE) 0)
1206 return;
1208 if ((shutdownEvent = CreateEvent(NULL, true, false, NULL)) == NULL)
1209 return;
1211 /* Start the postmaster */
1212 pgwin32_SetServiceStatus(SERVICE_START_PENDING);
1213 if (!CreateRestrictedProcess(pgwin32_CommandLine(false), &pi, true))
1215 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1216 return;
1218 postmasterPID = pi.dwProcessId;
1219 postmasterProcess = pi.hProcess;
1220 CloseHandle(pi.hThread);
1222 if (do_wait)
1224 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Waiting for server startup...\n"));
1225 if (test_postmaster_connection(true) == false)
1227 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Timed out waiting for server startup\n"));
1228 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1229 return;
1231 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Server started and accepting connections\n"));
1235 * Save the checkpoint value as it might have been incremented in
1236 * test_postmaster_connection
1238 check_point_start = status.dwCheckPoint;
1240 pgwin32_SetServiceStatus(SERVICE_RUNNING);
1242 /* Wait for quit... */
1243 ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);
1245 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1246 switch (ret)
1248 case WAIT_OBJECT_0: /* shutdown event */
1249 kill(postmasterPID, SIGINT);
1252 * Increment the checkpoint and try again Abort after 12
1253 * checkpoints as the postmaster has probably hung
1255 while (WaitForSingleObject(postmasterProcess, 5000) == WAIT_TIMEOUT && status.dwCheckPoint < 12)
1256 status.dwCheckPoint++;
1257 break;
1259 case (WAIT_OBJECT_0 + 1): /* postmaster went down */
1260 break;
1262 default:
1263 /* shouldn't get here? */
1264 break;
1267 CloseHandle(shutdownEvent);
1268 CloseHandle(postmasterProcess);
1270 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1273 static void
1274 pgwin32_doRunAsService(void)
1276 SERVICE_TABLE_ENTRY st[] = {{register_servicename, pgwin32_ServiceMain},
1277 {NULL, NULL}};
1279 if (StartServiceCtrlDispatcher(st) == 0)
1281 write_stderr(_("%s: could not start service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1282 exit(1);
1288 * Mingw headers are incomplete, and so are the libraries. So we have to load
1289 * a whole lot of API functions dynamically. Since we have to do this anyway,
1290 * also load the couple of functions that *do* exist in minwg headers but not
1291 * on NT4. That way, we don't break on NT4.
1293 typedef BOOL(WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
1294 typedef BOOL(WINAPI * __IsProcessInJob) (HANDLE, HANDLE, PBOOL);
1295 typedef HANDLE(WINAPI * __CreateJobObject) (LPSECURITY_ATTRIBUTES, LPCTSTR);
1296 typedef BOOL(WINAPI * __SetInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD);
1297 typedef BOOL(WINAPI * __AssignProcessToJobObject) (HANDLE, HANDLE);
1298 typedef BOOL(WINAPI * __QueryInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD);
1300 /* Windows API define missing from MingW headers */
1301 #define DISABLE_MAX_PRIVILEGE 0x1
1304 * Create a restricted token, a job object sandbox, and execute the specified
1305 * process with it.
1307 * Returns 0 on success, non-zero on failure, same as CreateProcess().
1309 * On NT4, or any other system not containing the required functions, will
1310 * launch the process under the current token without doing any modifications.
1312 * NOTE! Job object will only work when running as a service, because it's
1313 * automatically destroyed when pg_ctl exits.
1315 static int
1316 CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo, bool as_service)
1318 int r;
1319 BOOL b;
1320 STARTUPINFO si;
1321 HANDLE origToken;
1322 HANDLE restrictedToken;
1323 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
1324 SID_AND_ATTRIBUTES dropSids[2];
1326 /* Functions loaded dynamically */
1327 __CreateRestrictedToken _CreateRestrictedToken = NULL;
1328 __IsProcessInJob _IsProcessInJob = NULL;
1329 __CreateJobObject _CreateJobObject = NULL;
1330 __SetInformationJobObject _SetInformationJobObject = NULL;
1331 __AssignProcessToJobObject _AssignProcessToJobObject = NULL;
1332 __QueryInformationJobObject _QueryInformationJobObject = NULL;
1333 HANDLE Kernel32Handle;
1334 HANDLE Advapi32Handle;
1336 ZeroMemory(&si, sizeof(si));
1337 si.cb = sizeof(si);
1339 Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
1340 if (Advapi32Handle != NULL)
1342 _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
1345 if (_CreateRestrictedToken == NULL)
1348 * NT4 doesn't have CreateRestrictedToken, so just call ordinary
1349 * CreateProcess
1351 write_stderr("WARNING: cannot create restricted tokens on this platform\n");
1352 if (Advapi32Handle != NULL)
1353 FreeLibrary(Advapi32Handle);
1354 return CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, processInfo);
1357 /* Open the current token to use as a base for the restricted one */
1358 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
1360 write_stderr("Failed to open process token: %lu\n", GetLastError());
1361 return 0;
1364 /* Allocate list of SIDs to remove */
1365 ZeroMemory(&dropSids, sizeof(dropSids));
1366 if (!AllocateAndInitializeSid(&NtAuthority, 2,
1367 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
1368 0, &dropSids[0].Sid) ||
1369 !AllocateAndInitializeSid(&NtAuthority, 2,
1370 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
1371 0, &dropSids[1].Sid))
1373 write_stderr("Failed to allocate SIDs: %lu\n", GetLastError());
1374 return 0;
1377 b = _CreateRestrictedToken(origToken,
1378 DISABLE_MAX_PRIVILEGE,
1379 sizeof(dropSids) / sizeof(dropSids[0]),
1380 dropSids,
1381 0, NULL,
1382 0, NULL,
1383 &restrictedToken);
1385 FreeSid(dropSids[1].Sid);
1386 FreeSid(dropSids[0].Sid);
1387 CloseHandle(origToken);
1388 FreeLibrary(Advapi32Handle);
1390 if (!b)
1392 write_stderr("Failed to create restricted token: %lu\n", GetLastError());
1393 return 0;
1396 r = CreateProcessAsUser(restrictedToken, NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, processInfo);
1398 Kernel32Handle = LoadLibrary("KERNEL32.DLL");
1399 if (Kernel32Handle != NULL)
1401 _IsProcessInJob = (__IsProcessInJob) GetProcAddress(Kernel32Handle, "IsProcessInJob");
1402 _CreateJobObject = (__CreateJobObject) GetProcAddress(Kernel32Handle, "CreateJobObjectA");
1403 _SetInformationJobObject = (__SetInformationJobObject) GetProcAddress(Kernel32Handle, "SetInformationJobObject");
1404 _AssignProcessToJobObject = (__AssignProcessToJobObject) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject");
1405 _QueryInformationJobObject = (__QueryInformationJobObject) GetProcAddress(Kernel32Handle, "QueryInformationJobObject");
1408 /* Verify that we found all functions */
1409 if (_IsProcessInJob == NULL || _CreateJobObject == NULL || _SetInformationJobObject == NULL || _AssignProcessToJobObject == NULL || _QueryInformationJobObject == NULL)
1412 * IsProcessInJob() is not available on < WinXP, so there is no need
1413 * to log the error every time in that case
1415 OSVERSIONINFO osv;
1417 osv.dwOSVersionInfoSize = sizeof(osv);
1418 if (!GetVersionEx(&osv) || /* could not get version */
1419 (osv.dwMajorVersion == 5 && osv.dwMinorVersion > 0) || /* 5.1=xp, 5.2=2003, etc */
1420 osv.dwMajorVersion > 5) /* anything newer should have the API */
1423 * Log error if we can't get version, or if we're on WinXP/2003 or
1424 * newer
1426 write_stderr("WARNING: could not locate all job object functions in system API\n");
1428 else
1430 BOOL inJob;
1432 if (_IsProcessInJob(processInfo->hProcess, NULL, &inJob))
1434 if (!inJob)
1437 * Job objects are working, and the new process isn't in one,
1438 * so we can create one safely. If any problems show up when
1439 * setting it, we're going to ignore them.
1441 HANDLE job;
1442 char jobname[128];
1444 sprintf(jobname, "PostgreSQL_%lu", processInfo->dwProcessId);
1446 job = _CreateJobObject(NULL, jobname);
1447 if (job)
1449 JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
1450 JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
1451 JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
1452 OSVERSIONINFO osv;
1454 ZeroMemory(&basicLimit, sizeof(basicLimit));
1455 ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
1456 ZeroMemory(&securityLimit, sizeof(securityLimit));
1458 basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
1459 basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
1460 _SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));
1462 uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
1463 JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
1464 JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
1466 if (as_service)
1468 osv.dwOSVersionInfoSize = sizeof(osv);
1469 if (!GetVersionEx(&osv) ||
1470 osv.dwMajorVersion < 6 ||
1471 (osv.dwMajorVersion == 6 && osv.dwMinorVersion == 0))
1474 * On Windows 7 (and presumably later), JOB_OBJECT_UILIMIT_HANDLES prevents us from
1475 * starting as a service. So we only enable it on Vista and earlier (version <= 6.0)
1477 uiRestrictions.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
1480 _SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));
1482 securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
1483 securityLimit.JobToken = restrictedToken;
1484 _SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));
1486 _AssignProcessToJobObject(job, processInfo->hProcess);
1492 #ifndef __CYGWIN__
1493 AddUserToDacl(processInfo->hProcess);
1494 #endif
1496 CloseHandle(restrictedToken);
1498 ResumeThread(processInfo->hThread);
1500 FreeLibrary(Kernel32Handle);
1503 * We intentionally don't close the job object handle, because we want the
1504 * object to live on until pg_ctl shuts down.
1506 return r;
1508 #endif
1510 static void
1511 do_advice(void)
1513 write_stderr(_("Try \"%s --help\" for more information.\n"), progname);
1518 static void
1519 do_help(void)
1521 printf(_("%s is a utility to start, stop, restart, reload configuration files,\n"
1522 "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n\n"), progname);
1523 printf(_("Usage:\n"));
1524 printf(_(" %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n"), progname);
1525 printf(_(" %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"), progname);
1526 printf(_(" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"
1527 " [-o \"OPTIONS\"]\n"), progname);
1528 printf(_(" %s reload [-D DATADIR] [-s]\n"), progname);
1529 printf(_(" %s status [-D DATADIR]\n"), progname);
1530 printf(_(" %s kill SIGNALNAME PID\n"), progname);
1531 #if defined(WIN32) || defined(__CYGWIN__)
1532 printf(_(" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n"
1533 " [-w] [-t SECS] [-o \"OPTIONS\"]\n"), progname);
1534 printf(_(" %s unregister [-N SERVICENAME]\n"), progname);
1535 #endif
1537 printf(_("\nCommon options:\n"));
1538 printf(_(" -D, --pgdata DATADIR location of the database storage area\n"));
1539 printf(_(" -s, --silent only print errors, no informational messages\n"));
1540 printf(_(" -t SECS seconds to wait when using -w option\n"));
1541 printf(_(" -w wait until operation completes\n"));
1542 printf(_(" -W do not wait until operation completes\n"));
1543 printf(_(" --help show this help, then exit\n"));
1544 printf(_(" --version output version information, then exit\n"));
1545 printf(_("(The default is to wait for shutdown, but not for start or restart.)\n\n"));
1546 printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
1548 printf(_("\nOptions for start or restart:\n"));
1549 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
1550 printf(_(" -c, --core-files allow postgres to produce core files\n"));
1551 #else
1552 printf(_(" -c, --core-files not applicable on this platform\n"));
1553 #endif
1554 printf(_(" -l, --log FILENAME write (or append) server log to FILENAME\n"));
1555 printf(_(" -o OPTIONS command line options to pass to postgres\n"
1556 " (PostgreSQL server executable)\n"));
1557 printf(_(" -p PATH-TO-POSTGRES normally not necessary\n"));
1558 printf(_("\nOptions for stop or restart:\n"));
1559 printf(_(" -m SHUTDOWN-MODE can be \"smart\", \"fast\", or \"immediate\"\n"));
1561 printf(_("\nShutdown modes are:\n"));
1562 printf(_(" smart quit after all clients have disconnected\n"));
1563 printf(_(" fast quit directly, with proper shutdown\n"));
1564 printf(_(" immediate quit without complete shutdown; will lead to recovery on restart\n"));
1566 printf(_("\nAllowed signal names for kill:\n"));
1567 printf(" HUP INT QUIT ABRT TERM USR1 USR2\n");
1569 #if defined(WIN32) || defined(__CYGWIN__)
1570 printf(_("\nOptions for register and unregister:\n"));
1571 printf(_(" -N SERVICENAME service name with which to register PostgreSQL server\n"));
1572 printf(_(" -P PASSWORD password of account to register PostgreSQL server\n"));
1573 printf(_(" -U USERNAME user name of account to register PostgreSQL server\n"));
1574 #endif
1576 printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
1581 static void
1582 set_mode(char *modeopt)
1584 if (strcmp(modeopt, "s") == 0 || strcmp(modeopt, "smart") == 0)
1586 shutdown_mode = SMART_MODE;
1587 sig = SIGTERM;
1589 else if (strcmp(modeopt, "f") == 0 || strcmp(modeopt, "fast") == 0)
1591 shutdown_mode = FAST_MODE;
1592 sig = SIGINT;
1594 else if (strcmp(modeopt, "i") == 0 || strcmp(modeopt, "immediate") == 0)
1596 shutdown_mode = IMMEDIATE_MODE;
1597 sig = SIGQUIT;
1599 else
1601 write_stderr(_("%s: unrecognized shutdown mode \"%s\"\n"), progname, modeopt);
1602 do_advice();
1603 exit(1);
1609 static void
1610 set_sig(char *signame)
1612 if (!strcmp(signame, "HUP"))
1613 sig = SIGHUP;
1614 else if (!strcmp(signame, "INT"))
1615 sig = SIGINT;
1616 else if (!strcmp(signame, "QUIT"))
1617 sig = SIGQUIT;
1618 else if (!strcmp(signame, "ABRT"))
1619 sig = SIGABRT;
1622 * probably should NOT provide SIGKILL
1624 * else if (!strcmp(signame,"KILL")) sig = SIGKILL;
1626 else if (!strcmp(signame, "TERM"))
1627 sig = SIGTERM;
1628 else if (!strcmp(signame, "USR1"))
1629 sig = SIGUSR1;
1630 else if (!strcmp(signame, "USR2"))
1631 sig = SIGUSR2;
1632 else
1634 write_stderr(_("%s: unrecognized signal name \"%s\"\n"), progname, signame);
1635 do_advice();
1636 exit(1);
1644 main(int argc, char **argv)
1646 static struct option long_options[] = {
1647 {"help", no_argument, NULL, '?'},
1648 {"version", no_argument, NULL, 'V'},
1649 {"log", required_argument, NULL, 'l'},
1650 {"mode", required_argument, NULL, 'm'},
1651 {"pgdata", required_argument, NULL, 'D'},
1652 {"silent", no_argument, NULL, 's'},
1653 {"timeout", required_argument, NULL, 't'},
1654 {"core-files", no_argument, NULL, 'c'},
1655 {NULL, 0, NULL, 0}
1658 int option_index;
1659 int c;
1660 pgpid_t killproc = 0;
1662 #if defined(WIN32) || defined(__CYGWIN__)
1663 setvbuf(stderr, NULL, _IONBF, 0);
1664 #endif
1666 progname = get_progname(argv[0]);
1667 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_ctl"));
1670 * save argv[0] so do_start() can look for the postmaster if necessary. we
1671 * don't look for postmaster here because in many cases we won't need it.
1673 argv0 = argv[0];
1675 umask(077);
1677 /* support --help and --version even if invoked as root */
1678 if (argc > 1)
1680 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 ||
1681 strcmp(argv[1], "-?") == 0)
1683 do_help();
1684 exit(0);
1686 else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0)
1688 puts("pg_ctl (PostgreSQL) " PG_VERSION);
1689 exit(0);
1694 * Disallow running as root, to forestall any possible security holes.
1696 #ifndef WIN32
1697 if (geteuid() == 0)
1699 write_stderr(_("%s: cannot be run as root\n"
1700 "Please log in (using, e.g., \"su\") as the "
1701 "(unprivileged) user that will\n"
1702 "own the server process.\n"),
1703 progname);
1704 exit(1);
1706 #endif
1709 * 'Action' can be before or after args so loop over both. Some
1710 * getopt_long() implementations will reorder argv[] to place all flags
1711 * first (GNU?), but we don't rely on it. Our /port version doesn't do
1712 * that.
1714 optind = 1;
1716 /* process command-line options */
1717 while (optind < argc)
1719 while ((c = getopt_long(argc, argv, "cD:l:m:N:o:p:P:st:U:wW", long_options, &option_index)) != -1)
1721 switch (c)
1723 case 'D':
1725 char *pgdata_D;
1726 char *env_var = pg_malloc(strlen(optarg) + 8);
1728 pgdata_D = xstrdup(optarg);
1729 canonicalize_path(pgdata_D);
1730 snprintf(env_var, strlen(optarg) + 8, "PGDATA=%s",
1731 pgdata_D);
1732 putenv(env_var);
1735 * We could pass PGDATA just in an environment
1736 * variable but we do -D too for clearer postmaster
1737 * 'ps' display
1739 pgdata_opt = pg_malloc(strlen(pgdata_D) + 7);
1740 snprintf(pgdata_opt, strlen(pgdata_D) + 7,
1741 "-D \"%s\" ",
1742 pgdata_D);
1743 break;
1745 case 'l':
1746 log_file = xstrdup(optarg);
1747 break;
1748 case 'm':
1749 set_mode(optarg);
1750 break;
1751 case 'N':
1752 register_servicename = xstrdup(optarg);
1753 break;
1754 case 'o':
1755 post_opts = xstrdup(optarg);
1756 break;
1757 case 'p':
1758 postgres_path = xstrdup(optarg);
1759 break;
1760 case 'P':
1761 register_password = xstrdup(optarg);
1762 break;
1763 case 's':
1764 silent_mode = true;
1765 break;
1766 case 't':
1767 wait_seconds = atoi(optarg);
1768 break;
1769 case 'U':
1770 if (strchr(optarg, '\\'))
1771 register_username = xstrdup(optarg);
1772 else
1773 /* Prepend .\ for local accounts */
1775 register_username = malloc(strlen(optarg) + 3);
1776 if (!register_username)
1778 write_stderr(_("%s: out of memory\n"), progname);
1779 exit(1);
1781 strcpy(register_username, ".\\");
1782 strcat(register_username, optarg);
1784 break;
1785 case 'w':
1786 do_wait = true;
1787 wait_set = true;
1788 break;
1789 case 'W':
1790 do_wait = false;
1791 wait_set = true;
1792 break;
1793 case 'c':
1794 allow_core_files = true;
1795 break;
1796 default:
1797 /* getopt_long already issued a suitable error message */
1798 do_advice();
1799 exit(1);
1803 /* Process an action */
1804 if (optind < argc)
1806 if (ctl_command != NO_COMMAND)
1808 write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]);
1809 do_advice();
1810 exit(1);
1813 if (strcmp(argv[optind], "start") == 0)
1814 ctl_command = START_COMMAND;
1815 else if (strcmp(argv[optind], "stop") == 0)
1816 ctl_command = STOP_COMMAND;
1817 else if (strcmp(argv[optind], "restart") == 0)
1818 ctl_command = RESTART_COMMAND;
1819 else if (strcmp(argv[optind], "reload") == 0)
1820 ctl_command = RELOAD_COMMAND;
1821 else if (strcmp(argv[optind], "status") == 0)
1822 ctl_command = STATUS_COMMAND;
1823 else if (strcmp(argv[optind], "kill") == 0)
1825 if (argc - optind < 3)
1827 write_stderr(_("%s: missing arguments for kill mode\n"), progname);
1828 do_advice();
1829 exit(1);
1831 ctl_command = KILL_COMMAND;
1832 set_sig(argv[++optind]);
1833 killproc = atol(argv[++optind]);
1835 #if defined(WIN32) || defined(__CYGWIN__)
1836 else if (strcmp(argv[optind], "register") == 0)
1837 ctl_command = REGISTER_COMMAND;
1838 else if (strcmp(argv[optind], "unregister") == 0)
1839 ctl_command = UNREGISTER_COMMAND;
1840 else if (strcmp(argv[optind], "runservice") == 0)
1841 ctl_command = RUN_AS_SERVICE_COMMAND;
1842 #endif
1843 else
1845 write_stderr(_("%s: unrecognized operation mode \"%s\"\n"), progname, argv[optind]);
1846 do_advice();
1847 exit(1);
1849 optind++;
1853 if (ctl_command == NO_COMMAND)
1855 write_stderr(_("%s: no operation specified\n"), progname);
1856 do_advice();
1857 exit(1);
1860 /* Note we put any -D switch into the env var above */
1861 pg_data = getenv("PGDATA");
1862 if (pg_data)
1864 pg_data = xstrdup(pg_data);
1865 canonicalize_path(pg_data);
1868 if (pg_data == NULL &&
1869 ctl_command != KILL_COMMAND && ctl_command != UNREGISTER_COMMAND)
1871 write_stderr(_("%s: no database directory specified "
1872 "and environment variable PGDATA unset\n"),
1873 progname);
1874 do_advice();
1875 exit(1);
1878 if (!wait_set)
1880 switch (ctl_command)
1882 case RESTART_COMMAND:
1883 case START_COMMAND:
1884 do_wait = false;
1885 break;
1886 case STOP_COMMAND:
1887 do_wait = true;
1888 break;
1889 default:
1890 break;
1894 if (ctl_command == RELOAD_COMMAND)
1896 sig = SIGHUP;
1897 do_wait = false;
1900 if (pg_data)
1902 snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);
1903 snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
1904 snprintf(conf_file, MAXPGPATH, "%s/postgresql.conf", pg_data);
1905 snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data);
1908 switch (ctl_command)
1910 case STATUS_COMMAND:
1911 do_status();
1912 break;
1913 case START_COMMAND:
1914 do_start();
1915 break;
1916 case STOP_COMMAND:
1917 do_stop();
1918 break;
1919 case RESTART_COMMAND:
1920 do_restart();
1921 break;
1922 case RELOAD_COMMAND:
1923 do_reload();
1924 break;
1925 case KILL_COMMAND:
1926 do_kill(killproc);
1927 break;
1928 #if defined(WIN32) || defined(__CYGWIN__)
1929 case REGISTER_COMMAND:
1930 pgwin32_doRegister();
1931 break;
1932 case UNREGISTER_COMMAND:
1933 pgwin32_doUnregister();
1934 break;
1935 case RUN_AS_SERVICE_COMMAND:
1936 pgwin32_doRunAsService();
1937 break;
1938 #endif
1939 default:
1940 break;
1943 exit(0);