1 /*-------------------------------------------------------------------------
3 * pg_ctl --- start/stops/restarts the PostgreSQL server
5 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
7 * src/bin/pg_ctl/pg_ctl.c
9 *-------------------------------------------------------------------------
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 0x0501
20 #include "postgres_fe.h"
25 #include <sys/types.h>
29 #ifdef HAVE_SYS_RESOURCE_H
31 #include <sys/resource.h>
34 #include "libpq/pqsignal.h"
35 #include "getopt_long.h"
36 #include "miscadmin.h"
38 #if defined(__CYGWIN__)
39 #include <sys/cygwin.h>
41 /* Cygwin defines WIN32 in windows.h, but we don't want it. */
45 /* PID can be negative for standalone backend */
69 RUN_AS_SERVICE_COMMAND
72 #define DEFAULT_WAIT 60
74 static bool do_wait = false;
75 static bool wait_set = false;
76 static int wait_seconds = DEFAULT_WAIT;
77 static bool silent_mode = false;
78 static ShutdownMode shutdown_mode = SMART_MODE;
79 static int sig = SIGTERM; /* default */
80 static CtlCommand ctl_command = NO_COMMAND;
81 static char *pg_data = NULL;
82 static char *pgdata_opt = NULL;
83 static char *post_opts = NULL;
84 static const char *progname;
85 static char *log_file = NULL;
86 static char *exec_path = NULL;
87 static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
88 static char *register_username = NULL;
89 static char *register_password = NULL;
90 static char *argv0 = NULL;
91 static bool allow_core_files = false;
94 write_stderr(const char *fmt,...)
95 /* This extension allows gcc to check the format string for consistency with
96 the supplied arguments. */
97 __attribute__((format(printf, 1, 2)));
98 static void *pg_malloc(size_t size);
99 static char *xstrdup(const char *s);
100 static void do_advice(void);
101 static void do_help(void);
102 static void set_mode(char *modeopt);
103 static void set_sig(char *signame);
104 static void do_init(void);
105 static void do_start(void);
106 static void do_stop(void);
107 static void do_restart(void);
108 static void do_reload(void);
109 static void do_status(void);
110 static void do_kill(pgpid_t pid);
111 static void print_msg(const char *msg);
113 #if defined(WIN32) || defined(__CYGWIN__)
114 static bool pgwin32_IsInstalled(SC_HANDLE);
115 static char *pgwin32_CommandLine(bool);
116 static void pgwin32_doRegister(void);
117 static void pgwin32_doUnregister(void);
118 static void pgwin32_SetServiceStatus(DWORD);
119 static void WINAPI pgwin32_ServiceHandler(DWORD);
120 static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
121 static void pgwin32_doRunAsService(void);
122 static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service);
124 static DWORD pgctl_start_type = SERVICE_AUTO_START;
125 static SERVICE_STATUS status;
126 static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
127 static HANDLE shutdownHandles[2];
128 static pid_t postmasterPID = -1;
130 #define shutdownEvent shutdownHandles[0]
131 #define postmasterProcess shutdownHandles[1]
134 static pgpid_t get_pgpid(void);
135 static char **readfile(const char *path);
136 static int start_postmaster(void);
137 static void read_post_opts(void);
139 static PGPing test_postmaster_connection(bool);
140 static bool postmaster_is_alive(pid_t pid);
142 static char postopts_file[MAXPGPATH];
143 static char pid_file[MAXPGPATH];
144 static char conf_file[MAXPGPATH];
145 static char backup_file[MAXPGPATH];
146 static char recovery_file[MAXPGPATH];
148 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
149 static void unlimit_core_size(void);
153 #if defined(WIN32) || defined(__CYGWIN__)
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;
169 ReportEvent(evtHandle,
172 0, /* All events are Id 0 */
182 * Write errors to stderr (or by equal means when stderr is
186 write_stderr(const char *fmt,...)
191 #if !defined(WIN32) && !defined(__CYGWIN__)
192 /* On Unix, we just fprintf to stderr */
193 vfprintf(stderr, fmt, ap);
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);
209 /* Not running as service, write to stderr */
210 vfprintf(stderr, fmt, ap);
216 * routines to check memory allocations and fail noisily.
220 pg_malloc(size_t size)
224 result = malloc(size);
227 write_stderr(_("%s: out of memory\n"), progname);
235 xstrdup(const char *s)
242 write_stderr(_("%s: out of memory\n"), progname);
249 * Given an already-localized string, print it to stdout unless the
250 * user has specified that no messages should be printed.
253 print_msg(const char *msg)
268 pidf = fopen(pid_file, "r");
271 /* No pid file, not an error on startup */
276 write_stderr(_("%s: could not open PID file \"%s\": %s\n"),
277 progname, pid_file, strerror(errno));
281 if (fscanf(pidf, "%ld", &pid) != 1)
283 write_stderr(_("%s: invalid data in PID file \"%s\"\n"),
288 return (pgpid_t) pid;
293 * get the lines from a text file - return NULL if file can't be opened
296 readfile(const char *path)
306 if ((infile = fopen(path, "r")) == NULL)
309 /* pass over the file twice - the first time to size the result */
311 while ((c = fgetc(infile)) != EOF)
317 if (linelen > maxlength)
323 /* handle last line without a terminating newline (yuck) */
326 if (linelen > maxlength)
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 */
336 while (fgets(buffer, maxlength + 1, infile) != NULL)
337 result[nlines++] = xstrdup(buffer);
341 result[nlines] = NULL;
349 * start/test/stop routines
353 start_postmaster(void)
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 exec_path, pgdata_opt, post_opts,
368 snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s < \"%s\" 2>&1 &" SYSTEMQUOTE,
369 exec_path, pgdata_opt, post_opts, DEVNULL);
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 exec_path, pgdata_opt, post_opts, DEVNULL, log_file);
385 snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < \"%s\" 2>&1" SYSTEMQUOTE,
386 exec_path, pgdata_opt, post_opts, DEVNULL);
388 if (!CreateRestrictedProcess(cmd, &pi, false))
389 return GetLastError();
390 CloseHandle(pi.hProcess);
391 CloseHandle(pi.hThread);
399 * Find the pgport and try a connection
401 * Note that the checkpoint parameter enables a Windows service control
402 * manager checkpoint, it's got nothing to do with database checkpoints!!
405 test_postmaster_connection(bool do_checkpoint)
407 PGPing ret = PQPING_OK; /* assume success for wait == zero */
412 char connstr[128]; /* Should be way more than enough! */
417 * Look in post_opts for a -p switch.
419 * This parsing code is not amazingly bright; it could for instance get
420 * fooled if ' -p' occurs within a quoted argument value. Given that few
421 * people pass complicated settings in post_opts, it's probably good
424 for (p = post_opts; *p;)
426 /* advance past whitespace */
427 while (isspace((unsigned char) *p))
430 if (strncmp(p, "-p", 2) == 0)
433 /* advance past any whitespace/quoting */
434 while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
436 /* find end of value (not including any ending quote!) */
439 !(isspace((unsigned char) *q) || *q == '\'' || *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 */
446 /* Advance to next whitespace */
447 while (*p && !isspace((unsigned char) *p))
452 * Search config file for a 'port' option.
454 * This parsing code isn't amazingly bright either, but it should be okay
455 * for valid port settings.
461 optlines = readfile(conf_file);
462 if (optlines != NULL)
464 for (; *optlines != NULL; optlines++)
468 while (isspace((unsigned char) *p))
470 if (strncmp(p, "port", 4) != 0)
473 while (isspace((unsigned char) *p))
478 /* advance past any whitespace/quoting */
479 while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
481 /* find end of value (not including any ending quote/comment!) */
484 !(isspace((unsigned char) *q) ||
485 *q == '\'' || *q == '"' || *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[0] && getenv("PGPORT") != NULL)
496 strlcpy(portstr, getenv("PGPORT"), sizeof(portstr));
498 /* Else use compiled-in default */
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 ret = PQping(connstr);
512 if (ret == PQPING_OK || ret == PQPING_NO_ATTEMPT)
514 /* No response, or startup still in process; wait */
519 * Increment the wait hint by 6 secs (connection timeout +
520 * sleep) We must do this to indicate to the SCM that our
521 * startup time is changing, otherwise it'll usually send a
522 * stop signal after 20 seconds, despite incrementing the
523 * checkpoint counter.
525 status.dwWaitHint += 6000;
526 status.dwCheckPoint++;
527 SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
533 pg_usleep(1000000); /* 1 sec */
536 /* return result of last call to PQping */
541 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
543 unlimit_core_size(void)
547 getrlimit(RLIMIT_CORE, &lim);
548 if (lim.rlim_max == 0)
550 write_stderr(_("%s: cannot set core file size limit; disallowed by hard limit\n"),
554 else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
556 lim.rlim_cur = lim.rlim_max;
557 setrlimit(RLIMIT_CORE, &lim);
565 if (post_opts == NULL)
567 post_opts = ""; /* default */
568 if (ctl_command == RESTART_COMMAND)
572 optlines = readfile(postopts_file);
573 if (optlines == NULL)
575 write_stderr(_("%s: could not read file \"%s\"\n"), progname, postopts_file);
578 else if (optlines[0] == NULL || optlines[1] != NULL)
580 write_stderr(_("%s: option file \"%s\" must have exactly one line\n"),
581 progname, postopts_file);
590 optline = optlines[0];
591 /* trim off line endings */
592 len = strcspn(optline, "\r\n");
596 * Are we at the first option, as defined by space and
599 if ((arg1 = strstr(optline, " \"")) != NULL)
601 *arg1 = '\0'; /* terminate so we get only program
603 post_opts = arg1 + 1; /* point past whitespace */
605 if (exec_path == NULL)
613 find_other_exec_or_die(const char *argv0, const char *target, const char *versionstr)
618 found_path = pg_malloc(MAXPGPATH);
620 if ((ret = find_other_exec(argv0, target, versionstr, found_path)) < 0)
622 char full_path[MAXPGPATH];
624 if (find_my_exec(argv0, full_path) < 0)
625 strlcpy(full_path, progname, sizeof(full_path));
628 write_stderr(_("The program \"%s\" is needed by %s "
629 "but was not found in the\n"
630 "same directory as \"%s\".\n"
631 "Check your installation.\n"),
632 target, progname, full_path);
634 write_stderr(_("The program \"%s\" was found by \"%s\"\n"
635 "but was not the same version as %s.\n"
636 "Check your installation.\n"),
637 target, full_path, progname);
649 if (exec_path == NULL)
650 exec_path = find_other_exec_or_die(argv0, "initdb", "initdb (PostgreSQL) " PG_VERSION "\n");
652 if (pgdata_opt == NULL)
655 if (post_opts == NULL)
659 snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s" SYSTEMQUOTE,
660 exec_path, pgdata_opt, post_opts);
662 snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s > \"%s\"" SYSTEMQUOTE,
663 exec_path, pgdata_opt, post_opts, DEVNULL);
665 if (system(cmd) != 0)
667 write_stderr(_("%s: database system initialization failed\n"), progname);
679 if (ctl_command != RESTART_COMMAND)
681 old_pid = get_pgpid();
683 write_stderr(_("%s: another server might be running; "
684 "trying to start server anyway\n"),
690 /* No -D or -D already added during server start */
691 if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
694 if (exec_path == NULL)
695 exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
697 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
698 if (allow_core_files)
703 * If possible, tell the postmaster our parent shell's PID (see the
704 * comments in CreateLockFile() for motivation). Windows hasn't got
705 * getppid() unfortunately.
709 static char env_var[32];
711 snprintf(env_var, sizeof(env_var), "PG_GRANDPARENT_PID=%d",
717 exitcode = start_postmaster();
720 write_stderr(_("%s: could not start server: exit code was %d\n"),
731 write_stderr(_("%s: could not start server\n"
732 "Examine the log output.\n"),
740 print_msg(_("waiting for server to start..."));
742 switch (test_postmaster_connection(false))
745 print_msg(_(" done\n"));
746 print_msg(_("server started\n"));
749 print_msg(_(" stopped waiting\n"));
750 print_msg(_("server is still starting up\n"));
752 case PQPING_NO_RESPONSE:
753 print_msg(_(" stopped waiting\n"));
754 write_stderr(_("%s: could not start server\n"
755 "Examine the log output.\n"),
759 case PQPING_NO_ATTEMPT:
760 print_msg(_(" failed\n"));
761 write_stderr(_("%s: could not wait for server because of misconfiguration\n"),
767 print_msg(_("server starting\n"));
780 if (pid == 0) /* no pid file */
782 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
783 write_stderr(_("Is server running?\n"));
786 else if (pid < 0) /* standalone backend, not postmaster */
789 write_stderr(_("%s: cannot stop server; "
790 "single-user server is running (PID: %ld)\n"),
795 if (kill((pid_t) pid, sig) != 0)
797 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
804 print_msg(_("server shutting down\n"));
810 * If backup_label exists, an online backup is running. Warn the
811 * user that smart shutdown will wait for it to finish. However, if
812 * recovery.conf is also present, we're recovering from an online
813 * backup instead of performing one.
815 if (shutdown_mode == SMART_MODE &&
816 stat(backup_file, &statbuf) == 0 &&
817 stat(recovery_file, &statbuf) != 0)
819 print_msg(_("WARNING: online backup mode is active\n"
820 "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
823 print_msg(_("waiting for server to shut down..."));
825 for (cnt = 0; cnt < wait_seconds; cnt++)
827 if ((pid = get_pgpid()) != 0)
830 pg_usleep(1000000); /* 1 sec */
836 if (pid != 0) /* pid file still exists */
838 print_msg(_(" failed\n"));
840 write_stderr(_("%s: server does not shut down\n"), progname);
843 print_msg(_(" done\n"));
845 print_msg(_("server stopped\n"));
851 * restart/reload routines
863 if (pid == 0) /* no pid file */
865 write_stderr(_("%s: PID file \"%s\" does not exist\n"),
867 write_stderr(_("Is server running?\n"));
868 write_stderr(_("starting server anyway\n"));
872 else if (pid < 0) /* standalone backend, not postmaster */
875 if (postmaster_is_alive((pid_t) pid))
877 write_stderr(_("%s: cannot restart server; "
878 "single-user server is running (PID: %ld)\n"),
880 write_stderr(_("Please terminate the single-user server and try again.\n"));
885 if (postmaster_is_alive((pid_t) pid))
887 if (kill((pid_t) pid, sig) != 0)
889 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
895 * If backup_label exists, an online backup is running. Warn the
896 * user that smart shutdown will wait for it to finish. However, if
897 * recovery.conf is also present, we're recovering from an online
898 * backup instead of performing one.
900 if (shutdown_mode == SMART_MODE &&
901 stat(backup_file, &statbuf) == 0 &&
902 stat(recovery_file, &statbuf) != 0)
904 print_msg(_("WARNING: online backup mode is active\n"
905 "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
908 print_msg(_("waiting for server to shut down..."));
910 /* always wait for restart */
912 for (cnt = 0; cnt < wait_seconds; cnt++)
914 if ((pid = get_pgpid()) != 0)
917 pg_usleep(1000000); /* 1 sec */
923 if (pid != 0) /* pid file still exists */
925 print_msg(_(" failed\n"));
927 write_stderr(_("%s: server does not shut down\n"), progname);
931 print_msg(_(" done\n"));
932 print_msg(_("server stopped\n"));
936 write_stderr(_("%s: old server process (PID: %ld) seems to be gone\n"),
938 write_stderr(_("starting server anyway\n"));
951 if (pid == 0) /* no pid file */
953 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
954 write_stderr(_("Is server running?\n"));
957 else if (pid < 0) /* standalone backend, not postmaster */
960 write_stderr(_("%s: cannot reload server; "
961 "single-user server is running (PID: %ld)\n"),
963 write_stderr(_("Please terminate the single-user server and try again.\n"));
967 if (kill((pid_t) pid, sig) != 0)
969 write_stderr(_("%s: could not send reload signal (PID: %ld): %s\n"),
970 progname, pid, strerror(errno));
974 print_msg(_("server signaled\n"));
982 postmaster_is_alive(pid_t pid)
985 * Test to see if the process is still there. Note that we do not
986 * consider an EPERM failure to mean that the process is still there;
987 * EPERM must mean that the given PID belongs to some other userid, and
988 * considering the permissions on $PGDATA, that means it's not the
989 * postmaster we are after.
991 * Don't believe that our own PID or parent shell's PID is the postmaster,
992 * either. (Windows hasn't got getppid(), though.)
997 if (pid == getppid())
1000 if (kill(pid, 0) == 0)
1011 if (pid != 0) /* 0 means no pid file */
1013 if (pid < 0) /* standalone backend */
1016 if (postmaster_is_alive((pid_t) pid))
1018 printf(_("%s: single-user server is running (PID: %ld)\n"),
1026 if (postmaster_is_alive((pid_t) pid))
1030 printf(_("%s: server is running (PID: %ld)\n"),
1033 optlines = readfile(postopts_file);
1034 if (optlines != NULL)
1035 for (; *optlines != NULL; optlines++)
1036 fputs(*optlines, stdout);
1041 printf(_("%s: no server running\n"), progname);
1048 do_kill(pgpid_t pid)
1050 if (kill((pid_t) pid, sig) != 0)
1052 write_stderr(_("%s: could not send signal %d (PID: %ld): %s\n"),
1053 progname, sig, pid, strerror(errno));
1058 #if defined(WIN32) || defined(__CYGWIN__)
1061 pgwin32_IsInstalled(SC_HANDLE hSCM)
1063 SC_HANDLE hService = OpenService(hSCM, register_servicename, SERVICE_QUERY_CONFIG);
1064 bool bResult = (hService != NULL);
1067 CloseServiceHandle(hService);
1072 pgwin32_CommandLine(bool registration)
1074 static char cmdLine[MAXPGPATH];
1078 char buf[MAXPGPATH];
1083 ret = find_my_exec(argv0, cmdLine);
1086 write_stderr(_("%s: could not find own program executable\n"), progname);
1092 ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
1096 write_stderr(_("%s: could not find postgres program executable\n"), progname);
1102 /* need to convert to windows path */
1103 #if CYGWIN_VERSION_DLL_MAJOR >= 1007
1104 cygwin_conv_path(CCP_POSIX_TO_WIN_A, cmdLine, buf, sizeof(buf));
1106 cygwin_conv_to_full_win32_path(cmdLine, buf);
1108 strcpy(cmdLine, buf);
1113 if (pg_strcasecmp(cmdLine + strlen(cmdLine) - 4, ".exe"))
1115 /* If commandline does not end in .exe, append it */
1116 strcat(cmdLine, ".exe");
1118 strcat(cmdLine, " runservice -N \"");
1119 strcat(cmdLine, register_servicename);
1120 strcat(cmdLine, "\"");
1125 strcat(cmdLine, " -D \"");
1126 strcat(cmdLine, pg_data);
1127 strcat(cmdLine, "\"");
1130 if (registration && do_wait)
1131 strcat(cmdLine, " -w");
1133 if (registration && wait_seconds != DEFAULT_WAIT)
1135 sprintf(cmdLine + strlen(cmdLine), " -t %d", wait_seconds);
1139 strcat(cmdLine, " ");
1141 strcat(cmdLine, " -o \"");
1142 strcat(cmdLine, post_opts);
1144 strcat(cmdLine, "\"");
1151 pgwin32_doRegister(void)
1154 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1158 write_stderr(_("%s: could not open service manager\n"), progname);
1161 if (pgwin32_IsInstalled(hSCM))
1163 CloseServiceHandle(hSCM);
1164 write_stderr(_("%s: service \"%s\" already registered\n"), progname, register_servicename);
1168 if ((hService = CreateService(hSCM, register_servicename, register_servicename,
1169 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
1170 pgctl_start_type, SERVICE_ERROR_NORMAL,
1171 pgwin32_CommandLine(true),
1172 NULL, NULL, "RPCSS\0", register_username, register_password)) == NULL)
1174 CloseServiceHandle(hSCM);
1175 write_stderr(_("%s: could not register service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1178 CloseServiceHandle(hService);
1179 CloseServiceHandle(hSCM);
1183 pgwin32_doUnregister(void)
1186 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1190 write_stderr(_("%s: could not open service manager\n"), progname);
1193 if (!pgwin32_IsInstalled(hSCM))
1195 CloseServiceHandle(hSCM);
1196 write_stderr(_("%s: service \"%s\" not registered\n"), progname, register_servicename);
1200 if ((hService = OpenService(hSCM, register_servicename, DELETE)) == NULL)
1202 CloseServiceHandle(hSCM);
1203 write_stderr(_("%s: could not open service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1206 if (!DeleteService(hService))
1208 CloseServiceHandle(hService);
1209 CloseServiceHandle(hSCM);
1210 write_stderr(_("%s: could not unregister service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1213 CloseServiceHandle(hService);
1214 CloseServiceHandle(hSCM);
1218 pgwin32_SetServiceStatus(DWORD currentState)
1220 status.dwCurrentState = currentState;
1221 SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
1225 pgwin32_ServiceHandler(DWORD request)
1229 case SERVICE_CONTROL_STOP:
1230 case SERVICE_CONTROL_SHUTDOWN:
1233 * We only need a short wait hint here as it just needs to wait
1234 * for the next checkpoint. They occur every 5 seconds during
1237 status.dwWaitHint = 10000;
1238 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1239 SetEvent(shutdownEvent);
1242 case SERVICE_CONTROL_PAUSE:
1243 /* Win32 config reloading */
1244 status.dwWaitHint = 5000;
1245 kill(postmasterPID, SIGHUP);
1248 /* FIXME: These could be used to replace other signals etc */
1249 case SERVICE_CONTROL_CONTINUE:
1250 case SERVICE_CONTROL_INTERROGATE:
1257 pgwin32_ServiceMain(DWORD argc, LPTSTR *argv)
1259 PROCESS_INFORMATION pi;
1261 DWORD check_point_start;
1263 /* Initialize variables */
1264 status.dwWin32ExitCode = S_OK;
1265 status.dwCheckPoint = 0;
1266 status.dwWaitHint = 60000;
1267 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
1268 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
1269 status.dwServiceSpecificExitCode = 0;
1270 status.dwCurrentState = SERVICE_START_PENDING;
1272 memset(&pi, 0, sizeof(pi));
1276 /* Register the control request handler */
1277 if ((hStatus = RegisterServiceCtrlHandler(register_servicename, pgwin32_ServiceHandler)) == (SERVICE_STATUS_HANDLE) 0)
1280 if ((shutdownEvent = CreateEvent(NULL, true, false, NULL)) == NULL)
1283 /* Start the postmaster */
1284 pgwin32_SetServiceStatus(SERVICE_START_PENDING);
1285 if (!CreateRestrictedProcess(pgwin32_CommandLine(false), &pi, true))
1287 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1290 postmasterPID = pi.dwProcessId;
1291 postmasterProcess = pi.hProcess;
1292 CloseHandle(pi.hThread);
1296 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Waiting for server startup...\n"));
1297 if (test_postmaster_connection(true) != PQPING_OK)
1299 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Timed out waiting for server startup\n"));
1300 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1303 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Server started and accepting connections\n"));
1307 * Save the checkpoint value as it might have been incremented in
1308 * test_postmaster_connection
1310 check_point_start = status.dwCheckPoint;
1312 pgwin32_SetServiceStatus(SERVICE_RUNNING);
1314 /* Wait for quit... */
1315 ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);
1317 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1320 case WAIT_OBJECT_0: /* shutdown event */
1321 kill(postmasterPID, SIGINT);
1324 * Increment the checkpoint and try again Abort after 12
1325 * checkpoints as the postmaster has probably hung
1327 while (WaitForSingleObject(postmasterProcess, 5000) == WAIT_TIMEOUT && status.dwCheckPoint < 12)
1328 status.dwCheckPoint++;
1331 case (WAIT_OBJECT_0 + 1): /* postmaster went down */
1335 /* shouldn't get here? */
1339 CloseHandle(shutdownEvent);
1340 CloseHandle(postmasterProcess);
1342 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1346 pgwin32_doRunAsService(void)
1348 SERVICE_TABLE_ENTRY st[] = {{register_servicename, pgwin32_ServiceMain},
1351 if (StartServiceCtrlDispatcher(st) == 0)
1353 write_stderr(_("%s: could not start service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1360 * Mingw headers are incomplete, and so are the libraries. So we have to load
1361 * a whole lot of API functions dynamically. Since we have to do this anyway,
1362 * also load the couple of functions that *do* exist in minwg headers but not
1363 * on NT4. That way, we don't break on NT4.
1365 typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
1366 typedef BOOL (WINAPI * __IsProcessInJob) (HANDLE, HANDLE, PBOOL);
1367 typedef HANDLE (WINAPI * __CreateJobObject) (LPSECURITY_ATTRIBUTES, LPCTSTR);
1368 typedef BOOL (WINAPI * __SetInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD);
1369 typedef BOOL (WINAPI * __AssignProcessToJobObject) (HANDLE, HANDLE);
1370 typedef BOOL (WINAPI * __QueryInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD);
1372 /* Windows API define missing from MingW headers */
1373 #define DISABLE_MAX_PRIVILEGE 0x1
1376 * Create a restricted token, a job object sandbox, and execute the specified
1379 * Returns 0 on success, non-zero on failure, same as CreateProcess().
1381 * On NT4, or any other system not containing the required functions, will
1382 * launch the process under the current token without doing any modifications.
1384 * NOTE! Job object will only work when running as a service, because it's
1385 * automatically destroyed when pg_ctl exits.
1388 CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service)
1394 HANDLE restrictedToken;
1395 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
1396 SID_AND_ATTRIBUTES dropSids[2];
1398 /* Functions loaded dynamically */
1399 __CreateRestrictedToken _CreateRestrictedToken = NULL;
1400 __IsProcessInJob _IsProcessInJob = NULL;
1401 __CreateJobObject _CreateJobObject = NULL;
1402 __SetInformationJobObject _SetInformationJobObject = NULL;
1403 __AssignProcessToJobObject _AssignProcessToJobObject = NULL;
1404 __QueryInformationJobObject _QueryInformationJobObject = NULL;
1405 HANDLE Kernel32Handle;
1406 HANDLE Advapi32Handle;
1408 ZeroMemory(&si, sizeof(si));
1411 Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
1412 if (Advapi32Handle != NULL)
1414 _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
1417 if (_CreateRestrictedToken == NULL)
1420 * NT4 doesn't have CreateRestrictedToken, so just call ordinary
1423 write_stderr("WARNING: cannot create restricted tokens on this platform\n");
1424 if (Advapi32Handle != NULL)
1425 FreeLibrary(Advapi32Handle);
1426 return CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, processInfo);
1429 /* Open the current token to use as a base for the restricted one */
1430 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
1432 write_stderr("Failed to open process token: %lu\n", GetLastError());
1436 /* Allocate list of SIDs to remove */
1437 ZeroMemory(&dropSids, sizeof(dropSids));
1438 if (!AllocateAndInitializeSid(&NtAuthority, 2,
1439 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
1440 0, &dropSids[0].Sid) ||
1441 !AllocateAndInitializeSid(&NtAuthority, 2,
1442 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
1443 0, &dropSids[1].Sid))
1445 write_stderr("Failed to allocate SIDs: %lu\n", GetLastError());
1449 b = _CreateRestrictedToken(origToken,
1450 DISABLE_MAX_PRIVILEGE,
1451 sizeof(dropSids) / sizeof(dropSids[0]),
1457 FreeSid(dropSids[1].Sid);
1458 FreeSid(dropSids[0].Sid);
1459 CloseHandle(origToken);
1460 FreeLibrary(Advapi32Handle);
1464 write_stderr("Failed to create restricted token: %lu\n", GetLastError());
1469 AddUserToTokenDacl(restrictedToken);
1472 r = CreateProcessAsUser(restrictedToken, NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, processInfo);
1474 Kernel32Handle = LoadLibrary("KERNEL32.DLL");
1475 if (Kernel32Handle != NULL)
1477 _IsProcessInJob = (__IsProcessInJob) GetProcAddress(Kernel32Handle, "IsProcessInJob");
1478 _CreateJobObject = (__CreateJobObject) GetProcAddress(Kernel32Handle, "CreateJobObjectA");
1479 _SetInformationJobObject = (__SetInformationJobObject) GetProcAddress(Kernel32Handle, "SetInformationJobObject");
1480 _AssignProcessToJobObject = (__AssignProcessToJobObject) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject");
1481 _QueryInformationJobObject = (__QueryInformationJobObject) GetProcAddress(Kernel32Handle, "QueryInformationJobObject");
1484 /* Verify that we found all functions */
1485 if (_IsProcessInJob == NULL || _CreateJobObject == NULL || _SetInformationJobObject == NULL || _AssignProcessToJobObject == NULL || _QueryInformationJobObject == NULL)
1488 * IsProcessInJob() is not available on < WinXP, so there is no need
1489 * to log the error every time in that case
1493 osv.dwOSVersionInfoSize = sizeof(osv);
1494 if (!GetVersionEx(&osv) || /* could not get version */
1495 (osv.dwMajorVersion == 5 && osv.dwMinorVersion > 0) || /* 5.1=xp, 5.2=2003, etc */
1496 osv.dwMajorVersion > 5) /* anything newer should have the API */
1499 * Log error if we can't get version, or if we're on WinXP/2003 or
1502 write_stderr("WARNING: could not locate all job object functions in system API\n");
1508 if (_IsProcessInJob(processInfo->hProcess, NULL, &inJob))
1513 * Job objects are working, and the new process isn't in one,
1514 * so we can create one safely. If any problems show up when
1515 * setting it, we're going to ignore them.
1520 sprintf(jobname, "PostgreSQL_%lu", processInfo->dwProcessId);
1522 job = _CreateJobObject(NULL, jobname);
1525 JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
1526 JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
1527 JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
1530 ZeroMemory(&basicLimit, sizeof(basicLimit));
1531 ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
1532 ZeroMemory(&securityLimit, sizeof(securityLimit));
1534 basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
1535 basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
1536 _SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));
1538 uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
1539 JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
1540 JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
1544 osv.dwOSVersionInfoSize = sizeof(osv);
1545 if (!GetVersionEx(&osv) ||
1546 osv.dwMajorVersion < 6 ||
1547 (osv.dwMajorVersion == 6 && osv.dwMinorVersion == 0))
1550 * On Windows 7 (and presumably later),
1551 * JOB_OBJECT_UILIMIT_HANDLES prevents us from
1552 * starting as a service. So we only enable it on
1553 * Vista and earlier (version <= 6.0)
1555 uiRestrictions.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
1558 _SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));
1560 securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
1561 securityLimit.JobToken = restrictedToken;
1562 _SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));
1564 _AssignProcessToJobObject(job, processInfo->hProcess);
1571 CloseHandle(restrictedToken);
1573 ResumeThread(processInfo->hThread);
1575 FreeLibrary(Kernel32Handle);
1578 * We intentionally don't close the job object handle, because we want the
1579 * object to live on until pg_ctl shuts down.
1588 write_stderr(_("Try \"%s --help\" for more information.\n"), progname);
1596 printf(_("%s is a utility to start, stop, restart, reload configuration files,\n"
1597 "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n\n"), progname);
1598 printf(_("Usage:\n"));
1599 printf(_(" %s init[db] [-D DATADIR] [-s] [-o \"OPTIONS\"]\n"), progname);
1600 printf(_(" %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n"), progname);
1601 printf(_(" %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"), progname);
1602 printf(_(" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"
1603 " [-o \"OPTIONS\"]\n"), progname);
1604 printf(_(" %s reload [-D DATADIR] [-s]\n"), progname);
1605 printf(_(" %s status [-D DATADIR]\n"), progname);
1606 printf(_(" %s kill SIGNALNAME PID\n"), progname);
1607 #if defined(WIN32) || defined(__CYGWIN__)
1608 printf(_(" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n"
1609 " [-S START-TYPE] [-w] [-t SECS] [-o \"OPTIONS\"]\n"), progname);
1610 printf(_(" %s unregister [-N SERVICENAME]\n"), progname);
1613 printf(_("\nCommon options:\n"));
1614 printf(_(" -D, --pgdata DATADIR location of the database storage area\n"));
1615 printf(_(" -s, --silent only print errors, no informational messages\n"));
1616 printf(_(" -t SECS seconds to wait when using -w option\n"));
1617 printf(_(" -w wait until operation completes\n"));
1618 printf(_(" -W do not wait until operation completes\n"));
1619 printf(_(" --help show this help, then exit\n"));
1620 printf(_(" --version output version information, then exit\n"));
1621 printf(_("(The default is to wait for shutdown, but not for start or restart.)\n\n"));
1622 printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
1624 printf(_("\nOptions for start or restart:\n"));
1625 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
1626 printf(_(" -c, --core-files allow postgres to produce core files\n"));
1628 printf(_(" -c, --core-files not applicable on this platform\n"));
1630 printf(_(" -l, --log FILENAME write (or append) server log to FILENAME\n"));
1631 printf(_(" -o OPTIONS command line options to pass to postgres\n"
1632 " (PostgreSQL server executable) or initdb\n"));
1633 printf(_(" -p PATH-TO-POSTGRES normally not necessary\n"));
1634 printf(_("\nOptions for stop or restart:\n"));
1635 printf(_(" -m SHUTDOWN-MODE can be \"smart\", \"fast\", or \"immediate\"\n"));
1637 printf(_("\nShutdown modes are:\n"));
1638 printf(_(" smart quit after all clients have disconnected\n"));
1639 printf(_(" fast quit directly, with proper shutdown\n"));
1640 printf(_(" immediate quit without complete shutdown; will lead to recovery on restart\n"));
1642 printf(_("\nAllowed signal names for kill:\n"));
1643 printf(" HUP INT QUIT ABRT TERM USR1 USR2\n");
1645 #if defined(WIN32) || defined(__CYGWIN__)
1646 printf(_("\nOptions for register and unregister:\n"));
1647 printf(_(" -N SERVICENAME service name with which to register PostgreSQL server\n"));
1648 printf(_(" -P PASSWORD password of account to register PostgreSQL server\n"));
1649 printf(_(" -U USERNAME user name of account to register PostgreSQL server\n"));
1650 printf(_(" -S START-TYPE service start type to register PostgreSQL server\n"));
1652 printf(_("\nStart types are:\n"));
1653 printf(_(" auto start service automatically during system startup (default)\n"));
1654 printf(_(" demand start service on demand\n"));
1657 printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
1663 set_mode(char *modeopt)
1665 if (strcmp(modeopt, "s") == 0 || strcmp(modeopt, "smart") == 0)
1667 shutdown_mode = SMART_MODE;
1670 else if (strcmp(modeopt, "f") == 0 || strcmp(modeopt, "fast") == 0)
1672 shutdown_mode = FAST_MODE;
1675 else if (strcmp(modeopt, "i") == 0 || strcmp(modeopt, "immediate") == 0)
1677 shutdown_mode = IMMEDIATE_MODE;
1682 write_stderr(_("%s: unrecognized shutdown mode \"%s\"\n"), progname, modeopt);
1691 set_sig(char *signame)
1693 if (!strcmp(signame, "HUP"))
1695 else if (!strcmp(signame, "INT"))
1697 else if (!strcmp(signame, "QUIT"))
1699 else if (!strcmp(signame, "ABRT"))
1703 * probably should NOT provide SIGKILL
1705 * else if (!strcmp(signame,"KILL")) sig = SIGKILL;
1707 else if (!strcmp(signame, "TERM"))
1709 else if (!strcmp(signame, "USR1"))
1711 else if (!strcmp(signame, "USR2"))
1715 write_stderr(_("%s: unrecognized signal name \"%s\"\n"), progname, signame);
1722 #if defined(WIN32) || defined(__CYGWIN__)
1724 set_starttype(char *starttypeopt)
1726 if (strcmp(starttypeopt, "a") == 0 || strcmp(starttypeopt, "auto") == 0)
1727 pgctl_start_type = SERVICE_AUTO_START;
1728 else if (strcmp(starttypeopt, "d") == 0 || strcmp(starttypeopt, "demand") == 0)
1729 pgctl_start_type = SERVICE_DEMAND_START;
1732 write_stderr(_("%s: unrecognized start type \"%s\"\n"), progname, starttypeopt);
1741 main(int argc, char **argv)
1743 static struct option long_options[] = {
1744 {"help", no_argument, NULL, '?'},
1745 {"version", no_argument, NULL, 'V'},
1746 {"log", required_argument, NULL, 'l'},
1747 {"mode", required_argument, NULL, 'm'},
1748 {"pgdata", required_argument, NULL, 'D'},
1749 {"silent", no_argument, NULL, 's'},
1750 {"timeout", required_argument, NULL, 't'},
1751 {"core-files", no_argument, NULL, 'c'},
1757 pgpid_t killproc = 0;
1759 #if defined(WIN32) || defined(__CYGWIN__)
1760 setvbuf(stderr, NULL, _IONBF, 0);
1763 progname = get_progname(argv[0]);
1764 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_ctl"));
1767 * save argv[0] so do_start() can look for the postmaster if necessary. we
1768 * don't look for postmaster here because in many cases we won't need it.
1774 /* support --help and --version even if invoked as root */
1777 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 ||
1778 strcmp(argv[1], "-?") == 0)
1783 else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0)
1785 puts("pg_ctl (PostgreSQL) " PG_VERSION);
1791 * Disallow running as root, to forestall any possible security holes.
1796 write_stderr(_("%s: cannot be run as root\n"
1797 "Please log in (using, e.g., \"su\") as the "
1798 "(unprivileged) user that will\n"
1799 "own the server process.\n"),
1806 * 'Action' can be before or after args so loop over both. Some
1807 * getopt_long() implementations will reorder argv[] to place all flags
1808 * first (GNU?), but we don't rely on it. Our /port version doesn't do
1813 /* process command-line options */
1814 while (optind < argc)
1816 while ((c = getopt_long(argc, argv, "cD:l:m:N:o:p:P:sS:t:U:wW", long_options, &option_index)) != -1)
1823 char *env_var = pg_malloc(strlen(optarg) + 8);
1825 pgdata_D = xstrdup(optarg);
1826 canonicalize_path(pgdata_D);
1827 snprintf(env_var, strlen(optarg) + 8, "PGDATA=%s",
1832 * We could pass PGDATA just in an environment
1833 * variable but we do -D too for clearer postmaster
1836 pgdata_opt = pg_malloc(strlen(pgdata_D) + 7);
1837 snprintf(pgdata_opt, strlen(pgdata_D) + 7,
1843 log_file = xstrdup(optarg);
1849 register_servicename = xstrdup(optarg);
1852 post_opts = xstrdup(optarg);
1855 exec_path = xstrdup(optarg);
1858 register_password = xstrdup(optarg);
1864 #if defined(WIN32) || defined(__CYGWIN__)
1865 set_starttype(optarg);
1867 write_stderr(_("%s: -S option not supported on this platform\n"),
1873 wait_seconds = atoi(optarg);
1876 if (strchr(optarg, '\\'))
1877 register_username = xstrdup(optarg);
1879 /* Prepend .\ for local accounts */
1881 register_username = malloc(strlen(optarg) + 3);
1882 if (!register_username)
1884 write_stderr(_("%s: out of memory\n"), progname);
1887 strcpy(register_username, ".\\");
1888 strcat(register_username, optarg);
1900 allow_core_files = true;
1903 /* getopt_long already issued a suitable error message */
1909 /* Process an action */
1912 if (ctl_command != NO_COMMAND)
1914 write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]);
1919 if (strcmp(argv[optind], "init") == 0
1920 || strcmp(argv[optind], "initdb") == 0)
1921 ctl_command = INIT_COMMAND;
1922 else if (strcmp(argv[optind], "start") == 0)
1923 ctl_command = START_COMMAND;
1924 else if (strcmp(argv[optind], "stop") == 0)
1925 ctl_command = STOP_COMMAND;
1926 else if (strcmp(argv[optind], "restart") == 0)
1927 ctl_command = RESTART_COMMAND;
1928 else if (strcmp(argv[optind], "reload") == 0)
1929 ctl_command = RELOAD_COMMAND;
1930 else if (strcmp(argv[optind], "status") == 0)
1931 ctl_command = STATUS_COMMAND;
1932 else if (strcmp(argv[optind], "kill") == 0)
1934 if (argc - optind < 3)
1936 write_stderr(_("%s: missing arguments for kill mode\n"), progname);
1940 ctl_command = KILL_COMMAND;
1941 set_sig(argv[++optind]);
1942 killproc = atol(argv[++optind]);
1944 #if defined(WIN32) || defined(__CYGWIN__)
1945 else if (strcmp(argv[optind], "register") == 0)
1946 ctl_command = REGISTER_COMMAND;
1947 else if (strcmp(argv[optind], "unregister") == 0)
1948 ctl_command = UNREGISTER_COMMAND;
1949 else if (strcmp(argv[optind], "runservice") == 0)
1950 ctl_command = RUN_AS_SERVICE_COMMAND;
1954 write_stderr(_("%s: unrecognized operation mode \"%s\"\n"), progname, argv[optind]);
1962 if (ctl_command == NO_COMMAND)
1964 write_stderr(_("%s: no operation specified\n"), progname);
1969 /* Note we put any -D switch into the env var above */
1970 pg_data = getenv("PGDATA");
1973 pg_data = xstrdup(pg_data);
1974 canonicalize_path(pg_data);
1977 if (pg_data == NULL &&
1978 ctl_command != KILL_COMMAND && ctl_command != UNREGISTER_COMMAND)
1980 write_stderr(_("%s: no database directory specified and environment variable PGDATA unset\n"),
1988 switch (ctl_command)
1990 case RESTART_COMMAND:
2002 if (ctl_command == RELOAD_COMMAND)
2010 snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);
2011 snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
2012 snprintf(conf_file, MAXPGPATH, "%s/postgresql.conf", pg_data);
2013 snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data);
2014 snprintf(recovery_file, MAXPGPATH, "%s/recovery.conf", pg_data);
2017 switch (ctl_command)
2022 case STATUS_COMMAND:
2031 case RESTART_COMMAND:
2034 case RELOAD_COMMAND:
2040 #if defined(WIN32) || defined(__CYGWIN__)
2041 case REGISTER_COMMAND:
2042 pgwin32_doRegister();
2044 case UNREGISTER_COMMAND:
2045 pgwin32_doUnregister();
2047 case RUN_AS_SERVICE_COMMAND:
2048 pgwin32_doRunAsService();