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