PostgreSQL Source Code  git master
pg_ctl.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_ctl --- start/stops/restarts the PostgreSQL server
4  *
5  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
6  *
7  * src/bin/pg_ctl/pg_ctl.c
8  *
9  *-------------------------------------------------------------------------
10  */
11 
12 #include "postgres_fe.h"
13 
14 #include <fcntl.h>
15 #include <signal.h>
16 #include <time.h>
17 #include <sys/stat.h>
18 #include <sys/wait.h>
19 #include <unistd.h>
20 
21 #ifdef HAVE_SYS_RESOURCE_H
22 #include <sys/time.h>
23 #include <sys/resource.h>
24 #endif
25 
26 #include "catalog/pg_control.h"
28 #include "common/file_perm.h"
29 #include "common/logging.h"
30 #include "common/string.h"
31 #include "getopt_long.h"
32 #include "utils/pidfile.h"
33 
34 #ifdef WIN32 /* on Unix, we don't need libpq */
35 #include "pqexpbuffer.h"
36 #endif
37 
38 /* PID can be negative for standalone backend */
39 typedef long pgpid_t;
40 
41 
42 typedef enum
43 {
48 
49 typedef enum
50 {
55 
56 typedef enum
57 {
72 
73 #define DEFAULT_WAIT 60
74 
75 #define USEC_PER_SEC 1000000
76 
77 #define WAITS_PER_SEC 10 /* should divide USEC_PER_SEC evenly */
78 
79 static bool do_wait = true;
81 static bool wait_seconds_arg = false;
82 static bool silent_mode = false;
84 static int sig = SIGINT; /* default */
86 static char *pg_data = NULL;
87 static char *pg_config = NULL;
88 static char *pgdata_opt = NULL;
89 static char *post_opts = NULL;
90 static const char *progname;
91 static char *log_file = NULL;
92 static char *exec_path = NULL;
93 static char *event_source = NULL;
94 static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
95 static char *register_username = NULL;
96 static char *register_password = NULL;
97 static char *argv0 = NULL;
98 static bool allow_core_files = false;
99 static time_t start_time;
100 
102 static char version_file[MAXPGPATH];
103 static char pid_file[MAXPGPATH];
104 static char backup_file[MAXPGPATH];
105 static char promote_file[MAXPGPATH];
107 
108 static volatile pgpid_t postmasterPID = -1;
109 
110 #ifdef WIN32
111 static DWORD pgctl_start_type = SERVICE_AUTO_START;
112 static SERVICE_STATUS status;
113 static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
114 static HANDLE shutdownHandles[2];
115 
116 #define shutdownEvent shutdownHandles[0]
117 #define postmasterProcess shutdownHandles[1]
118 #endif
119 
120 
121 static void write_stderr(const char *fmt,...) pg_attribute_printf(1, 2);
122 static void do_advice(void);
123 static void do_help(void);
124 static void set_mode(char *modeopt);
125 static void set_sig(char *signame);
126 static void do_init(void);
127 static void do_start(void);
128 static void do_stop(void);
129 static void do_restart(void);
130 static void do_reload(void);
131 static void do_status(void);
132 static void do_promote(void);
133 static void do_logrotate(void);
134 static void do_kill(pgpid_t pid);
135 static void print_msg(const char *msg);
136 static void adjust_data_dir(void);
137 
138 #ifdef WIN32
139 #include <versionhelpers.h>
140 static bool pgwin32_IsInstalled(SC_HANDLE);
141 static char *pgwin32_CommandLine(bool);
142 static void pgwin32_doRegister(void);
143 static void pgwin32_doUnregister(void);
144 static void pgwin32_SetServiceStatus(DWORD);
145 static void WINAPI pgwin32_ServiceHandler(DWORD);
146 static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
147 static void pgwin32_doRunAsService(void);
148 static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service);
149 static PTOKEN_PRIVILEGES GetPrivilegesToDelete(HANDLE hToken);
150 #endif
151 
152 static pgpid_t get_pgpid(bool is_status_request);
153 static char **readfile(const char *path, int *numlines);
154 static void free_readfile(char **optlines);
155 static pgpid_t start_postmaster(void);
156 static void read_post_opts(void);
157 
158 static WaitPMResult wait_for_postmaster(pgpid_t pm_pid, bool do_checkpoint);
159 static bool postmaster_is_alive(pid_t pid);
160 
161 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
162 static void unlimit_core_size(void);
163 #endif
164 
165 static DBState get_control_dbstate(void);
166 
167 
168 #ifdef WIN32
169 static void
170 write_eventlog(int level, const char *line)
171 {
172  static HANDLE evtHandle = INVALID_HANDLE_VALUE;
173 
174  if (silent_mode && level == EVENTLOG_INFORMATION_TYPE)
175  return;
176 
177  if (evtHandle == INVALID_HANDLE_VALUE)
178  {
179  evtHandle = RegisterEventSource(NULL,
181  if (evtHandle == NULL)
182  {
183  evtHandle = INVALID_HANDLE_VALUE;
184  return;
185  }
186  }
187 
188  ReportEvent(evtHandle,
189  level,
190  0,
191  0, /* All events are Id 0 */
192  NULL,
193  1,
194  0,
195  &line,
196  NULL);
197 }
198 #endif
199 
200 /*
201  * Write errors to stderr (or by equal means when stderr is
202  * not available).
203  */
204 static void
205 write_stderr(const char *fmt,...)
206 {
207  va_list ap;
208 
209  va_start(ap, fmt);
210 #ifndef WIN32
211  /* On Unix, we just fprintf to stderr */
212  vfprintf(stderr, fmt, ap);
213 #else
214 
215  /*
216  * On Win32, we print to stderr if running on a console, or write to
217  * eventlog if running as a service
218  */
219  if (pgwin32_is_service()) /* Running as a service */
220  {
221  char errbuf[2048]; /* Arbitrary size? */
222 
223  vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
224 
225  write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
226  }
227  else
228  /* Not running as service, write to stderr */
229  vfprintf(stderr, fmt, ap);
230 #endif
231  va_end(ap);
232 }
233 
234 /*
235  * Given an already-localized string, print it to stdout unless the
236  * user has specified that no messages should be printed.
237  */
238 static void
239 print_msg(const char *msg)
240 {
241  if (!silent_mode)
242  {
243  fputs(msg, stdout);
244  fflush(stdout);
245  }
246 }
247 
248 static pgpid_t
249 get_pgpid(bool is_status_request)
250 {
251  FILE *pidf;
252  long pid;
253  struct stat statbuf;
254 
255  if (stat(pg_data, &statbuf) != 0)
256  {
257  if (errno == ENOENT)
258  write_stderr(_("%s: directory \"%s\" does not exist\n"), progname,
259  pg_data);
260  else
261  write_stderr(_("%s: could not access directory \"%s\": %s\n"), progname,
262  pg_data, strerror(errno));
263 
264  /*
265  * The Linux Standard Base Core Specification 3.1 says this should
266  * return '4, program or service status is unknown'
267  * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
268  */
269  exit(is_status_request ? 4 : 1);
270  }
271 
272  if (stat(version_file, &statbuf) != 0 && errno == ENOENT)
273  {
274  write_stderr(_("%s: directory \"%s\" is not a database cluster directory\n"),
275  progname, pg_data);
276  exit(is_status_request ? 4 : 1);
277  }
278 
279  pidf = fopen(pid_file, "r");
280  if (pidf == NULL)
281  {
282  /* No pid file, not an error on startup */
283  if (errno == ENOENT)
284  return 0;
285  else
286  {
287  write_stderr(_("%s: could not open PID file \"%s\": %s\n"),
288  progname, pid_file, strerror(errno));
289  exit(1);
290  }
291  }
292  if (fscanf(pidf, "%ld", &pid) != 1)
293  {
294  /* Is the file empty? */
295  if (ftell(pidf) == 0 && feof(pidf))
296  write_stderr(_("%s: the PID file \"%s\" is empty\n"),
297  progname, pid_file);
298  else
299  write_stderr(_("%s: invalid data in PID file \"%s\"\n"),
300  progname, pid_file);
301  exit(1);
302  }
303  fclose(pidf);
304  return (pgpid_t) pid;
305 }
306 
307 
308 /*
309  * get the lines from a text file - return NULL if file can't be opened
310  *
311  * Trailing newlines are deleted from the lines (this is a change from pre-v10)
312  *
313  * *numlines is set to the number of line pointers returned; there is
314  * also an additional NULL pointer after the last real line.
315  */
316 static char **
317 readfile(const char *path, int *numlines)
318 {
319  int fd;
320  int nlines;
321  char **result;
322  char *buffer;
323  char *linebegin;
324  int i;
325  int n;
326  int len;
327  struct stat statbuf;
328 
329  *numlines = 0; /* in case of failure or empty file */
330 
331  /*
332  * Slurp the file into memory.
333  *
334  * The file can change concurrently, so we read the whole file into memory
335  * with a single read() call. That's not guaranteed to get an atomic
336  * snapshot, but in practice, for a small file, it's close enough for the
337  * current use.
338  */
339  fd = open(path, O_RDONLY | PG_BINARY, 0);
340  if (fd < 0)
341  return NULL;
342  if (fstat(fd, &statbuf) < 0)
343  {
344  close(fd);
345  return NULL;
346  }
347  if (statbuf.st_size == 0)
348  {
349  /* empty file */
350  close(fd);
351  result = (char **) pg_malloc(sizeof(char *));
352  *result = NULL;
353  return result;
354  }
355  buffer = pg_malloc(statbuf.st_size + 1);
356 
357  len = read(fd, buffer, statbuf.st_size + 1);
358  close(fd);
359  if (len != statbuf.st_size)
360  {
361  /* oops, the file size changed between fstat and read */
362  free(buffer);
363  return NULL;
364  }
365 
366  /*
367  * Count newlines. We expect there to be a newline after each full line,
368  * including one at the end of file. If there isn't a newline at the end,
369  * any characters after the last newline will be ignored.
370  */
371  nlines = 0;
372  for (i = 0; i < len; i++)
373  {
374  if (buffer[i] == '\n')
375  nlines++;
376  }
377 
378  /* set up the result buffer */
379  result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
380  *numlines = nlines;
381 
382  /* now split the buffer into lines */
383  linebegin = buffer;
384  n = 0;
385  for (i = 0; i < len; i++)
386  {
387  if (buffer[i] == '\n')
388  {
389  int slen = &buffer[i] - linebegin;
390  char *linebuf = pg_malloc(slen + 1);
391 
392  memcpy(linebuf, linebegin, slen);
393  /* we already dropped the \n, but get rid of any \r too */
394  if (slen > 0 && linebuf[slen - 1] == '\r')
395  slen--;
396  linebuf[slen] = '\0';
397  result[n++] = linebuf;
398  linebegin = &buffer[i + 1];
399  }
400  }
401  result[n] = NULL;
402 
403  free(buffer);
404 
405  return result;
406 }
407 
408 
409 /*
410  * Free memory allocated for optlines through readfile()
411  */
412 static void
413 free_readfile(char **optlines)
414 {
415  char *curr_line = NULL;
416  int i = 0;
417 
418  if (!optlines)
419  return;
420 
421  while ((curr_line = optlines[i++]))
422  free(curr_line);
423 
424  free(optlines);
425 }
426 
427 /*
428  * start/test/stop routines
429  */
430 
431 /*
432  * Start the postmaster and return its PID.
433  *
434  * Currently, on Windows what we return is the PID of the shell process
435  * that launched the postmaster (and, we trust, is waiting for it to exit).
436  * So the PID is usable for "is the postmaster still running" checks,
437  * but cannot be compared directly to postmaster.pid.
438  *
439  * On Windows, we also save aside a handle to the shell process in
440  * "postmasterProcess", which the caller should close when done with it.
441  */
442 static pgpid_t
444 {
445  char *cmd;
446 
447 #ifndef WIN32
448  pgpid_t pm_pid;
449 
450  /* Flush stdio channels just before fork, to avoid double-output problems */
451  fflush(stdout);
452  fflush(stderr);
453 
454 #ifdef EXEC_BACKEND
455  pg_disable_aslr();
456 #endif
457 
458  pm_pid = fork();
459  if (pm_pid < 0)
460  {
461  /* fork failed */
462  write_stderr(_("%s: could not start server: %s\n"),
463  progname, strerror(errno));
464  exit(1);
465  }
466  if (pm_pid > 0)
467  {
468  /* fork succeeded, in parent */
469  return pm_pid;
470  }
471 
472  /* fork succeeded, in child */
473 
474  /*
475  * If possible, detach the postmaster process from the launching process
476  * group and make it a group leader, so that it doesn't get signaled along
477  * with the current group that launched it.
478  */
479 #ifdef HAVE_SETSID
480  if (setsid() < 0)
481  {
482  write_stderr(_("%s: could not start server due to setsid() failure: %s\n"),
483  progname, strerror(errno));
484  exit(1);
485  }
486 #endif
487 
488  /*
489  * Since there might be quotes to handle here, it is easier simply to pass
490  * everything to a shell to process them. Use exec so that the postmaster
491  * has the same PID as the current child process.
492  */
493  if (log_file != NULL)
494  cmd = psprintf("exec \"%s\" %s%s < \"%s\" >> \"%s\" 2>&1",
496  DEVNULL, log_file);
497  else
498  cmd = psprintf("exec \"%s\" %s%s < \"%s\" 2>&1",
500 
501  (void) execl("/bin/sh", "/bin/sh", "-c", cmd, (char *) NULL);
502 
503  /* exec failed */
504  write_stderr(_("%s: could not start server: %s\n"),
505  progname, strerror(errno));
506  exit(1);
507 
508  return 0; /* keep dumb compilers quiet */
509 
510 #else /* WIN32 */
511 
512  /*
513  * As with the Unix case, it's easiest to use the shell (CMD.EXE) to
514  * handle redirection etc. Unfortunately CMD.EXE lacks any equivalent of
515  * "exec", so we don't get to find out the postmaster's PID immediately.
516  */
517  PROCESS_INFORMATION pi;
518  const char *comspec;
519 
520  /* Find CMD.EXE location using COMSPEC, if it's set */
521  comspec = getenv("COMSPEC");
522  if (comspec == NULL)
523  comspec = "CMD";
524 
525  if (log_file != NULL)
526  {
527  /*
528  * First, open the log file if it exists. The idea is that if the
529  * file is still locked by a previous postmaster run, we'll wait until
530  * it comes free, instead of failing with ERROR_SHARING_VIOLATION.
531  * (It'd be better to open the file in a sharing-friendly mode, but we
532  * can't use CMD.EXE to do that, so work around it. Note that the
533  * previous postmaster will still have the file open for a short time
534  * after removing postmaster.pid.)
535  *
536  * If the log file doesn't exist, we *must not* create it here. If we
537  * were launched with higher privileges than the restricted process
538  * will have, the log file might end up with permissions settings that
539  * prevent the postmaster from writing on it.
540  */
541  int fd = open(log_file, O_RDWR, 0);
542 
543  if (fd == -1)
544  {
545  /*
546  * ENOENT is expectable since we didn't use O_CREAT. Otherwise
547  * complain. We could just fall through and let CMD.EXE report
548  * the problem, but its error reporting is pretty miserable.
549  */
550  if (errno != ENOENT)
551  {
552  write_stderr(_("%s: could not open log file \"%s\": %s\n"),
553  progname, log_file, strerror(errno));
554  exit(1);
555  }
556  }
557  else
558  close(fd);
559 
560  cmd = psprintf("\"%s\" /C \"\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1\"",
562  }
563  else
564  cmd = psprintf("\"%s\" /C \"\"%s\" %s%s < \"%s\" 2>&1\"",
565  comspec, exec_path, pgdata_opt, post_opts, DEVNULL);
566 
567  if (!CreateRestrictedProcess(cmd, &pi, false))
568  {
569  write_stderr(_("%s: could not start server: error code %lu\n"),
570  progname, (unsigned long) GetLastError());
571  exit(1);
572  }
573  /* Don't close command process handle here; caller must do so */
574  postmasterProcess = pi.hProcess;
575  CloseHandle(pi.hThread);
576  return pi.dwProcessId; /* Shell's PID, not postmaster's! */
577 #endif /* WIN32 */
578 }
579 
580 
581 
582 /*
583  * Wait for the postmaster to become ready.
584  *
585  * On Unix, pm_pid is the PID of the just-launched postmaster. On Windows,
586  * it may be the PID of an ancestor shell process, so we can't check the
587  * contents of postmaster.pid quite as carefully.
588  *
589  * On Windows, the static variable postmasterProcess is an implicit argument
590  * to this routine; it contains a handle to the postmaster process or an
591  * ancestor shell process thereof.
592  *
593  * Note that the checkpoint parameter enables a Windows service control
594  * manager checkpoint, it's got nothing to do with database checkpoints!!
595  */
596 static WaitPMResult
597 wait_for_postmaster(pgpid_t pm_pid, bool do_checkpoint)
598 {
599  int i;
600 
601  for (i = 0; i < wait_seconds * WAITS_PER_SEC; i++)
602  {
603  char **optlines;
604  int numlines;
605 
606  /*
607  * Try to read the postmaster.pid file. If it's not valid, or if the
608  * status line isn't there yet, just keep waiting.
609  */
610  if ((optlines = readfile(pid_file, &numlines)) != NULL &&
611  numlines >= LOCK_FILE_LINE_PM_STATUS)
612  {
613  /* File is complete enough for us, parse it */
614  pgpid_t pmpid;
615  time_t pmstart;
616 
617  /*
618  * Make sanity checks. If it's for the wrong PID, or the recorded
619  * start time is before pg_ctl started, then either we are looking
620  * at the wrong data directory, or this is a pre-existing pidfile
621  * that hasn't (yet?) been overwritten by our child postmaster.
622  * Allow 2 seconds slop for possible cross-process clock skew.
623  */
624  pmpid = atol(optlines[LOCK_FILE_LINE_PID - 1]);
625  pmstart = atol(optlines[LOCK_FILE_LINE_START_TIME - 1]);
626  if (pmstart >= start_time - 2 &&
627 #ifndef WIN32
628  pmpid == pm_pid
629 #else
630  /* Windows can only reject standalone-backend PIDs */
631  pmpid > 0
632 #endif
633  )
634  {
635  /*
636  * OK, seems to be a valid pidfile from our child. Check the
637  * status line (this assumes a v10 or later server).
638  */
639  char *pmstatus = optlines[LOCK_FILE_LINE_PM_STATUS - 1];
640 
641  if (strcmp(pmstatus, PM_STATUS_READY) == 0 ||
642  strcmp(pmstatus, PM_STATUS_STANDBY) == 0)
643  {
644  /* postmaster is done starting up */
645  free_readfile(optlines);
646  return POSTMASTER_READY;
647  }
648  }
649  }
650 
651  /*
652  * Free the results of readfile.
653  *
654  * This is safe to call even if optlines is NULL.
655  */
656  free_readfile(optlines);
657 
658  /*
659  * Check whether the child postmaster process is still alive. This
660  * lets us exit early if the postmaster fails during startup.
661  *
662  * On Windows, we may be checking the postmaster's parent shell, but
663  * that's fine for this purpose.
664  */
665 #ifndef WIN32
666  {
667  int exitstatus;
668 
669  if (waitpid((pid_t) pm_pid, &exitstatus, WNOHANG) == (pid_t) pm_pid)
670  return POSTMASTER_FAILED;
671  }
672 #else
673  if (WaitForSingleObject(postmasterProcess, 0) == WAIT_OBJECT_0)
674  return POSTMASTER_FAILED;
675 #endif
676 
677  /* Startup still in process; wait, printing a dot once per second */
678  if (i % WAITS_PER_SEC == 0)
679  {
680 #ifdef WIN32
681  if (do_checkpoint)
682  {
683  /*
684  * Increment the wait hint by 6 secs (connection timeout +
685  * sleep). We must do this to indicate to the SCM that our
686  * startup time is changing, otherwise it'll usually send a
687  * stop signal after 20 seconds, despite incrementing the
688  * checkpoint counter.
689  */
690  status.dwWaitHint += 6000;
691  status.dwCheckPoint++;
692  SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
693  }
694  else
695 #endif
696  print_msg(".");
697  }
698 
700  }
701 
702  /* out of patience; report that postmaster is still starting up */
704 }
705 
706 
707 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
708 static void
709 unlimit_core_size(void)
710 {
711  struct rlimit lim;
712 
713  getrlimit(RLIMIT_CORE, &lim);
714  if (lim.rlim_max == 0)
715  {
716  write_stderr(_("%s: cannot set core file size limit; disallowed by hard limit\n"),
717  progname);
718  return;
719  }
720  else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
721  {
722  lim.rlim_cur = lim.rlim_max;
723  setrlimit(RLIMIT_CORE, &lim);
724  }
725 }
726 #endif
727 
728 static void
730 {
731  if (post_opts == NULL)
732  {
733  post_opts = ""; /* default */
735  {
736  char **optlines;
737  int numlines;
738 
739  optlines = readfile(postopts_file, &numlines);
740  if (optlines == NULL)
741  {
742  write_stderr(_("%s: could not read file \"%s\"\n"), progname, postopts_file);
743  exit(1);
744  }
745  else if (numlines != 1)
746  {
747  write_stderr(_("%s: option file \"%s\" must have exactly one line\n"),
749  exit(1);
750  }
751  else
752  {
753  char *optline;
754  char *arg1;
755 
756  optline = optlines[0];
757 
758  /*
759  * Are we at the first option, as defined by space and
760  * double-quote?
761  */
762  if ((arg1 = strstr(optline, " \"")) != NULL)
763  {
764  *arg1 = '\0'; /* terminate so we get only program name */
765  post_opts = pg_strdup(arg1 + 1); /* point past whitespace */
766  }
767  if (exec_path == NULL)
768  exec_path = pg_strdup(optline);
769  }
770 
771  /* Free the results of readfile. */
772  free_readfile(optlines);
773  }
774  }
775 }
776 
777 /*
778  * SIGINT signal handler used while waiting for postmaster to start up.
779  * Forwards the SIGINT to the postmaster process, asking it to shut down,
780  * before terminating pg_ctl itself. This way, if the user hits CTRL-C while
781  * waiting for the server to start up, the server launch is aborted.
782  */
783 static void
785 {
786  if (postmasterPID != -1)
787  {
788  if (kill(postmasterPID, SIGINT) != 0)
789  write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"),
791  }
792 
793  /*
794  * Clear the signal handler, and send the signal again, to terminate the
795  * process as normal.
796  */
797  pqsignal(SIGINT, SIG_DFL);
798  raise(SIGINT);
799 }
800 
801 static char *
802 find_other_exec_or_die(const char *argv0, const char *target, const char *versionstr)
803 {
804  int ret;
805  char *found_path;
806 
807  found_path = pg_malloc(MAXPGPATH);
808 
809  if ((ret = find_other_exec(argv0, target, versionstr, found_path)) < 0)
810  {
811  char full_path[MAXPGPATH];
812 
813  if (find_my_exec(argv0, full_path) < 0)
814  strlcpy(full_path, progname, sizeof(full_path));
815 
816  if (ret == -1)
817  write_stderr(_("The program \"%s\" is needed by %s but was not found in the\n"
818  "same directory as \"%s\".\n"
819  "Check your installation.\n"),
820  target, progname, full_path);
821  else
822  write_stderr(_("The program \"%s\" was found by \"%s\"\n"
823  "but was not the same version as %s.\n"
824  "Check your installation.\n"),
825  target, full_path, progname);
826  exit(1);
827  }
828 
829  return found_path;
830 }
831 
832 static void
833 do_init(void)
834 {
835  char *cmd;
836 
837  if (exec_path == NULL)
838  exec_path = find_other_exec_or_die(argv0, "initdb", "initdb (PostgreSQL) " PG_VERSION "\n");
839 
840  if (pgdata_opt == NULL)
841  pgdata_opt = "";
842 
843  if (post_opts == NULL)
844  post_opts = "";
845 
846  if (!silent_mode)
847  cmd = psprintf("\"%s\" %s%s",
849  else
850  cmd = psprintf("\"%s\" %s%s > \"%s\"",
852 
853  if (system(cmd) != 0)
854  {
855  write_stderr(_("%s: database system initialization failed\n"), progname);
856  exit(1);
857  }
858 }
859 
860 static void
861 do_start(void)
862 {
863  pgpid_t old_pid = 0;
864  pgpid_t pm_pid;
865 
867  {
868  old_pid = get_pgpid(false);
869  if (old_pid != 0)
870  write_stderr(_("%s: another server might be running; "
871  "trying to start server anyway\n"),
872  progname);
873  }
874 
875  read_post_opts();
876 
877  /* No -D or -D already added during server start */
878  if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
879  pgdata_opt = "";
880 
881  if (exec_path == NULL)
883 
884 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
885  if (allow_core_files)
886  unlimit_core_size();
887 #endif
888 
889  /*
890  * If possible, tell the postmaster our parent shell's PID (see the
891  * comments in CreateLockFile() for motivation). Windows hasn't got
892  * getppid() unfortunately.
893  */
894 #ifndef WIN32
895  {
896  char env_var[32];
897 
898  snprintf(env_var, sizeof(env_var), "%d", (int) getppid());
899  setenv("PG_GRANDPARENT_PID", env_var, 1);
900  }
901 #endif
902 
903  pm_pid = start_postmaster();
904 
905  if (do_wait)
906  {
907  /*
908  * If the user interrupts the startup (e.g. with CTRL-C), we'd like to
909  * abort the server launch. Install a signal handler that will
910  * forward SIGINT to the postmaster process, while we wait.
911  *
912  * (We don't bother to reset the signal handler after the launch, as
913  * we're about to exit, anyway.)
914  */
915  postmasterPID = pm_pid;
917 
918  print_msg(_("waiting for server to start..."));
919 
920  switch (wait_for_postmaster(pm_pid, false))
921  {
922  case POSTMASTER_READY:
923  print_msg(_(" done\n"));
924  print_msg(_("server started\n"));
925  break;
927  print_msg(_(" stopped waiting\n"));
928  write_stderr(_("%s: server did not start in time\n"),
929  progname);
930  exit(1);
931  break;
932  case POSTMASTER_FAILED:
933  print_msg(_(" stopped waiting\n"));
934  write_stderr(_("%s: could not start server\n"
935  "Examine the log output.\n"),
936  progname);
937  exit(1);
938  break;
939  }
940  }
941  else
942  print_msg(_("server starting\n"));
943 
944 #ifdef WIN32
945  /* Now we don't need the handle to the shell process anymore */
946  CloseHandle(postmasterProcess);
947  postmasterProcess = INVALID_HANDLE_VALUE;
948 #endif
949 }
950 
951 
952 static void
953 do_stop(void)
954 {
955  int cnt;
956  pgpid_t pid;
957  struct stat statbuf;
958 
959  pid = get_pgpid(false);
960 
961  if (pid == 0) /* no pid file */
962  {
963  write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
964  write_stderr(_("Is server running?\n"));
965  exit(1);
966  }
967  else if (pid < 0) /* standalone backend, not postmaster */
968  {
969  pid = -pid;
970  write_stderr(_("%s: cannot stop server; "
971  "single-user server is running (PID: %ld)\n"),
972  progname, pid);
973  exit(1);
974  }
975 
976  if (kill((pid_t) pid, sig) != 0)
977  {
978  write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
979  strerror(errno));
980  exit(1);
981  }
982 
983  if (!do_wait)
984  {
985  print_msg(_("server shutting down\n"));
986  return;
987  }
988  else
989  {
990  /*
991  * If backup_label exists, an online backup is running. Warn the user
992  * that smart shutdown will wait for it to finish. However, if the
993  * server is in archive recovery, we're recovering from an online
994  * backup instead of performing one.
995  */
996  if (shutdown_mode == SMART_MODE &&
997  stat(backup_file, &statbuf) == 0 &&
999  {
1000  print_msg(_("WARNING: online backup mode is active\n"
1001  "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
1002  }
1003 
1004  print_msg(_("waiting for server to shut down..."));
1005 
1006  for (cnt = 0; cnt < wait_seconds * WAITS_PER_SEC; cnt++)
1007  {
1008  if ((pid = get_pgpid(false)) != 0)
1009  {
1010  if (cnt % WAITS_PER_SEC == 0)
1011  print_msg(".");
1013  }
1014  else
1015  break;
1016  }
1017 
1018  if (pid != 0) /* pid file still exists */
1019  {
1020  print_msg(_(" failed\n"));
1021 
1022  write_stderr(_("%s: server does not shut down\n"), progname);
1023  if (shutdown_mode == SMART_MODE)
1024  write_stderr(_("HINT: The \"-m fast\" option immediately disconnects sessions rather than\n"
1025  "waiting for session-initiated disconnection.\n"));
1026  exit(1);
1027  }
1028  print_msg(_(" done\n"));
1029 
1030  print_msg(_("server stopped\n"));
1031  }
1032 }
1033 
1034 
1035 /*
1036  * restart/reload routines
1037  */
1038 
1039 static void
1041 {
1042  int cnt;
1043  pgpid_t pid;
1044  struct stat statbuf;
1045 
1046  pid = get_pgpid(false);
1047 
1048  if (pid == 0) /* no pid file */
1049  {
1050  write_stderr(_("%s: PID file \"%s\" does not exist\n"),
1051  progname, pid_file);
1052  write_stderr(_("Is server running?\n"));
1053  write_stderr(_("trying to start server anyway\n"));
1054  do_start();
1055  return;
1056  }
1057  else if (pid < 0) /* standalone backend, not postmaster */
1058  {
1059  pid = -pid;
1060  if (postmaster_is_alive((pid_t) pid))
1061  {
1062  write_stderr(_("%s: cannot restart server; "
1063  "single-user server is running (PID: %ld)\n"),
1064  progname, pid);
1065  write_stderr(_("Please terminate the single-user server and try again.\n"));
1066  exit(1);
1067  }
1068  }
1069 
1070  if (postmaster_is_alive((pid_t) pid))
1071  {
1072  if (kill((pid_t) pid, sig) != 0)
1073  {
1074  write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
1075  strerror(errno));
1076  exit(1);
1077  }
1078 
1079  /*
1080  * If backup_label exists, an online backup is running. Warn the user
1081  * that smart shutdown will wait for it to finish. However, if the
1082  * server is in archive recovery, we're recovering from an online
1083  * backup instead of performing one.
1084  */
1085  if (shutdown_mode == SMART_MODE &&
1086  stat(backup_file, &statbuf) == 0 &&
1088  {
1089  print_msg(_("WARNING: online backup mode is active\n"
1090  "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
1091  }
1092 
1093  print_msg(_("waiting for server to shut down..."));
1094 
1095  /* always wait for restart */
1096 
1097  for (cnt = 0; cnt < wait_seconds * WAITS_PER_SEC; cnt++)
1098  {
1099  if ((pid = get_pgpid(false)) != 0)
1100  {
1101  if (cnt % WAITS_PER_SEC == 0)
1102  print_msg(".");
1104  }
1105  else
1106  break;
1107  }
1108 
1109  if (pid != 0) /* pid file still exists */
1110  {
1111  print_msg(_(" failed\n"));
1112 
1113  write_stderr(_("%s: server does not shut down\n"), progname);
1114  if (shutdown_mode == SMART_MODE)
1115  write_stderr(_("HINT: The \"-m fast\" option immediately disconnects sessions rather than\n"
1116  "waiting for session-initiated disconnection.\n"));
1117  exit(1);
1118  }
1119 
1120  print_msg(_(" done\n"));
1121  print_msg(_("server stopped\n"));
1122  }
1123  else
1124  {
1125  write_stderr(_("%s: old server process (PID: %ld) seems to be gone\n"),
1126  progname, pid);
1127  write_stderr(_("starting server anyway\n"));
1128  }
1129 
1130  do_start();
1131 }
1132 
1133 static void
1135 {
1136  pgpid_t pid;
1137 
1138  pid = get_pgpid(false);
1139  if (pid == 0) /* no pid file */
1140  {
1141  write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
1142  write_stderr(_("Is server running?\n"));
1143  exit(1);
1144  }
1145  else if (pid < 0) /* standalone backend, not postmaster */
1146  {
1147  pid = -pid;
1148  write_stderr(_("%s: cannot reload server; "
1149  "single-user server is running (PID: %ld)\n"),
1150  progname, pid);
1151  write_stderr(_("Please terminate the single-user server and try again.\n"));
1152  exit(1);
1153  }
1154 
1155  if (kill((pid_t) pid, sig) != 0)
1156  {
1157  write_stderr(_("%s: could not send reload signal (PID: %ld): %s\n"),
1158  progname, pid, strerror(errno));
1159  exit(1);
1160  }
1161 
1162  print_msg(_("server signaled\n"));
1163 }
1164 
1165 
1166 /*
1167  * promote
1168  */
1169 
1170 static void
1172 {
1173  FILE *prmfile;
1174  pgpid_t pid;
1175 
1176  pid = get_pgpid(false);
1177 
1178  if (pid == 0) /* no pid file */
1179  {
1180  write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
1181  write_stderr(_("Is server running?\n"));
1182  exit(1);
1183  }
1184  else if (pid < 0) /* standalone backend, not postmaster */
1185  {
1186  pid = -pid;
1187  write_stderr(_("%s: cannot promote server; "
1188  "single-user server is running (PID: %ld)\n"),
1189  progname, pid);
1190  exit(1);
1191  }
1192 
1194  {
1195  write_stderr(_("%s: cannot promote server; "
1196  "server is not in standby mode\n"),
1197  progname);
1198  exit(1);
1199  }
1200 
1201  snprintf(promote_file, MAXPGPATH, "%s/promote", pg_data);
1202 
1203  if ((prmfile = fopen(promote_file, "w")) == NULL)
1204  {
1205  write_stderr(_("%s: could not create promote signal file \"%s\": %s\n"),
1206  progname, promote_file, strerror(errno));
1207  exit(1);
1208  }
1209  if (fclose(prmfile))
1210  {
1211  write_stderr(_("%s: could not write promote signal file \"%s\": %s\n"),
1212  progname, promote_file, strerror(errno));
1213  exit(1);
1214  }
1215 
1216  sig = SIGUSR1;
1217  if (kill((pid_t) pid, sig) != 0)
1218  {
1219  write_stderr(_("%s: could not send promote signal (PID: %ld): %s\n"),
1220  progname, pid, strerror(errno));
1221  if (unlink(promote_file) != 0)
1222  write_stderr(_("%s: could not remove promote signal file \"%s\": %s\n"),
1223  progname, promote_file, strerror(errno));
1224  exit(1);
1225  }
1226 
1227  if (do_wait)
1228  {
1230  int cnt;
1231 
1232  print_msg(_("waiting for server to promote..."));
1233  for (cnt = 0; cnt < wait_seconds * WAITS_PER_SEC; cnt++)
1234  {
1236  if (state == DB_IN_PRODUCTION)
1237  break;
1238 
1239  if (cnt % WAITS_PER_SEC == 0)
1240  print_msg(".");
1242  }
1243  if (state == DB_IN_PRODUCTION)
1244  {
1245  print_msg(_(" done\n"));
1246  print_msg(_("server promoted\n"));
1247  }
1248  else
1249  {
1250  print_msg(_(" stopped waiting\n"));
1251  write_stderr(_("%s: server did not promote in time\n"),
1252  progname);
1253  exit(1);
1254  }
1255  }
1256  else
1257  print_msg(_("server promoting\n"));
1258 }
1259 
1260 /*
1261  * log rotate
1262  */
1263 
1264 static void
1266 {
1267  FILE *logrotatefile;
1268  pgpid_t pid;
1269 
1270  pid = get_pgpid(false);
1271 
1272  if (pid == 0) /* no pid file */
1273  {
1274  write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
1275  write_stderr(_("Is server running?\n"));
1276  exit(1);
1277  }
1278  else if (pid < 0) /* standalone backend, not postmaster */
1279  {
1280  pid = -pid;
1281  write_stderr(_("%s: cannot rotate log file; "
1282  "single-user server is running (PID: %ld)\n"),
1283  progname, pid);
1284  exit(1);
1285  }
1286 
1287  snprintf(logrotate_file, MAXPGPATH, "%s/logrotate", pg_data);
1288 
1289  if ((logrotatefile = fopen(logrotate_file, "w")) == NULL)
1290  {
1291  write_stderr(_("%s: could not create log rotation signal file \"%s\": %s\n"),
1292  progname, logrotate_file, strerror(errno));
1293  exit(1);
1294  }
1295  if (fclose(logrotatefile))
1296  {
1297  write_stderr(_("%s: could not write log rotation signal file \"%s\": %s\n"),
1298  progname, logrotate_file, strerror(errno));
1299  exit(1);
1300  }
1301 
1302  sig = SIGUSR1;
1303  if (kill((pid_t) pid, sig) != 0)
1304  {
1305  write_stderr(_("%s: could not send log rotation signal (PID: %ld): %s\n"),
1306  progname, pid, strerror(errno));
1307  if (unlink(logrotate_file) != 0)
1308  write_stderr(_("%s: could not remove log rotation signal file \"%s\": %s\n"),
1309  progname, logrotate_file, strerror(errno));
1310  exit(1);
1311  }
1312 
1313  print_msg(_("server signaled to rotate log file\n"));
1314 }
1315 
1316 
1317 /*
1318  * utility routines
1319  */
1320 
1321 static bool
1323 {
1324  /*
1325  * Test to see if the process is still there. Note that we do not
1326  * consider an EPERM failure to mean that the process is still there;
1327  * EPERM must mean that the given PID belongs to some other userid, and
1328  * considering the permissions on $PGDATA, that means it's not the
1329  * postmaster we are after.
1330  *
1331  * Don't believe that our own PID or parent shell's PID is the postmaster,
1332  * either. (Windows hasn't got getppid(), though.)
1333  */
1334  if (pid == getpid())
1335  return false;
1336 #ifndef WIN32
1337  if (pid == getppid())
1338  return false;
1339 #endif
1340  if (kill(pid, 0) == 0)
1341  return true;
1342  return false;
1343 }
1344 
1345 static void
1347 {
1348  pgpid_t pid;
1349 
1350  pid = get_pgpid(true);
1351  /* Is there a pid file? */
1352  if (pid != 0)
1353  {
1354  /* standalone backend? */
1355  if (pid < 0)
1356  {
1357  pid = -pid;
1358  if (postmaster_is_alive((pid_t) pid))
1359  {
1360  printf(_("%s: single-user server is running (PID: %ld)\n"),
1361  progname, pid);
1362  return;
1363  }
1364  }
1365  else
1366  /* must be a postmaster */
1367  {
1368  if (postmaster_is_alive((pid_t) pid))
1369  {
1370  char **optlines;
1371  char **curr_line;
1372  int numlines;
1373 
1374  printf(_("%s: server is running (PID: %ld)\n"),
1375  progname, pid);
1376 
1377  optlines = readfile(postopts_file, &numlines);
1378  if (optlines != NULL)
1379  {
1380  for (curr_line = optlines; *curr_line != NULL; curr_line++)
1381  puts(*curr_line);
1382 
1383  /* Free the results of readfile */
1384  free_readfile(optlines);
1385  }
1386  return;
1387  }
1388  }
1389  }
1390  printf(_("%s: no server running\n"), progname);
1391 
1392  /*
1393  * The Linux Standard Base Core Specification 3.1 says this should return
1394  * '3, program is not running'
1395  * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
1396  */
1397  exit(3);
1398 }
1399 
1400 
1401 
1402 static void
1404 {
1405  if (kill((pid_t) pid, sig) != 0)
1406  {
1407  write_stderr(_("%s: could not send signal %d (PID: %ld): %s\n"),
1408  progname, sig, pid, strerror(errno));
1409  exit(1);
1410  }
1411 }
1412 
1413 #ifdef WIN32
1414 
1415 static bool
1416 pgwin32_IsInstalled(SC_HANDLE hSCM)
1417 {
1418  SC_HANDLE hService = OpenService(hSCM, register_servicename, SERVICE_QUERY_CONFIG);
1419  bool bResult = (hService != NULL);
1420 
1421  if (bResult)
1422  CloseServiceHandle(hService);
1423  return bResult;
1424 }
1425 
1426 static char *
1427 pgwin32_CommandLine(bool registration)
1428 {
1429  PQExpBuffer cmdLine = createPQExpBuffer();
1430  char cmdPath[MAXPGPATH];
1431  int ret;
1432 
1433  if (registration)
1434  {
1435  ret = find_my_exec(argv0, cmdPath);
1436  if (ret != 0)
1437  {
1438  write_stderr(_("%s: could not find own program executable\n"), progname);
1439  exit(1);
1440  }
1441  }
1442  else
1443  {
1444  ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
1445  cmdPath);
1446  if (ret != 0)
1447  {
1448  write_stderr(_("%s: could not find postgres program executable\n"), progname);
1449  exit(1);
1450  }
1451  }
1452 
1453  /* if path does not end in .exe, append it */
1454  if (strlen(cmdPath) < 4 ||
1455  pg_strcasecmp(cmdPath + strlen(cmdPath) - 4, ".exe") != 0)
1456  snprintf(cmdPath + strlen(cmdPath), sizeof(cmdPath) - strlen(cmdPath),
1457  ".exe");
1458 
1459  /* use backslashes in path to avoid problems with some third-party tools */
1460  make_native_path(cmdPath);
1461 
1462  /* be sure to double-quote the executable's name in the command */
1463  appendPQExpBuffer(cmdLine, "\"%s\"", cmdPath);
1464 
1465  /* append assorted switches to the command line, as needed */
1466 
1467  if (registration)
1468  appendPQExpBuffer(cmdLine, " runservice -N \"%s\"",
1470 
1471  if (pg_config)
1472  {
1473  /* We need the -D path to be absolute */
1474  char *dataDir;
1475 
1476  if ((dataDir = make_absolute_path(pg_config)) == NULL)
1477  {
1478  /* make_absolute_path already reported the error */
1479  exit(1);
1480  }
1481  make_native_path(dataDir);
1482  appendPQExpBuffer(cmdLine, " -D \"%s\"", dataDir);
1483  free(dataDir);
1484  }
1485 
1486  if (registration && event_source != NULL)
1487  appendPQExpBuffer(cmdLine, " -e \"%s\"", event_source);
1488 
1489  if (registration && do_wait)
1490  appendPQExpBufferStr(cmdLine, " -w");
1491 
1492  /* Don't propagate a value from an environment variable. */
1493  if (registration && wait_seconds_arg && wait_seconds != DEFAULT_WAIT)
1494  appendPQExpBuffer(cmdLine, " -t %d", wait_seconds);
1495 
1496  if (registration && silent_mode)
1497  appendPQExpBufferStr(cmdLine, " -s");
1498 
1499  if (post_opts)
1500  {
1501  if (registration)
1502  appendPQExpBuffer(cmdLine, " -o \"%s\"", post_opts);
1503  else
1504  appendPQExpBuffer(cmdLine, " %s", post_opts);
1505  }
1506 
1507  return cmdLine->data;
1508 }
1509 
1510 static void
1511 pgwin32_doRegister(void)
1512 {
1513  SC_HANDLE hService;
1514  SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1515 
1516  if (hSCM == NULL)
1517  {
1518  write_stderr(_("%s: could not open service manager\n"), progname);
1519  exit(1);
1520  }
1521  if (pgwin32_IsInstalled(hSCM))
1522  {
1523  CloseServiceHandle(hSCM);
1524  write_stderr(_("%s: service \"%s\" already registered\n"), progname, register_servicename);
1525  exit(1);
1526  }
1527 
1528  if ((hService = CreateService(hSCM, register_servicename, register_servicename,
1529  SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
1530  pgctl_start_type, SERVICE_ERROR_NORMAL,
1531  pgwin32_CommandLine(true),
1532  NULL, NULL, "RPCSS\0", register_username, register_password)) == NULL)
1533  {
1534  CloseServiceHandle(hSCM);
1535  write_stderr(_("%s: could not register service \"%s\": error code %lu\n"),
1537  (unsigned long) GetLastError());
1538  exit(1);
1539  }
1540  CloseServiceHandle(hService);
1541  CloseServiceHandle(hSCM);
1542 }
1543 
1544 static void
1545 pgwin32_doUnregister(void)
1546 {
1547  SC_HANDLE hService;
1548  SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1549 
1550  if (hSCM == NULL)
1551  {
1552  write_stderr(_("%s: could not open service manager\n"), progname);
1553  exit(1);
1554  }
1555  if (!pgwin32_IsInstalled(hSCM))
1556  {
1557  CloseServiceHandle(hSCM);
1558  write_stderr(_("%s: service \"%s\" not registered\n"), progname, register_servicename);
1559  exit(1);
1560  }
1561 
1562  if ((hService = OpenService(hSCM, register_servicename, DELETE)) == NULL)
1563  {
1564  CloseServiceHandle(hSCM);
1565  write_stderr(_("%s: could not open service \"%s\": error code %lu\n"),
1567  (unsigned long) GetLastError());
1568  exit(1);
1569  }
1570  if (!DeleteService(hService))
1571  {
1572  CloseServiceHandle(hService);
1573  CloseServiceHandle(hSCM);
1574  write_stderr(_("%s: could not unregister service \"%s\": error code %lu\n"),
1576  (unsigned long) GetLastError());
1577  exit(1);
1578  }
1579  CloseServiceHandle(hService);
1580  CloseServiceHandle(hSCM);
1581 }
1582 
1583 static void
1584 pgwin32_SetServiceStatus(DWORD currentState)
1585 {
1586  status.dwCurrentState = currentState;
1587  SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
1588 }
1589 
1590 static void WINAPI
1591 pgwin32_ServiceHandler(DWORD request)
1592 {
1593  switch (request)
1594  {
1595  case SERVICE_CONTROL_STOP:
1596  case SERVICE_CONTROL_SHUTDOWN:
1597 
1598  /*
1599  * We only need a short wait hint here as it just needs to wait
1600  * for the next checkpoint. They occur every 5 seconds during
1601  * shutdown
1602  */
1603  status.dwWaitHint = 10000;
1604  pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1605  SetEvent(shutdownEvent);
1606  return;
1607 
1608  case SERVICE_CONTROL_PAUSE:
1609  /* Win32 config reloading */
1610  status.dwWaitHint = 5000;
1612  return;
1613 
1614  /* FIXME: These could be used to replace other signals etc */
1615  case SERVICE_CONTROL_CONTINUE:
1616  case SERVICE_CONTROL_INTERROGATE:
1617  default:
1618  break;
1619  }
1620 }
1621 
1622 static void WINAPI
1623 pgwin32_ServiceMain(DWORD argc, LPTSTR *argv)
1624 {
1625  PROCESS_INFORMATION pi;
1626  DWORD ret;
1627 
1628  /* Initialize variables */
1629  status.dwWin32ExitCode = S_OK;
1630  status.dwCheckPoint = 0;
1631  status.dwWaitHint = 60000;
1632  status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
1633  status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
1634  status.dwServiceSpecificExitCode = 0;
1635  status.dwCurrentState = SERVICE_START_PENDING;
1636 
1637  memset(&pi, 0, sizeof(pi));
1638 
1639  read_post_opts();
1640 
1641  /* Register the control request handler */
1642  if ((hStatus = RegisterServiceCtrlHandler(register_servicename, pgwin32_ServiceHandler)) == (SERVICE_STATUS_HANDLE) 0)
1643  return;
1644 
1645  if ((shutdownEvent = CreateEvent(NULL, true, false, NULL)) == NULL)
1646  return;
1647 
1648  /* Start the postmaster */
1649  pgwin32_SetServiceStatus(SERVICE_START_PENDING);
1650  if (!CreateRestrictedProcess(pgwin32_CommandLine(false), &pi, true))
1651  {
1652  pgwin32_SetServiceStatus(SERVICE_STOPPED);
1653  return;
1654  }
1655  postmasterPID = pi.dwProcessId;
1656  postmasterProcess = pi.hProcess;
1657  CloseHandle(pi.hThread);
1658 
1659  if (do_wait)
1660  {
1661  write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Waiting for server startup...\n"));
1663  {
1664  write_eventlog(EVENTLOG_ERROR_TYPE, _("Timed out waiting for server startup\n"));
1665  pgwin32_SetServiceStatus(SERVICE_STOPPED);
1666  return;
1667  }
1668  write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Server started and accepting connections\n"));
1669  }
1670 
1671  pgwin32_SetServiceStatus(SERVICE_RUNNING);
1672 
1673  /* Wait for quit... */
1674  ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);
1675 
1676  pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1677  switch (ret)
1678  {
1679  case WAIT_OBJECT_0: /* shutdown event */
1680  {
1681  /*
1682  * status.dwCheckPoint can be incremented by
1683  * wait_for_postmaster(), so it might not start from 0.
1684  */
1685  int maxShutdownCheckPoint = status.dwCheckPoint + 12;
1686 
1687  kill(postmasterPID, SIGINT);
1688 
1689  /*
1690  * Increment the checkpoint and try again. Abort after 12
1691  * checkpoints as the postmaster has probably hung.
1692  */
1693  while (WaitForSingleObject(postmasterProcess, 5000) == WAIT_TIMEOUT && status.dwCheckPoint < maxShutdownCheckPoint)
1694  {
1695  status.dwCheckPoint++;
1696  SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
1697  }
1698  break;
1699  }
1700 
1701  case (WAIT_OBJECT_0 + 1): /* postmaster went down */
1702  break;
1703 
1704  default:
1705  /* shouldn't get here? */
1706  break;
1707  }
1708 
1709  CloseHandle(shutdownEvent);
1710  CloseHandle(postmasterProcess);
1711 
1712  pgwin32_SetServiceStatus(SERVICE_STOPPED);
1713 }
1714 
1715 static void
1716 pgwin32_doRunAsService(void)
1717 {
1718  SERVICE_TABLE_ENTRY st[] = {{register_servicename, pgwin32_ServiceMain},
1719  {NULL, NULL}};
1720 
1721  if (StartServiceCtrlDispatcher(st) == 0)
1722  {
1723  write_stderr(_("%s: could not start service \"%s\": error code %lu\n"),
1725  (unsigned long) GetLastError());
1726  exit(1);
1727  }
1728 }
1729 
1730 
1731 /*
1732  * Mingw headers are incomplete, and so are the libraries. So we have to load
1733  * a whole lot of API functions dynamically. Since we have to do this anyway,
1734  * also load the couple of functions that *do* exist in mingw headers but not
1735  * on NT4. That way, we don't break on NT4.
1736  */
1737 typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
1738 typedef BOOL (WINAPI * __IsProcessInJob) (HANDLE, HANDLE, PBOOL);
1739 typedef HANDLE (WINAPI * __CreateJobObject) (LPSECURITY_ATTRIBUTES, LPCTSTR);
1740 typedef BOOL (WINAPI * __SetInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD);
1741 typedef BOOL (WINAPI * __AssignProcessToJobObject) (HANDLE, HANDLE);
1742 typedef BOOL (WINAPI * __QueryInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD);
1743 
1744 /*
1745  * Set up STARTUPINFO for the new process to inherit this process' handles.
1746  *
1747  * Process started as services appear to have "empty" handles (GetStdHandle()
1748  * returns NULL) rather than invalid ones. But passing down NULL ourselves
1749  * doesn't work, it's interpreted as STARTUPINFO->hStd* not being set. But we
1750  * can pass down INVALID_HANDLE_VALUE - which makes GetStdHandle() in the new
1751  * process (and its child processes!) return INVALID_HANDLE_VALUE. Which
1752  * achieves the goal of postmaster running in a similar environment as pg_ctl.
1753  */
1754 static void
1755 InheritStdHandles(STARTUPINFO* si)
1756 {
1757  si->dwFlags |= STARTF_USESTDHANDLES;
1758  si->hStdInput = GetStdHandle(STD_INPUT_HANDLE);
1759  if (si->hStdInput == NULL)
1760  si->hStdInput = INVALID_HANDLE_VALUE;
1761  si->hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
1762  if (si->hStdOutput == NULL)
1763  si->hStdOutput = INVALID_HANDLE_VALUE;
1764  si->hStdError = GetStdHandle(STD_ERROR_HANDLE);
1765  if (si->hStdError == NULL)
1766  si->hStdError = INVALID_HANDLE_VALUE;
1767 }
1768 
1769 /*
1770  * Create a restricted token, a job object sandbox, and execute the specified
1771  * process with it.
1772  *
1773  * Returns 0 on success, non-zero on failure, same as CreateProcess().
1774  *
1775  * On NT4, or any other system not containing the required functions, will
1776  * launch the process under the current token without doing any modifications.
1777  *
1778  * NOTE! Job object will only work when running as a service, because it's
1779  * automatically destroyed when pg_ctl exits.
1780  */
1781 static int
1782 CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service)
1783 {
1784  int r;
1785  BOOL b;
1786  STARTUPINFO si;
1787  HANDLE origToken;
1788  HANDLE restrictedToken;
1789  SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
1790  SID_AND_ATTRIBUTES dropSids[2];
1791  PTOKEN_PRIVILEGES delPrivs;
1792 
1793  /* Functions loaded dynamically */
1794  __CreateRestrictedToken _CreateRestrictedToken = NULL;
1795  __IsProcessInJob _IsProcessInJob = NULL;
1796  __CreateJobObject _CreateJobObject = NULL;
1797  __SetInformationJobObject _SetInformationJobObject = NULL;
1798  __AssignProcessToJobObject _AssignProcessToJobObject = NULL;
1799  __QueryInformationJobObject _QueryInformationJobObject = NULL;
1800  HANDLE Kernel32Handle;
1801  HANDLE Advapi32Handle;
1802 
1803  ZeroMemory(&si, sizeof(si));
1804  si.cb = sizeof(si);
1805 
1806  /*
1807  * Set stdin/stdout/stderr handles to be inherited in the child
1808  * process. That allows postmaster and the processes it starts to perform
1809  * additional checks to see if running in a service (otherwise they get
1810  * the default console handles - which point to "somewhere").
1811  */
1812  InheritStdHandles(&si);
1813 
1814  Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
1815  if (Advapi32Handle != NULL)
1816  {
1817  _CreateRestrictedToken = (__CreateRestrictedToken) (pg_funcptr_t) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
1818  }
1819 
1820  if (_CreateRestrictedToken == NULL)
1821  {
1822  /*
1823  * NT4 doesn't have CreateRestrictedToken, so just call ordinary
1824  * CreateProcess
1825  */
1826  write_stderr(_("%s: WARNING: cannot create restricted tokens on this platform\n"), progname);
1827  if (Advapi32Handle != NULL)
1828  FreeLibrary(Advapi32Handle);
1829  return CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, processInfo);
1830  }
1831 
1832  /* Open the current token to use as a base for the restricted one */
1833  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
1834  {
1835  /*
1836  * Most Windows targets make DWORD a 32-bit unsigned long, but in case
1837  * it doesn't cast DWORD before printing.
1838  */
1839  write_stderr(_("%s: could not open process token: error code %lu\n"),
1840  progname, (unsigned long) GetLastError());
1841  return 0;
1842  }
1843 
1844  /* Allocate list of SIDs to remove */
1845  ZeroMemory(&dropSids, sizeof(dropSids));
1846  if (!AllocateAndInitializeSid(&NtAuthority, 2,
1847  SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
1848  0, &dropSids[0].Sid) ||
1849  !AllocateAndInitializeSid(&NtAuthority, 2,
1850  SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
1851  0, &dropSids[1].Sid))
1852  {
1853  write_stderr(_("%s: could not allocate SIDs: error code %lu\n"),
1854  progname, (unsigned long) GetLastError());
1855  return 0;
1856  }
1857 
1858  /* Get list of privileges to remove */
1859  delPrivs = GetPrivilegesToDelete(origToken);
1860  if (delPrivs == NULL)
1861  /* Error message already printed */
1862  return 0;
1863 
1864  b = _CreateRestrictedToken(origToken,
1865  0,
1866  sizeof(dropSids) / sizeof(dropSids[0]),
1867  dropSids,
1868  delPrivs->PrivilegeCount, delPrivs->Privileges,
1869  0, NULL,
1870  &restrictedToken);
1871 
1872  free(delPrivs);
1873  FreeSid(dropSids[1].Sid);
1874  FreeSid(dropSids[0].Sid);
1875  CloseHandle(origToken);
1876  FreeLibrary(Advapi32Handle);
1877 
1878  if (!b)
1879  {
1880  write_stderr(_("%s: could not create restricted token: error code %lu\n"),
1881  progname, (unsigned long) GetLastError());
1882  return 0;
1883  }
1884 
1885  AddUserToTokenDacl(restrictedToken);
1886  r = CreateProcessAsUser(restrictedToken, NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, processInfo);
1887 
1888  Kernel32Handle = LoadLibrary("KERNEL32.DLL");
1889  if (Kernel32Handle != NULL)
1890  {
1891  _IsProcessInJob = (__IsProcessInJob) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "IsProcessInJob");
1892  _CreateJobObject = (__CreateJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "CreateJobObjectA");
1893  _SetInformationJobObject = (__SetInformationJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "SetInformationJobObject");
1894  _AssignProcessToJobObject = (__AssignProcessToJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject");
1895  _QueryInformationJobObject = (__QueryInformationJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "QueryInformationJobObject");
1896  }
1897 
1898  /* Verify that we found all functions */
1899  if (_IsProcessInJob == NULL || _CreateJobObject == NULL || _SetInformationJobObject == NULL || _AssignProcessToJobObject == NULL || _QueryInformationJobObject == NULL)
1900  {
1901  /*
1902  * IsProcessInJob() is not available on < WinXP, so there is no need
1903  * to log the error every time in that case
1904  */
1905  if (IsWindowsXPOrGreater())
1906 
1907  /*
1908  * Log error if we can't get version, or if we're on WinXP/2003 or
1909  * newer
1910  */
1911  write_stderr(_("%s: WARNING: could not locate all job object functions in system API\n"), progname);
1912  }
1913  else
1914  {
1915  BOOL inJob;
1916 
1917  if (_IsProcessInJob(processInfo->hProcess, NULL, &inJob))
1918  {
1919  if (!inJob)
1920  {
1921  /*
1922  * Job objects are working, and the new process isn't in one,
1923  * so we can create one safely. If any problems show up when
1924  * setting it, we're going to ignore them.
1925  */
1926  HANDLE job;
1927  char jobname[128];
1928 
1929  sprintf(jobname, "PostgreSQL_%lu",
1930  (unsigned long) processInfo->dwProcessId);
1931 
1932  job = _CreateJobObject(NULL, jobname);
1933  if (job)
1934  {
1935  JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
1936  JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
1937  JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
1938 
1939  ZeroMemory(&basicLimit, sizeof(basicLimit));
1940  ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
1941  ZeroMemory(&securityLimit, sizeof(securityLimit));
1942 
1943  basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
1944  basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
1945  _SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));
1946 
1947  uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
1948  JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
1949  JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
1950 
1951  if (as_service)
1952  {
1953  if (!IsWindows7OrGreater())
1954  {
1955  /*
1956  * On Windows 7 (and presumably later),
1957  * JOB_OBJECT_UILIMIT_HANDLES prevents us from
1958  * starting as a service. So we only enable it on
1959  * Vista and earlier (version <= 6.0)
1960  */
1961  uiRestrictions.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
1962  }
1963  }
1964  _SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));
1965 
1966  securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
1967  securityLimit.JobToken = restrictedToken;
1968  _SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));
1969 
1970  _AssignProcessToJobObject(job, processInfo->hProcess);
1971  }
1972  }
1973  }
1974  }
1975 
1976 
1977  CloseHandle(restrictedToken);
1978 
1979  ResumeThread(processInfo->hThread);
1980 
1981  FreeLibrary(Kernel32Handle);
1982 
1983  /*
1984  * We intentionally don't close the job object handle, because we want the
1985  * object to live on until pg_ctl shuts down.
1986  */
1987  return r;
1988 }
1989 
1990 /*
1991  * Get a list of privileges to delete from the access token. We delete all privileges
1992  * except SeLockMemoryPrivilege which is needed to use large pages, and
1993  * SeChangeNotifyPrivilege which is enabled by default in DISABLE_MAX_PRIVILEGE.
1994  */
1995 static PTOKEN_PRIVILEGES
1996 GetPrivilegesToDelete(HANDLE hToken)
1997 {
1998  int i,
1999  j;
2000  DWORD length;
2001  PTOKEN_PRIVILEGES tokenPrivs;
2002  LUID luidLockPages;
2003  LUID luidChangeNotify;
2004 
2005  if (!LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &luidLockPages) ||
2006  !LookupPrivilegeValue(NULL, SE_CHANGE_NOTIFY_NAME, &luidChangeNotify))
2007  {
2008  write_stderr(_("%s: could not get LUIDs for privileges: error code %lu\n"),
2009  progname, (unsigned long) GetLastError());
2010  return NULL;
2011  }
2012 
2013  if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &length) &&
2014  GetLastError() != ERROR_INSUFFICIENT_BUFFER)
2015  {
2016  write_stderr(_("%s: could not get token information: error code %lu\n"),
2017  progname, (unsigned long) GetLastError());
2018  return NULL;
2019  }
2020 
2021  tokenPrivs = (PTOKEN_PRIVILEGES) pg_malloc_extended(length,
2023  if (tokenPrivs == NULL)
2024  {
2025  write_stderr(_("%s: out of memory\n"), progname);
2026  return NULL;
2027  }
2028 
2029  if (!GetTokenInformation(hToken, TokenPrivileges, tokenPrivs, length, &length))
2030  {
2031  write_stderr(_("%s: could not get token information: error code %lu\n"),
2032  progname, (unsigned long) GetLastError());
2033  free(tokenPrivs);
2034  return NULL;
2035  }
2036 
2037  for (i = 0; i < tokenPrivs->PrivilegeCount; i++)
2038  {
2039  if (memcmp(&tokenPrivs->Privileges[i].Luid, &luidLockPages, sizeof(LUID)) == 0 ||
2040  memcmp(&tokenPrivs->Privileges[i].Luid, &luidChangeNotify, sizeof(LUID)) == 0)
2041  {
2042  for (j = i; j < tokenPrivs->PrivilegeCount - 1; j++)
2043  tokenPrivs->Privileges[j] = tokenPrivs->Privileges[j + 1];
2044  tokenPrivs->PrivilegeCount--;
2045  }
2046  }
2047 
2048  return tokenPrivs;
2049 }
2050 #endif /* WIN32 */
2051 
2052 static void
2054 {
2055  write_stderr(_("Try \"%s --help\" for more information.\n"), progname);
2056 }
2057 
2058 
2059 
2060 static void
2061 do_help(void)
2062 {
2063  printf(_("%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n\n"), progname);
2064  printf(_("Usage:\n"));
2065  printf(_(" %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n"), progname);
2066  printf(_(" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n"
2067  " [-o OPTIONS] [-p PATH] [-c]\n"), progname);
2068  printf(_(" %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n"), progname);
2069  printf(_(" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n"
2070  " [-o OPTIONS] [-c]\n"), progname);
2071  printf(_(" %s reload [-D DATADIR] [-s]\n"), progname);
2072  printf(_(" %s status [-D DATADIR]\n"), progname);
2073  printf(_(" %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n"), progname);
2074  printf(_(" %s logrotate [-D DATADIR] [-s]\n"), progname);
2075  printf(_(" %s kill SIGNALNAME PID\n"), progname);
2076 #ifdef WIN32
2077  printf(_(" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n"
2078  " [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n"), progname);
2079  printf(_(" %s unregister [-N SERVICENAME]\n"), progname);
2080 #endif
2081 
2082  printf(_("\nCommon options:\n"));
2083  printf(_(" -D, --pgdata=DATADIR location of the database storage area\n"));
2084 #ifdef WIN32
2085  printf(_(" -e SOURCE event source for logging when running as a service\n"));
2086 #endif
2087  printf(_(" -s, --silent only print errors, no informational messages\n"));
2088  printf(_(" -t, --timeout=SECS seconds to wait when using -w option\n"));
2089  printf(_(" -V, --version output version information, then exit\n"));
2090  printf(_(" -w, --wait wait until operation completes (default)\n"));
2091  printf(_(" -W, --no-wait do not wait until operation completes\n"));
2092  printf(_(" -?, --help show this help, then exit\n"));
2093  printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
2094 
2095  printf(_("\nOptions for start or restart:\n"));
2096 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
2097  printf(_(" -c, --core-files allow postgres to produce core files\n"));
2098 #else
2099  printf(_(" -c, --core-files not applicable on this platform\n"));
2100 #endif
2101  printf(_(" -l, --log=FILENAME write (or append) server log to FILENAME\n"));
2102  printf(_(" -o, --options=OPTIONS command line options to pass to postgres\n"
2103  " (PostgreSQL server executable) or initdb\n"));
2104  printf(_(" -p PATH-TO-POSTGRES normally not necessary\n"));
2105  printf(_("\nOptions for stop or restart:\n"));
2106  printf(_(" -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n"));
2107 
2108  printf(_("\nShutdown modes are:\n"));
2109  printf(_(" smart quit after all clients have disconnected\n"));
2110  printf(_(" fast quit directly, with proper shutdown (default)\n"));
2111  printf(_(" immediate quit without complete shutdown; will lead to recovery on restart\n"));
2112 
2113  printf(_("\nAllowed signal names for kill:\n"));
2114  printf(" ABRT HUP INT KILL QUIT TERM USR1 USR2\n");
2115 
2116 #ifdef WIN32
2117  printf(_("\nOptions for register and unregister:\n"));
2118  printf(_(" -N SERVICENAME service name with which to register PostgreSQL server\n"));
2119  printf(_(" -P PASSWORD password of account to register PostgreSQL server\n"));
2120  printf(_(" -U USERNAME user name of account to register PostgreSQL server\n"));
2121  printf(_(" -S START-TYPE service start type to register PostgreSQL server\n"));
2122 
2123  printf(_("\nStart types are:\n"));
2124  printf(_(" auto start service automatically during system startup (default)\n"));
2125  printf(_(" demand start service on demand\n"));
2126 #endif
2127 
2128  printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
2129  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
2130 }
2131 
2132 
2133 
2134 static void
2135 set_mode(char *modeopt)
2136 {
2137  if (strcmp(modeopt, "s") == 0 || strcmp(modeopt, "smart") == 0)
2138  {
2140  sig = SIGTERM;
2141  }
2142  else if (strcmp(modeopt, "f") == 0 || strcmp(modeopt, "fast") == 0)
2143  {
2145  sig = SIGINT;
2146  }
2147  else if (strcmp(modeopt, "i") == 0 || strcmp(modeopt, "immediate") == 0)
2148  {
2150  sig = SIGQUIT;
2151  }
2152  else
2153  {
2154  write_stderr(_("%s: unrecognized shutdown mode \"%s\"\n"), progname, modeopt);
2155  do_advice();
2156  exit(1);
2157  }
2158 }
2159 
2160 
2161 
2162 static void
2163 set_sig(char *signame)
2164 {
2165  if (strcmp(signame, "HUP") == 0)
2166  sig = SIGHUP;
2167  else if (strcmp(signame, "INT") == 0)
2168  sig = SIGINT;
2169  else if (strcmp(signame, "QUIT") == 0)
2170  sig = SIGQUIT;
2171  else if (strcmp(signame, "ABRT") == 0)
2172  sig = SIGABRT;
2173  else if (strcmp(signame, "KILL") == 0)
2174  sig = SIGKILL;
2175  else if (strcmp(signame, "TERM") == 0)
2176  sig = SIGTERM;
2177  else if (strcmp(signame, "USR1") == 0)
2178  sig = SIGUSR1;
2179  else if (strcmp(signame, "USR2") == 0)
2180  sig = SIGUSR2;
2181  else
2182  {
2183  write_stderr(_("%s: unrecognized signal name \"%s\"\n"), progname, signame);
2184  do_advice();
2185  exit(1);
2186  }
2187 }
2188 
2189 
2190 #ifdef WIN32
2191 static void
2192 set_starttype(char *starttypeopt)
2193 {
2194  if (strcmp(starttypeopt, "a") == 0 || strcmp(starttypeopt, "auto") == 0)
2195  pgctl_start_type = SERVICE_AUTO_START;
2196  else if (strcmp(starttypeopt, "d") == 0 || strcmp(starttypeopt, "demand") == 0)
2197  pgctl_start_type = SERVICE_DEMAND_START;
2198  else
2199  {
2200  write_stderr(_("%s: unrecognized start type \"%s\"\n"), progname, starttypeopt);
2201  do_advice();
2202  exit(1);
2203  }
2204 }
2205 #endif
2206 
2207 /*
2208  * adjust_data_dir
2209  *
2210  * If a configuration-only directory was specified, find the real data dir.
2211  */
2212 static void
2214 {
2215  char filename[MAXPGPATH];
2216  char *my_exec_path,
2217  *cmd;
2218  FILE *fd;
2219 
2220  /* do nothing if we're working without knowledge of data dir */
2221  if (pg_config == NULL)
2222  return;
2223 
2224  /* If there is no postgresql.conf, it can't be a config-only dir */
2225  snprintf(filename, sizeof(filename), "%s/postgresql.conf", pg_config);
2226  if ((fd = fopen(filename, "r")) == NULL)
2227  return;
2228  fclose(fd);
2229 
2230  /* If PG_VERSION exists, it can't be a config-only dir */
2231  snprintf(filename, sizeof(filename), "%s/PG_VERSION", pg_config);
2232  if ((fd = fopen(filename, "r")) != NULL)
2233  {
2234  fclose(fd);
2235  return;
2236  }
2237 
2238  /* Must be a configuration directory, so find the data directory */
2239 
2240  /* we use a private my_exec_path to avoid interfering with later uses */
2241  if (exec_path == NULL)
2243  else
2245 
2246  /* it's important for -C to be the first option, see main.c */
2247  cmd = psprintf("\"%s\" -C data_directory %s%s",
2248  my_exec_path,
2249  pgdata_opt ? pgdata_opt : "",
2250  post_opts ? post_opts : "");
2251 
2252  fd = popen(cmd, "r");
2253  if (fd == NULL || fgets(filename, sizeof(filename), fd) == NULL)
2254  {
2255  write_stderr(_("%s: could not determine the data directory using command \"%s\"\n"), progname, cmd);
2256  exit(1);
2257  }
2258  pclose(fd);
2259  free(my_exec_path);
2260 
2261  /* strip trailing newline and carriage return */
2262  (void) pg_strip_crlf(filename);
2263 
2264  free(pg_data);
2267 }
2268 
2269 
2270 static DBState
2272 {
2273  DBState ret;
2274  bool crc_ok;
2275  ControlFileData *control_file_data = get_controlfile(pg_data, &crc_ok);
2276 
2277  if (!crc_ok)
2278  {
2279  write_stderr(_("%s: control file appears to be corrupt\n"), progname);
2280  exit(1);
2281  }
2282 
2283  ret = control_file_data->state;
2284  pfree(control_file_data);
2285  return ret;
2286 }
2287 
2288 
2289 int
2290 main(int argc, char **argv)
2291 {
2292  static struct option long_options[] = {
2293  {"help", no_argument, NULL, '?'},
2294  {"version", no_argument, NULL, 'V'},
2295  {"log", required_argument, NULL, 'l'},
2296  {"mode", required_argument, NULL, 'm'},
2297  {"pgdata", required_argument, NULL, 'D'},
2298  {"options", required_argument, NULL, 'o'},
2299  {"silent", no_argument, NULL, 's'},
2300  {"timeout", required_argument, NULL, 't'},
2301  {"core-files", no_argument, NULL, 'c'},
2302  {"wait", no_argument, NULL, 'w'},
2303  {"no-wait", no_argument, NULL, 'W'},
2304  {NULL, 0, NULL, 0}
2305  };
2306 
2307  char *env_wait;
2308  int option_index;
2309  int c;
2310  pgpid_t killproc = 0;
2311 
2312  pg_logging_init(argv[0]);
2313  progname = get_progname(argv[0]);
2314  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_ctl"));
2315  start_time = time(NULL);
2316 
2317  /*
2318  * save argv[0] so do_start() can look for the postmaster if necessary. we
2319  * don't look for postmaster here because in many cases we won't need it.
2320  */
2321  argv0 = argv[0];
2322 
2323  /* Set restrictive mode mask until PGDATA permissions are checked */
2324  umask(PG_MODE_MASK_OWNER);
2325 
2326  /* support --help and --version even if invoked as root */
2327  if (argc > 1)
2328  {
2329  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
2330  {
2331  do_help();
2332  exit(0);
2333  }
2334  else if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
2335  {
2336  puts("pg_ctl (PostgreSQL) " PG_VERSION);
2337  exit(0);
2338  }
2339  }
2340 
2341  /*
2342  * Disallow running as root, to forestall any possible security holes.
2343  */
2344 #ifndef WIN32
2345  if (geteuid() == 0)
2346  {
2347  write_stderr(_("%s: cannot be run as root\n"
2348  "Please log in (using, e.g., \"su\") as the "
2349  "(unprivileged) user that will\n"
2350  "own the server process.\n"),
2351  progname);
2352  exit(1);
2353  }
2354 #endif
2355 
2356  env_wait = getenv("PGCTLTIMEOUT");
2357  if (env_wait != NULL)
2358  wait_seconds = atoi(env_wait);
2359 
2360  /*
2361  * 'Action' can be before or after args so loop over both. Some
2362  * getopt_long() implementations will reorder argv[] to place all flags
2363  * first (GNU?), but we don't rely on it. Our /port version doesn't do
2364  * that.
2365  */
2366  optind = 1;
2367 
2368  /* process command-line options */
2369  while (optind < argc)
2370  {
2371  while ((c = getopt_long(argc, argv, "cD:e:l:m:N:o:p:P:sS:t:U:wW",
2372  long_options, &option_index)) != -1)
2373  {
2374  switch (c)
2375  {
2376  case 'D':
2377  {
2378  char *pgdata_D;
2379 
2380  pgdata_D = pg_strdup(optarg);
2381  canonicalize_path(pgdata_D);
2382  setenv("PGDATA", pgdata_D, 1);
2383 
2384  /*
2385  * We could pass PGDATA just in an environment
2386  * variable but we do -D too for clearer postmaster
2387  * 'ps' display
2388  */
2389  pgdata_opt = psprintf("-D \"%s\" ", pgdata_D);
2390  free(pgdata_D);
2391  break;
2392  }
2393  case 'e':
2395  break;
2396  case 'l':
2398  break;
2399  case 'm':
2400  set_mode(optarg);
2401  break;
2402  case 'N':
2404  break;
2405  case 'o':
2406  /* append option? */
2407  if (!post_opts)
2409  else
2410  {
2411  char *old_post_opts = post_opts;
2412 
2413  post_opts = psprintf("%s %s", old_post_opts, optarg);
2414  free(old_post_opts);
2415  }
2416  break;
2417  case 'p':
2419  break;
2420  case 'P':
2422  break;
2423  case 's':
2424  silent_mode = true;
2425  break;
2426  case 'S':
2427 #ifdef WIN32
2428  set_starttype(optarg);
2429 #else
2430  write_stderr(_("%s: -S option not supported on this platform\n"),
2431  progname);
2432  exit(1);
2433 #endif
2434  break;
2435  case 't':
2436  wait_seconds = atoi(optarg);
2437  wait_seconds_arg = true;
2438  break;
2439  case 'U':
2440  if (strchr(optarg, '\\'))
2442  else
2443  /* Prepend .\ for local accounts */
2444  register_username = psprintf(".\\%s", optarg);
2445  break;
2446  case 'w':
2447  do_wait = true;
2448  break;
2449  case 'W':
2450  do_wait = false;
2451  break;
2452  case 'c':
2453  allow_core_files = true;
2454  break;
2455  default:
2456  /* getopt_long already issued a suitable error message */
2457  do_advice();
2458  exit(1);
2459  }
2460  }
2461 
2462  /* Process an action */
2463  if (optind < argc)
2464  {
2465  if (ctl_command != NO_COMMAND)
2466  {
2467  write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]);
2468  do_advice();
2469  exit(1);
2470  }
2471 
2472  if (strcmp(argv[optind], "init") == 0
2473  || strcmp(argv[optind], "initdb") == 0)
2475  else if (strcmp(argv[optind], "start") == 0)
2477  else if (strcmp(argv[optind], "stop") == 0)
2479  else if (strcmp(argv[optind], "restart") == 0)
2481  else if (strcmp(argv[optind], "reload") == 0)
2483  else if (strcmp(argv[optind], "status") == 0)
2485  else if (strcmp(argv[optind], "promote") == 0)
2487  else if (strcmp(argv[optind], "logrotate") == 0)
2489  else if (strcmp(argv[optind], "kill") == 0)
2490  {
2491  if (argc - optind < 3)
2492  {
2493  write_stderr(_("%s: missing arguments for kill mode\n"), progname);
2494  do_advice();
2495  exit(1);
2496  }
2498  set_sig(argv[++optind]);
2499  killproc = atol(argv[++optind]);
2500  }
2501 #ifdef WIN32
2502  else if (strcmp(argv[optind], "register") == 0)
2504  else if (strcmp(argv[optind], "unregister") == 0)
2506  else if (strcmp(argv[optind], "runservice") == 0)
2508 #endif
2509  else
2510  {
2511  write_stderr(_("%s: unrecognized operation mode \"%s\"\n"), progname, argv[optind]);
2512  do_advice();
2513  exit(1);
2514  }
2515  optind++;
2516  }
2517  }
2518 
2519  if (ctl_command == NO_COMMAND)
2520  {
2521  write_stderr(_("%s: no operation specified\n"), progname);
2522  do_advice();
2523  exit(1);
2524  }
2525 
2526  /* Note we put any -D switch into the env var above */
2527  pg_config = getenv("PGDATA");
2528  if (pg_config)
2529  {
2533  }
2534 
2535  /* -D might point at config-only directory; if so find the real PGDATA */
2536  adjust_data_dir();
2537 
2538  /* Complain if -D needed and not provided */
2539  if (pg_config == NULL &&
2541  {
2542  write_stderr(_("%s: no database directory specified and environment variable PGDATA unset\n"),
2543  progname);
2544  do_advice();
2545  exit(1);
2546  }
2547 
2548  if (ctl_command == RELOAD_COMMAND)
2549  {
2550  sig = SIGHUP;
2551  do_wait = false;
2552  }
2553 
2554  if (pg_data)
2555  {
2556  snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);
2557  snprintf(version_file, MAXPGPATH, "%s/PG_VERSION", pg_data);
2558  snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
2559  snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data);
2560 
2561  /*
2562  * Set mask based on PGDATA permissions,
2563  *
2564  * Don't error here if the data directory cannot be stat'd. This is
2565  * handled differently based on the command and we don't want to
2566  * interfere with that logic.
2567  */
2569  umask(pg_mode_mask);
2570  }
2571 
2572  switch (ctl_command)
2573  {
2574  case INIT_COMMAND:
2575  do_init();
2576  break;
2577  case STATUS_COMMAND:
2578  do_status();
2579  break;
2580  case START_COMMAND:
2581  do_start();
2582  break;
2583  case STOP_COMMAND:
2584  do_stop();
2585  break;
2586  case RESTART_COMMAND:
2587  do_restart();
2588  break;
2589  case RELOAD_COMMAND:
2590  do_reload();
2591  break;
2592  case PROMOTE_COMMAND:
2593  do_promote();
2594  break;
2595  case LOGROTATE_COMMAND:
2596  do_logrotate();
2597  break;
2598  case KILL_COMMAND:
2599  do_kill(killproc);
2600  break;
2601 #ifdef WIN32
2602  case REGISTER_COMMAND:
2603  pgwin32_doRegister();
2604  break;
2605  case UNREGISTER_COMMAND:
2606  pgwin32_doUnregister();
2607  break;
2609  pgwin32_doRunAsService();
2610  break;
2611 #endif
2612  default:
2613  break;
2614  }
2615 
2616  exit(0);
2617 }
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1212
#define PG_BINARY
Definition: c.h:1268
#define pg_attribute_printf(f, a)
Definition: c.h:164
void(* pg_funcptr_t)(void)
Definition: c.h:340
int find_my_exec(const char *argv0, char *retpath)
Definition: exec.c:135
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:441
int find_other_exec(const char *argv0, const char *target, const char *versionstr, char *retpath)
Definition: exec.c:330
ControlFileData * get_controlfile(const char *DataDir, bool *crc_ok_p)
#define _(x)
Definition: elog.c:89
void * pg_malloc_extended(size_t size, int flags)
Definition: fe_memutils.c:59
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define MCXT_ALLOC_NO_OOM
Definition: fe_memutils.h:17
int pg_mode_mask
Definition: file_perm.c:25
bool GetDataDirectoryCreatePerm(const char *dataDir)
#define PG_MODE_MASK_OWNER
Definition: file_perm.h:24
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:57
#define no_argument
Definition: getopt_long.h:24
#define required_argument
Definition: getopt_long.h:25
char my_exec_path[MAXPGPATH]
Definition: globals.c:75
#define free(a)
Definition: header.h:65
#define close(a)
Definition: win32.h:12
#define read(a, b, c)
Definition: win32.h:13
int b
Definition: isn.c:70
int j
Definition: isn.c:74
int i
Definition: isn.c:73
static void const char fflush(stdout)
va_end(args)
vfprintf(stderr, fmt, args)
exit(1)
static void const char * fmt
va_start(args, fmt)
void pg_logging_init(const char *argv0)
Definition: logging.c:81
void pfree(void *pointer)
Definition: mcxt.c:1169
#define MAXPGPATH
#define DEFAULT_EVENT_SOURCE
DBState
Definition: pg_control.h:88
@ DB_IN_PRODUCTION
Definition: pg_control.h:95
@ DB_STARTUP
Definition: pg_control.h:89
@ DB_IN_ARCHIVE_RECOVERY
Definition: pg_control.h:94
const void size_t len
static char * post_opts
Definition: pg_ctl.c:89
static void trap_sigint_during_startup(int sig)
Definition: pg_ctl.c:784
static void read_post_opts(void)
Definition: pg_ctl.c:729
static void static void do_advice(void)
Definition: pg_ctl.c:2053
#define WAITS_PER_SEC
Definition: pg_ctl.c:77
static char * pgdata_opt
Definition: pg_ctl.c:88
static void do_reload(void)
Definition: pg_ctl.c:1134
static void do_help(void)
Definition: pg_ctl.c:2061
static void free_readfile(char **optlines)
Definition: pg_ctl.c:413
static char * register_username
Definition: pg_ctl.c:95
long pgpid_t
Definition: pg_ctl.c:39
static char * find_other_exec_or_die(const char *argv0, const char *target, const char *versionstr)
Definition: pg_ctl.c:802
static char * event_source
Definition: pg_ctl.c:93
static void adjust_data_dir(void)
Definition: pg_ctl.c:2213
static char * register_servicename
Definition: pg_ctl.c:94
static char version_file[MAXPGPATH]
Definition: pg_ctl.c:102
static pgpid_t get_pgpid(bool is_status_request)
Definition: pg_ctl.c:249
static volatile pgpid_t postmasterPID
Definition: pg_ctl.c:108
static bool allow_core_files
Definition: pg_ctl.c:98
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:443
int main(int argc, char **argv)
Definition: pg_ctl.c:2290
static char ** readfile(const char *path, int *numlines)
Definition: pg_ctl.c:317
#define DEFAULT_WAIT
Definition: pg_ctl.c:73
static char postopts_file[MAXPGPATH]
Definition: pg_ctl.c:101
static WaitPMResult wait_for_postmaster(pgpid_t pm_pid, bool do_checkpoint)
Definition: pg_ctl.c:597
WaitPMResult
Definition: pg_ctl.c:50
@ POSTMASTER_FAILED
Definition: pg_ctl.c:53
@ POSTMASTER_READY
Definition: pg_ctl.c:51
@ POSTMASTER_STILL_STARTING
Definition: pg_ctl.c:52
static int sig
Definition: pg_ctl.c:84
#define USEC_PER_SEC
Definition: pg_ctl.c:75
static void set_mode(char *modeopt)
Definition: pg_ctl.c:2135
static char promote_file[MAXPGPATH]
Definition: pg_ctl.c:105
static char * pg_config
Definition: pg_ctl.c:87
static void do_start(void)
Definition: pg_ctl.c:861
static DBState get_control_dbstate(void)
Definition: pg_ctl.c:2271
static char backup_file[MAXPGPATH]
Definition: pg_ctl.c:104
static void do_logrotate(void)
Definition: pg_ctl.c:1265
static void do_stop(void)
Definition: pg_ctl.c:953
static char pid_file[MAXPGPATH]
Definition: pg_ctl.c:103
static char * pg_data
Definition: pg_ctl.c:86
static char * register_password
Definition: pg_ctl.c:96
static CtlCommand ctl_command
Definition: pg_ctl.c:85
static bool silent_mode
Definition: pg_ctl.c:82
ShutdownMode
Definition: pg_ctl.c:43
@ FAST_MODE
Definition: pg_ctl.c:45
@ IMMEDIATE_MODE
Definition: pg_ctl.c:46
@ SMART_MODE
Definition: pg_ctl.c:44
static void do_init(void)
Definition: pg_ctl.c:833
static char * argv0
Definition: pg_ctl.c:97
static void print_msg(const char *msg)
Definition: pg_ctl.c:239
static int wait_seconds
Definition: pg_ctl.c:80
CtlCommand
Definition: pg_ctl.c:57
@ REGISTER_COMMAND
Definition: pg_ctl.c:68
@ RUN_AS_SERVICE_COMMAND
Definition: pg_ctl.c:70
@ LOGROTATE_COMMAND
Definition: pg_ctl.c:66
@ RESTART_COMMAND
Definition: pg_ctl.c:62
@ UNREGISTER_COMMAND
Definition: pg_ctl.c:69
@ START_COMMAND
Definition: pg_ctl.c:60
@ KILL_COMMAND
Definition: pg_ctl.c:67
@ INIT_COMMAND
Definition: pg_ctl.c:59
@ STOP_COMMAND
Definition: pg_ctl.c:61
@ STATUS_COMMAND
Definition: pg_ctl.c:64
@ NO_COMMAND
Definition: pg_ctl.c:58
@ PROMOTE_COMMAND
Definition: pg_ctl.c:65
@ RELOAD_COMMAND
Definition: pg_ctl.c:63
static void do_kill(pgpid_t pid)
Definition: pg_ctl.c:1403
static bool postmaster_is_alive(pid_t pid)
Definition: pg_ctl.c:1322
static void do_restart(void)
Definition: pg_ctl.c:1040
static bool wait_seconds_arg
Definition: pg_ctl.c:81
static char * log_file
Definition: pg_ctl.c:91
static void write_stderr(const char *fmt,...) pg_attribute_printf(1
Definition: pg_ctl.c:205
static void do_promote(void)
Definition: pg_ctl.c:1171
static time_t start_time
Definition: pg_ctl.c:99
static void set_sig(char *signame)
Definition: pg_ctl.c:2163
static const char * progname
Definition: pg_ctl.c:90
static void do_status(void)
Definition: pg_ctl.c:1346
static char logrotate_file[MAXPGPATH]
Definition: pg_ctl.c:106
static char * exec_path
Definition: pg_ctl.c:92
static ShutdownMode shutdown_mode
Definition: pg_ctl.c:83
static bool do_wait
Definition: pg_ctl.c:79
static char * filename
Definition: pg_dumpall.c:92
int optind
Definition: getopt.c:50
char * optarg
Definition: getopt.c:52
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:229
#define PM_STATUS_READY
Definition: pidfile.h:53
#define PM_STATUS_STANDBY
Definition: pidfile.h:54
#define LOCK_FILE_LINE_START_TIME
Definition: pidfile.h:39
#define LOCK_FILE_LINE_PM_STATUS
Definition: pidfile.h:44
#define LOCK_FILE_LINE_PID
Definition: pidfile.h:37
#define vsnprintf
Definition: port.h:224
char * make_absolute_path(const char *path)
Definition: path.c:608
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define sprintf
Definition: port.h:227
void make_native_path(char *path)
Definition: path.c:166
void canonicalize_path(char *path)
Definition: path.c:254
const char * get_progname(const char *argv0)
Definition: path.c:453
#define strerror
Definition: port.h:238
#define snprintf
Definition: port.h:225
#define DEVNULL
Definition: port.h:156
#define PG_BACKEND_VERSIONSTR
Definition: port.h:139
#define printf(...)
Definition: port.h:231
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
char * c
static int fd(const char *x, int i)
Definition: preproc-init.c:105
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
void pg_usleep(long microsec)
Definition: signal.c:53
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:180
int pg_strip_crlf(char *str)
Definition: string.c:121
__int64 st_size
Definition: win32_port.h:273
Definition: regguts.h:318
#define SIGHUP
Definition: win32_port.h:167
#define stat
Definition: win32_port.h:283
#define SIG_DFL
Definition: win32_port.h:162
#define SIGQUIT
Definition: win32_port.h:168
BOOL AddUserToTokenDacl(HANDLE hToken)
#define kill(pid, sig)
Definition: win32_port.h:464
#define SIGUSR1
Definition: win32_port.h:179
#define fstat
Definition: win32_port.h:282
#define SIGABRT
Definition: win32_port.h:170
#define setenv(x, y, z)
Definition: win32_port.h:507
int pgwin32_is_service(void)
#define SIGUSR2
Definition: win32_port.h:180
#define SIGKILL
Definition: win32_port.h:171