aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/ref/postgres-ref.sgml14
-rw-r--r--src/backend/main/main.c1
-rw-r--r--src/backend/postmaster/postmaster.c15
-rw-r--r--src/backend/tcop/postgres.c8
-rw-r--r--src/bin/pg_ctl/pg_ctl.c72
5 files changed, 100 insertions, 10 deletions
diff --git a/doc/src/sgml/ref/postgres-ref.sgml b/doc/src/sgml/ref/postgres-ref.sgml
index b16bbdfa4b3..3807f4090a8 100644
--- a/doc/src/sgml/ref/postgres-ref.sgml
+++ b/doc/src/sgml/ref/postgres-ref.sgml
@@ -141,6 +141,20 @@ PostgreSQL documentation
</varlistentry>
<varlistentry>
+ <term><option>-C <replaceable>name</replaceable></option></term>
+ <listitem>
+ <para>
+ Returns the value of a named run-time parameter, and exits.
+ (See the <option>-c</> option above for details.) This can
+ be used on a running server, and returns values from
+ <filename>postgresql.conf</>, modified by any parameters
+ supplied in this invocation. It does not reflect parameters
+ supplied when the cluster was started.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-d <replaceable>debug-level</replaceable></option></term>
<listitem>
<para>
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index 8d9cb9428df..b14c7318ab2 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -283,6 +283,7 @@ help(const char *progname)
#endif
printf(_(" -B NBUFFERS number of shared buffers\n"));
printf(_(" -c NAME=VALUE set run-time parameter\n"));
+ printf(_(" -C NAME return run-time parameter\n"));
printf(_(" -d 1-5 debugging level\n"));
printf(_(" -D DATADIR database directory\n"));
printf(_(" -e use European date input format (DMY)\n"));
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 0a84d97f517..dd7493cf9dd 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -203,6 +203,8 @@ bool enable_bonjour = false;
char *bonjour_name;
bool restart_after_crash = true;
+char *output_config_variable = NULL;
+
/* PIDs of special child processes; 0 when not running */
static pid_t StartupPID = 0,
BgWriterPID = 0,
@@ -537,7 +539,7 @@ PostmasterMain(int argc, char *argv[])
* tcop/postgres.c (the option sets should not conflict) and with the
* common help() function in main/main.c.
*/
- while ((opt = getopt(argc, argv, "A:B:bc:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:W:-:")) != -1)
+ while ((opt = getopt(argc, argv, "A:B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:W:-:")) != -1)
{
switch (opt)
{
@@ -554,6 +556,10 @@ PostmasterMain(int argc, char *argv[])
IsBinaryUpgrade = true;
break;
+ case 'C':
+ output_config_variable = optarg;
+ break;
+
case 'D':
userDoption = optarg;
break;
@@ -728,6 +734,13 @@ PostmasterMain(int argc, char *argv[])
if (!SelectConfigFiles(userDoption, progname))
ExitPostmaster(2);
+ if (output_config_variable != NULL)
+ {
+ /* permission is handled because the user is reading inside the data dir */
+ puts(GetConfigOption(output_config_variable, false, false));
+ ExitPostmaster(0);
+ }
+
/* Verify that DataDir looks reasonable */
checkDataDir();
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index c7eac71e91e..19d94b252c2 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -3170,7 +3170,7 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx)
* postmaster/postmaster.c (the option sets should not conflict) and with
* the common help() function in main/main.c.
*/
- while ((flag = getopt(argc, argv, "A:B:bc:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:v:W:-:")) != -1)
+ while ((flag = getopt(argc, argv, "A:B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:v:W:-:")) != -1)
{
switch (flag)
{
@@ -3187,6 +3187,10 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx)
IsBinaryUpgrade = true;
break;
+ case 'C':
+ /* ignored for consistency with the postmaster */
+ break;
+
case 'D':
if (secure)
userDoption = strdup(optarg);
@@ -3272,7 +3276,7 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx)
break;
case 'T':
- /* ignored for consistency with postmaster */
+ /* ignored for consistency with the postmaster */
break;
case 't':
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 0dbdfe7312c..e633d0c18fe 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -81,6 +81,7 @@ static ShutdownMode shutdown_mode = SMART_MODE;
static int sig = SIGTERM; /* default */
static CtlCommand ctl_command = NO_COMMAND;
static char *pg_data = NULL;
+static char *pg_config = NULL;
static char *pgdata_opt = NULL;
static char *post_opts = NULL;
static const char *progname;
@@ -131,6 +132,7 @@ static void do_status(void);
static void do_promote(void);
static void do_kill(pgpid_t pid);
static void print_msg(const char *msg);
+static void adjust_data_dir(void);
#if defined(WIN32) || defined(__CYGWIN__)
static bool pgwin32_IsInstalled(SC_HANDLE);
@@ -1265,10 +1267,10 @@ pgwin32_CommandLine(bool registration)
strcat(cmdLine, "\"");
}
- if (pg_data)
+ if (pg_config)
{
strcat(cmdLine, " -D \"");
- strcat(cmdLine, pg_data);
+ strcat(cmdLine, pg_config);
strcat(cmdLine, "\"");
}
@@ -1886,6 +1888,59 @@ set_starttype(char *starttypeopt)
}
#endif
+/*
+ * adjust_data_dir
+ *
+ * If a configuration-only directory was specified, find the real data dir.
+ */
+void
+adjust_data_dir(void)
+{
+ char cmd[MAXPGPATH], filename[MAXPGPATH], *my_exec_path;
+ FILE *fd;
+
+ /* 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 = xstrdup(exec_path);
+
+ snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s -C data_directory" SYSTEMQUOTE,
+ my_exec_path, pgdata_opt ? pgdata_opt : "", post_opts ?
+ post_opts : "");
+
+ fd = popen(cmd, "r");
+ if (fd == NULL || fgets(filename, sizeof(filename), fd) == NULL)
+ {
+ write_stderr(_("%s: cannot find the data directory using %s\n"), progname, my_exec_path);
+ exit(1);
+ }
+ pclose(fd);
+ free(my_exec_path);
+
+ if (strlen(filename) > 0 && filename[strlen(filename) - 1] == '\n')
+ filename[strlen(filename) - 1] = '\0';
+ free(pg_data);
+ pg_data = xstrdup(filename);
+ canonicalize_path(pg_data);
+}
+
int
main(int argc, char **argv)
@@ -2120,14 +2175,17 @@ main(int argc, char **argv)
}
/* Note we put any -D switch into the env var above */
- pg_data = getenv("PGDATA");
- if (pg_data)
+ pg_config = getenv("PGDATA");
+ if (pg_config)
{
- pg_data = xstrdup(pg_data);
- canonicalize_path(pg_data);
+ pg_config = xstrdup(pg_config);
+ canonicalize_path(pg_config);
+ pg_data = xstrdup(pg_config);
}
- if (pg_data == NULL &&
+ adjust_data_dir();
+
+ 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"),