va_start(ap, fmt); #ifndef WIN32 /* On Unix, we just fprintf to stderr */
vfprintf(stderr, fmt, ap); #else
/* *OnWin32,weprinttostderrifrunningonaconsole,orwriteto *eventlogifrunningasaservice
*/ if (pgwin32_is_service()) /* Running as a service */
{ char errbuf[2048]; /* Arbitrary size? */
vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
} else /* Not running as service, write to stderr */
vfprintf(stderr, fmt, ap); #endif
va_end(ap);
}
static pid_t
get_pgpid(bool is_status_request)
{
FILE *pidf; int pid; struct stat statbuf;
if (stat(pg_data, &statbuf) != 0)
{ if (errno == ENOENT)
write_stderr(_("%s: directory \"%s\" does not exist\n"), progname,
pg_data); else
write_stderr(_("%s: could not access directory \"%s\": %m\n"), progname,
pg_data);
if (stat(version_file, &statbuf) != 0 && errno == ENOENT)
{
write_stderr(_("%s: directory \"%s\" is not a database cluster directory\n"),
progname, pg_data); exit(is_status_request ? 4 : 1);
}
pidf = fopen(pid_file, "r"); if (pidf == NULL)
{ /* No pid file, not an error on startup */ if (errno == ENOENT) return0; else
{
write_stderr(_("%s: could not open PID file \"%s\": %m\n"),
progname, pid_file); exit(1);
}
} if (fscanf(pidf, "%d", &pid) != 1)
{ /* Is the file empty? */ if (ftell(pidf) == 0 && feof(pidf))
write_stderr(_("%s: the PID file \"%s\" is empty\n"),
progname, pid_file); else
write_stderr(_("%s: invalid data in PID file \"%s\"\n"),
progname, pid_file); exit(1);
}
fclose(pidf); return (pid_t) pid;
}
/* *getthelinesfromatextfile-returnNULLiffilecan'tbeopened * *Trailingnewlinesaredeletedfromthelines(thisisachangefrompre-v10) * **numlinesissettothenumberoflinepointersreturned;thereis *alsoanadditionalNULLpointerafterthelastrealline.
*/ staticchar **
readfile(constchar *path, int *numlines)
{ int fd; int nlines; char **result; char *buffer; char *linebegin; int i; int n; int len; struct stat statbuf;
*numlines = 0; /* in case of failure or empty file */
len = read(fd, buffer, statbuf.st_size + 1);
close(fd); if (len != statbuf.st_size)
{ /* oops, the file size changed between fstat and read */
free(buffer); return NULL;
}
/* *Countnewlines.Weexpecttheretobeanewlineaftereachfullline, *includingoneattheendoffile.Ifthereisn'tanewlineattheend, *anycharactersafterthelastnewlinewillbeignored.
*/
nlines = 0; for (i = 0; i < len; i++)
{ if (buffer[i] == '\n')
nlines++;
}
/* set up the result buffer */
result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
*numlines = nlines;
/* now split the buffer into lines */
linebegin = buffer;
n = 0; for (i = 0; i < len; i++)
{ if (buffer[i] == '\n')
{ int slen = &buffer[i] - linebegin; char *linebuf = pg_malloc(slen + 1);
memcpy(linebuf, linebegin, slen); /* we already dropped the \n, but get rid of any \r too */ if (slen > 0 && linebuf[slen - 1] == '\r')
slen--;
linebuf[slen] = '\0';
result[n++] = linebuf;
linebegin = &buffer[i + 1];
}
}
result[n] = NULL;
free(buffer);
return result;
}
/* *Freememoryallocatedforoptlinesthroughreadfile()
*/ staticvoid
free_readfile(char **optlines)
{ char *curr_line = NULL; int i = 0;
if (!optlines) return;
while ((curr_line = optlines[i++]))
free(curr_line);
/* Flush stdio channels just before fork, to avoid double-output problems */
fflush(NULL);
#ifdef EXEC_BACKEND
pg_disable_aslr(); #endif
pm_pid = fork(); if (pm_pid < 0)
{ /* fork failed */
write_stderr(_("%s: could not start server: %m\n"),
progname); exit(1);
} if (pm_pid > 0)
{ /* fork succeeded, in parent */ return pm_pid;
}
/* fork succeeded, in child */
/* *Ifpossible,detachthepostmasterprocessfromthelaunchingprocess *groupandmakeitagroupleader,sothatitdoesn'tgetsignaledalong *withthecurrentgroupthatlaunchedit.
*/ #ifdef HAVE_SETSID if (setsid() < 0)
{
write_stderr(_("%s: could not start server due to setsid() failure: %m\n"),
progname); exit(1);
} #endif
pm_died = (waitpid(pm_pid, &exitstatus, WNOHANG) == pm_pid); #else
pm_died = (WaitForSingleObject(postmasterProcess, 0) == WAIT_OBJECT_0); #endif if (pm_died)
{ /* See if postmaster terminated intentionally */ if (get_control_dbstate() == DB_SHUTDOWNED_IN_RECOVERY) return POSTMASTER_SHUTDOWN_IN_RECOVERY; else return POSTMASTER_FAILED;
}
}
/* Startup still in process; wait, printing a dot once per second */ if (i % WAITS_PER_SEC == 0)
{ #ifdef WIN32 if (do_checkpoint)
{ /* *Incrementthewaithintby6secs(connectiontimeout+ *sleep).WemustdothistoindicatetotheSCMthatour *startuptimeischanging,otherwiseit'llusuallysenda *stopsignalafter20seconds,despiteincrementingthe *checkpointcounter.
*/
status.dwWaitHint += 6000;
status.dwCheckPoint++;
SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
} else #endif
print_msg(".");
}
pg_usleep(USEC_PER_SEC / WAITS_PER_SEC);
}
/* out of patience; report that postmaster is still starting up */ return POSTMASTER_STILL_STARTING;
}
getrlimit(RLIMIT_CORE, &lim); if (lim.rlim_max == 0)
{
write_stderr(_("%s: cannot set core file size limit; disallowed by hard limit\n"),
progname); return;
} elseif (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
{
lim.rlim_cur = lim.rlim_max;
setrlimit(RLIMIT_CORE, &lim);
}
} #endif
staticvoid
read_post_opts(void)
{ if (post_opts == NULL)
{
post_opts = ""; /* default */ if (ctl_command == RESTART_COMMAND)
{ char **optlines; int numlines;
optlines = readfile(postopts_file, &numlines); if (optlines == NULL)
{
write_stderr(_("%s: could not read file \"%s\"\n"), progname, postopts_file); exit(1);
} elseif (numlines != 1)
{
write_stderr(_("%s: option file \"%s\" must have exactly one line\n"),
progname, postopts_file); exit(1);
} else
{ char *optline; char *arg1;
optline = optlines[0];
/* *Areweatthefirstoption,asdefinedbyspaceand *double-quote?
*/ if ((arg1 = strstr(optline, " \"")) != NULL)
{
*arg1 = '\0'; /* terminate so we get only program name */
post_opts = pg_strdup(arg1 + 1); /* point past whitespace */
} if (exec_path == NULL)
exec_path = pg_strdup(optline);
}
/* Free the results of readfile. */
free_readfile(optlines);
}
}
}
/* *SIGINTsignalhandlerusedwhilewaitingforpostmastertostartup. *ForwardstheSIGINTtothepostmasterprocess,askingittoshutdown, *beforeterminatingpg_ctlitself.Thisway,iftheuserhitsCTRL-Cwhile *waitingfortheservertostartup,theserverlaunchisaborted.
*/ staticvoid
trap_sigint_during_startup(SIGNAL_ARGS)
{ if (postmasterPID != -1)
{ if (kill(postmasterPID, SIGINT) != 0)
write_stderr(_("%s: could not send stop signal (PID: %d): %m\n"),
progname, (int) postmasterPID);
}
if (find_my_exec(argv0, full_path) < 0)
strlcpy(full_path, progname, sizeof(full_path));
if (ret == -1)
write_stderr(_("program \"%s\" is needed by %s but was not found in the same directory as \"%s\"\n"),
target, progname, full_path); else
write_stderr(_("program \"%s\" was found by \"%s\" but was not the same version as %s\n"),
target, full_path, progname); exit(1);
}
if (ctl_command != RESTART_COMMAND)
{
old_pid = get_pgpid(false); if (old_pid != 0)
write_stderr(_("%s: another server might be running; " "trying to start server anyway\n"),
progname);
}
read_post_opts();
/* No -D or -D already added during server start */ if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
pgdata_opt = "";
if (exec_path == NULL)
exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
#ifdefined(HAVE_GETRLIMIT) if (allow_core_files)
unlimit_core_size(); #endif
switch (wait_for_postmaster_start(pm_pid, false))
{ case POSTMASTER_READY:
print_msg(_(" done\n"));
print_msg(_("server started\n")); break; case POSTMASTER_STILL_STARTING:
print_msg(_(" stopped waiting\n"));
write_stderr(_("%s: server did not start in time\n"),
progname); exit(1); break; case POSTMASTER_SHUTDOWN_IN_RECOVERY:
print_msg(_(" done\n"));
print_msg(_("server shut down because of recovery target settings\n")); break; case POSTMASTER_FAILED:
print_msg(_(" stopped waiting\n"));
write_stderr(_("%s: could not start server\n" "Examine the log output.\n"),
progname); exit(1); break;
}
} else
print_msg(_("server starting\n"));
#ifdef WIN32 /* Now we don't need the handle to the shell process anymore */
CloseHandle(postmasterProcess);
postmasterProcess = INVALID_HANDLE_VALUE; #endif
}
staticvoid
do_stop(void)
{
pid_t pid;
pid = get_pgpid(false);
if (pid == 0) /* no pid file */
{
write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
write_stderr(_("Is server running?\n")); exit(1);
} elseif (pid < 0) /* standalone backend, not postmaster */
{
pid = -pid;
write_stderr(_("%s: cannot stop server; " "single-user server is running (PID: %d)\n"),
progname, (int) pid); exit(1);
}
if (kill(pid, sig) != 0)
{
write_stderr(_("%s: could not send stop signal (PID: %d): %m\n"), progname, (int) pid); exit(1);
}
if (!do_wait)
{
print_msg(_("server shutting down\n")); return;
} else
{
print_msg(_("waiting for server to shut down..."));
if (!wait_for_postmaster_stop())
{
print_msg(_(" failed\n"));
write_stderr(_("%s: server does not shut down\n"), progname); if (shutdown_mode == SMART_MODE)
write_stderr(_("HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n")); exit(1);
}
print_msg(_(" done\n"));
print_msg(_("server stopped\n"));
}
}
/* *restart/reloadroutines
*/
staticvoid
do_restart(void)
{
pid_t pid;
pid = get_pgpid(false);
if (pid == 0) /* no pid file */
{
write_stderr(_("%s: PID file \"%s\" does not exist\n"),
progname, pid_file);
write_stderr(_("Is server running?\n"));
write_stderr(_("trying to start server anyway\n"));
do_start(); return;
} elseif (pid < 0) /* standalone backend, not postmaster */
{
pid = -pid; if (postmaster_is_alive(pid))
{
write_stderr(_("%s: cannot restart server; " "single-user server is running (PID: %d)\n"),
progname, (int) pid);
write_stderr(_("Please terminate the single-user server and try again.\n")); exit(1);
}
}
if (postmaster_is_alive(pid))
{ if (kill(pid, sig) != 0)
{
write_stderr(_("%s: could not send stop signal (PID: %d): %m\n"), progname, (int) pid); exit(1);
}
print_msg(_("waiting for server to shut down..."));
/* always wait for restart */ if (!wait_for_postmaster_stop())
{
print_msg(_(" failed\n"));
write_stderr(_("%s: server does not shut down\n"), progname); if (shutdown_mode == SMART_MODE)
write_stderr(_("HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n")); exit(1);
}
print_msg(_(" done\n"));
print_msg(_("server stopped\n"));
} else
{
write_stderr(_("%s: old server process (PID: %d) seems to be gone\n"),
progname, (int) pid);
write_stderr(_("starting server anyway\n"));
}
do_start();
}
staticvoid
do_reload(void)
{
pid_t pid;
pid = get_pgpid(false); if (pid == 0) /* no pid file */
{
write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
write_stderr(_("Is server running?\n")); exit(1);
} elseif (pid < 0) /* standalone backend, not postmaster */
{
pid = -pid;
write_stderr(_("%s: cannot reload server; " "single-user server is running (PID: %d)\n"),
progname, (int) pid);
write_stderr(_("Please terminate the single-user server and try again.\n")); exit(1);
}
if (kill(pid, sig) != 0)
{
write_stderr(_("%s: could not send reload signal (PID: %d): %m\n"),
progname, (int) pid); exit(1);
}
if (pid == 0) /* no pid file */
{
write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
write_stderr(_("Is server running?\n")); exit(1);
} elseif (pid < 0) /* standalone backend, not postmaster */
{
pid = -pid;
write_stderr(_("%s: cannot promote server; " "single-user server is running (PID: %d)\n"),
progname, (int) pid); exit(1);
}
if (get_control_dbstate() != DB_IN_ARCHIVE_RECOVERY)
{
write_stderr(_("%s: cannot promote server; " "server is not in standby mode\n"),
progname); exit(1);
}
if ((prmfile = fopen(promote_file, "w")) == NULL)
{
write_stderr(_("%s: could not create promote signal file \"%s\": %m\n"),
progname, promote_file); exit(1);
} if (fclose(prmfile))
{
write_stderr(_("%s: could not write promote signal file \"%s\": %m\n"),
progname, promote_file); exit(1);
}
sig = SIGUSR1; if (kill(pid, sig) != 0)
{
write_stderr(_("%s: could not send promote signal (PID: %d): %m\n"),
progname, (int) pid); if (unlink(promote_file) != 0)
write_stderr(_("%s: could not remove promote signal file \"%s\": %m\n"),
progname, promote_file); exit(1);
}
if (do_wait)
{
print_msg(_("waiting for server to promote...")); if (wait_for_postmaster_promote())
{
print_msg(_(" done\n"));
print_msg(_("server promoted\n"));
} else
{
print_msg(_(" stopped waiting\n"));
write_stderr(_("%s: server did not promote in time\n"),
progname); exit(1);
}
} else
print_msg(_("server promoting\n"));
}
if ((logrotatefile = fopen(logrotate_file, "w")) == NULL)
{
write_stderr(_("%s: could not create log rotation signal file \"%s\": %m\n"),
progname, logrotate_file); exit(1);
} if (fclose(logrotatefile))
{
write_stderr(_("%s: could not write log rotation signal file \"%s\": %m\n"),
progname, logrotate_file); exit(1);
}
sig = SIGUSR1; if (kill(pid, sig) != 0)
{
write_stderr(_("%s: could not send log rotation signal (PID: %d): %m\n"),
progname, (int) pid); if (unlink(logrotate_file) != 0)
write_stderr(_("%s: could not remove log rotation signal file \"%s\": %m\n"),
progname, logrotate_file); exit(1);
}
print_msg(_("server signaled to rotate log file\n"));
}
pid = get_pgpid(true); /* Is there a pid file? */ if (pid != 0)
{ /* standalone backend? */ if (pid < 0)
{
pid = -pid; if (postmaster_is_alive(pid))
{
printf(_("%s: single-user server is running (PID: %d)\n"),
progname, (int) pid); return;
}
} else /* must be a postmaster */
{ if (postmaster_is_alive(pid))
{ char **optlines; char **curr_line; int numlines;
printf(_("%s: server is running (PID: %d)\n"),
progname, (int) pid);
optlines = readfile(postopts_file, &numlines); if (optlines != NULL)
{ for (curr_line = optlines; *curr_line != NULL; curr_line++)
puts(*curr_line);
/* Free the results of readfile */
free_readfile(optlines);
} return;
}
}
}
printf(_("%s: no server running\n"), progname);
if (registration)
{
ret = find_my_exec(argv0, cmdPath); if (ret != 0)
{
write_stderr(_("%s: could not find own program executable\n"), progname); exit(1);
}
} else
{
ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
cmdPath); if (ret != 0)
{
write_stderr(_("%s: could not find postgres program executable\n"), progname); exit(1);
}
}
/* if path does not end in .exe, append it */ if (strlen(cmdPath) < 4 ||
pg_strcasecmp(cmdPath + strlen(cmdPath) - 4, ".exe") != 0)
snprintf(cmdPath + strlen(cmdPath), sizeof(cmdPath) - strlen(cmdPath), ".exe");
/* use backslashes in path to avoid problems with some third-party tools */
make_native_path(cmdPath);
/* be sure to double-quote the executable's name in the command */
appendPQExpBuffer(cmdLine, "\"%s\"", cmdPath);
/* append assorted switches to the command line, as needed */
if (registration)
appendPQExpBuffer(cmdLine, " runservice -N \"%s\"",
register_servicename);
if (pg_config)
{ /* We need the -D path to be absolute */ char *dataDir;
if (registration && do_wait)
appendPQExpBufferStr(cmdLine, " -w");
/* Don't propagate a value from an environment variable. */ if (registration && wait_seconds_arg && wait_seconds != DEFAULT_WAIT)
appendPQExpBuffer(cmdLine, " -t %d", wait_seconds);
if (registration && silent_mode)
appendPQExpBufferStr(cmdLine, " -s");
if (post_opts)
{ if (registration)
appendPQExpBuffer(cmdLine, " -o \"%s\"", post_opts); else
appendPQExpBuffer(cmdLine, " %s", post_opts);
}
if (hSCM == NULL)
{
write_stderr(_("%s: could not open service manager\n"), progname); exit(1);
} if (pgwin32_IsInstalled(hSCM))
{
CloseServiceHandle(hSCM);
write_stderr(_("%s: service \"%s\" already registered\n"), progname, register_servicename); exit(1);
}
if ((hService = CreateService(hSCM, register_servicename, register_servicename,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
pgctl_start_type, SERVICE_ERROR_NORMAL,
pgwin32_CommandLine(true),
NULL, NULL, "RPCSS\0", register_username, register_password)) == NULL)
{
CloseServiceHandle(hSCM);
write_stderr(_("%s: could not register service \"%s\": error code %lu\n"),
progname, register_servicename,
(unsignedlong) GetLastError()); exit(1);
}
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
}
if (hSCM == NULL)
{
write_stderr(_("%s: could not open service manager\n"), progname); exit(1);
} if (!pgwin32_IsInstalled(hSCM))
{
CloseServiceHandle(hSCM);
write_stderr(_("%s: service \"%s\" not registered\n"), progname, register_servicename); exit(1);
}
if ((hService = OpenService(hSCM, register_servicename, DELETE)) == NULL)
{
CloseServiceHandle(hSCM);
write_stderr(_("%s: could not open service \"%s\": error code %lu\n"),
progname, register_servicename,
(unsignedlong) GetLastError()); exit(1);
} if (!DeleteService(hService))
{
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
write_stderr(_("%s: could not unregister service \"%s\": error code %lu\n"),
progname, register_servicename,
(unsignedlong) GetLastError()); exit(1);
}
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
}
if (do_wait)
{
write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Waiting for server startup...\n")); if (wait_for_postmaster_start(postmasterPID, true) != POSTMASTER_READY)
{
write_eventlog(EVENTLOG_ERROR_TYPE, _("Timed out waiting for server startup\n"));
pgwin32_SetServiceStatus(SERVICE_STOPPED); return;
}
write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Server started and accepting connections\n"));
}
pgwin32_SetServiceStatus(SERVICE_RUNNING);
/* Wait for quit... */
ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);
/* Open the current token to use as a base for the restricted one */ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
{ /* *MostWindowstargetsmakeDWORDa32-bitunsignedlong,butincase *itdoesn'tcastDWORDbeforeprinting.
*/
write_stderr(_("%s: could not open process token: error code %lu\n"),
progname, (unsignedlong) GetLastError()); return0;
}
/* Allocate list of SIDs to remove */
ZeroMemory(&dropSids, sizeof(dropSids)); if (!AllocateAndInitializeSid(&NtAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &dropSids[0].Sid) ||
!AllocateAndInitializeSid(&NtAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, 0, &dropSids[1].Sid))
{
write_stderr(_("%s: could not allocate SIDs: error code %lu\n"),
progname, (unsignedlong) GetLastError()); return0;
}
/* Get list of privileges to remove */
delPrivs = GetPrivilegesToDelete(origToken); if (delPrivs == NULL) /* Error message already printed */ return0;
if (!LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &luidLockPages) ||
!LookupPrivilegeValue(NULL, SE_CHANGE_NOTIFY_NAME, &luidChangeNotify))
{
write_stderr(_("%s: could not get LUIDs for privileges: error code %lu\n"),
progname, (unsignedlong) GetLastError()); return NULL;
}
if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &length) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
write_stderr(_("%s: could not get token information: error code %lu\n"),
progname, (unsignedlong) GetLastError()); return NULL;
}
tokenPrivs = (PTOKEN_PRIVILEGES) pg_malloc_extended(length,
MCXT_ALLOC_NO_OOM); if (tokenPrivs == NULL)
{
write_stderr(_("%s: out of memory\n"), progname); return NULL;
}
if (!GetTokenInformation(hToken, TokenPrivileges, tokenPrivs, length, &length))
{
write_stderr(_("%s: could not get token information: error code %lu\n"),
progname, (unsignedlong) GetLastError());
free(tokenPrivs); return NULL;
}
for (i = 0; i < tokenPrivs->PrivilegeCount; i++)
{ if (memcmp(&tokenPrivs->Privileges[i].Luid, &luidLockPages, sizeof(LUID)) == 0 ||
memcmp(&tokenPrivs->Privileges[i].Luid, &luidChangeNotify, sizeof(LUID)) == 0)
{ for (j = i; j < tokenPrivs->PrivilegeCount - 1; j++)
tokenPrivs->Privileges[j] = tokenPrivs->Privileges[j + 1];
tokenPrivs->PrivilegeCount--;
}
}
return tokenPrivs;
} #endif/* WIN32 */
staticvoid
do_advice(void)
{
write_stderr(_("Try \"%s --help\" for more information.\n"), progname);
}
printf(_("\nCommon options:\n"));
printf(_(" -D, --pgdata=DATADIR location of the database storage area\n")); #ifdef WIN32
printf(_(" -e SOURCE event source for logging when running as a service\n")); #endif
printf(_(" -s, --silent only print errors, no informational messages\n"));
printf(_(" -t, --timeout=SECS seconds to wait when using -w option\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -w, --wait wait until operation completes (default)\n"));
printf(_(" -W, --no-wait do not wait until operation completes\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
printf(_("\nOptions for start or restart:\n")); #ifdefined(HAVE_GETRLIMIT)
printf(_(" -c, --core-files allow postgres to produce core files\n")); #else
printf(_(" -c, --core-files not applicable on this platform\n")); #endif
printf(_(" -l, --log=FILENAME write (or append) server log to FILENAME\n"));
printf(_(" -o, --options=OPTIONS command line options to pass to postgres\n" " (PostgreSQL server executable) or initdb\n"));
printf(_(" -p PATH-TO-POSTGRES normally not necessary\n"));
printf(_("\nOptions for stop or restart:\n"));
printf(_(" -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n"));
printf(_("\nShutdown modes are:\n"));
printf(_(" smart quit after all clients have disconnected\n"));
printf(_(" fast quit directly, with proper shutdown (default)\n"));
printf(_(" immediate quit without complete shutdown; will lead to recovery on restart\n"));
printf(_("\nAllowed signal names for kill:\n"));
printf(" ABRT HUP INT KILL QUIT TERM USR1 USR2\n");
#ifdef WIN32
printf(_("\nOptions for register and unregister:\n"));
printf(_(" -N SERVICENAME service name with which to register PostgreSQL server\n"));
printf(_(" -P PASSWORD password of account to register PostgreSQL server\n"));
printf(_(" -U USERNAME user name of account to register PostgreSQL server\n"));
printf(_(" -S START-TYPE service start type to register PostgreSQL server\n"));
printf(_("\nStart types are:\n"));
printf(_(" auto start service automatically during system startup (default)\n"));
printf(_(" demand start service on demand\n")); #endif
printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
}
/* do nothing if we're working without knowledge of data dir */ if (pg_config == NULL) return;
/* If there is no postgresql.conf, it can't be a config-only dir */
snprintf(filename, sizeof(filename), "%s/postgresql.conf", pg_config); if ((fd = fopen(filename, "r")) == NULL) return;
fclose(fd);
/* If PG_VERSION exists, it can't be a config-only dir */
snprintf(filename, sizeof(filename), "%s/PG_VERSION", pg_config); if ((fd = fopen(filename, "r")) != NULL)
{
fclose(fd); return;
}
/* Must be a configuration directory, so find the data directory */
/* we use a private my_exec_path to avoid interfering with later uses */ if (exec_path == NULL)
my_exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR); else
my_exec_path = pg_strdup(exec_path);
/* it's important for -C to be the first option, see main.c */
cmd = psprintf("\"%s\" -C data_directory %s%s",
my_exec_path,
pgdata_opt ? pgdata_opt : "",
post_opts ? post_opts : "");
fflush(NULL);
fd = popen(cmd, "r"); if (fd == NULL || fgets(filename, sizeof(filename), fd) == NULL || pclose(fd) != 0)
{
write_stderr(_("%s: could not determine the data directory using command \"%s\"\n"), progname, cmd); exit(1);
}
free(my_exec_path);
/* strip trailing newline and carriage return */
(void) pg_strip_crlf(filename);
/* Set restrictive mode mask until PGDATA permissions are checked */
umask(PG_MODE_MASK_OWNER);
/* support --help and --version even if invoked as root */ if (argc > 1)
{ if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
{
do_help(); exit(0);
} elseif (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
{
puts("pg_ctl (PostgreSQL) " PG_VERSION); exit(0);
}
}
/* *Disallowrunningasroot,toforestallanypossiblesecurityholes.
*/ #ifndef WIN32 if (geteuid() == 0)
{
write_stderr(_("%s: cannot be run as root\n" "Please log in (using, e.g., \"su\") as the " "(unprivileged) user that will\n" "own the server process.\n"),
progname); exit(1);
} #endif
env_wait = getenv("PGCTLTIMEOUT"); if (env_wait != NULL)
wait_seconds = atoi(env_wait);
if (optind < argc)
{
write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]);
do_advice(); exit(1);
}
if (ctl_command == NO_COMMAND)
{
write_stderr(_("%s: no operation specified\n"), progname);
do_advice(); exit(1);
}
/* Note we put any -D switch into the env var above */
pg_config = getenv("PGDATA"); if (pg_config)
{
pg_config = pg_strdup(pg_config);
canonicalize_path(pg_config);
pg_data = pg_strdup(pg_config);
}
/* -D might point at config-only directory; if so find the real PGDATA */
adjust_data_dir();
/* Complain if -D needed and not provided */ if (pg_config == NULL &&
ctl_command != KILL_COMMAND && ctl_command != UNREGISTER_COMMAND)
{
write_stderr(_("%s: no database directory specified and environment variable PGDATA unset\n"),
progname);
do_advice(); exit(1);
}
if (ctl_command == RELOAD_COMMAND)
{
sig = SIGHUP;
do_wait = false;
}
switch (ctl_command)
{ case INIT_COMMAND:
do_init(); break; case STATUS_COMMAND:
do_status(); break; case START_COMMAND:
do_start(); break; case STOP_COMMAND:
do_stop(); break; case RESTART_COMMAND:
do_restart(); break; case RELOAD_COMMAND:
do_reload(); break; case PROMOTE_COMMAND:
do_promote(); break; case LOGROTATE_COMMAND:
do_logrotate(); break; case KILL_COMMAND:
do_kill(killproc); break; #ifdef WIN32 case REGISTER_COMMAND:
pgwin32_doRegister(); break; case UNREGISTER_COMMAND:
pgwin32_doUnregister(); break; case RUN_AS_SERVICE_COMMAND:
pgwin32_doRunAsService(); break; #endif default: break;
}
exit(0);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.42 Sekunden
(vorverarbeitet am 2026-08-07)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.