diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index f6946a08e18799a1d3639bff01e3330825ba0a47..da1d0745470cc08d5789e7afb25f3b66e01b9ddc 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.286 2004/10/08 01:36:31 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.287 2004/10/09 23:12:53 tgl Exp $
 -->
 
 <Chapter Id="runtime">
@@ -568,8 +568,8 @@ SET ENABLE_SEQSCAN TO OFF;
     <title>File Locations</title>
 
      <variablelist>
-     <varlistentry id="guc-pgdata" xreflabel="pgdata">
-      <term><varname>pgdata</varname> (<type>string</type>)</term>
+     <varlistentry id="guc-data-directory" xreflabel="data-directory">
+      <term><varname>data_directory</varname> (<type>string</type>)</term>
       <listitem>
        <para>
          Specifies the directory to use for data storage.
@@ -578,36 +578,45 @@ SET ENABLE_SEQSCAN TO OFF;
       </listitem>
      </varlistentry>
 
-     <varlistentry id="guc-hba-conf" xreflabel="hba-conf">
-      <term><varname>hba_conf</varname> (<type>string</type>)</term>
+     <varlistentry id="guc-config-file" xreflabel="config-file">
+      <term><varname>config_file</varname> (<type>string</type>)</term>
       <listitem>
        <para>
-         Specifies the file name to use for configuration of host-based 
-         authentication (HBA).
-         This option can only be set at server start or in the
-         <filename>postgresql.conf</filename> file.
+         Specifies the main server configuration file
+	 (customarily called <filename>postgresql.conf</>).
+         This option can only be set on the postmaster command line.
        </para>
       </listitem>
      </varlistentry>
 
-     <varlistentry id="guc-ident-conf" xreflabel="ident-conf">
-      <term><varname>ident_conf</varname> (<type>string</type>)</term>
+     <varlistentry id="guc-hba-file" xreflabel="hba-file">
+      <term><varname>hba_file</varname> (<type>string</type>)</term>
       <listitem>
        <para>
-         Specifies the file name to use for configuration of 
+         Specifies the configuration file for host-based authentication.
+         This option can only be set at server start.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry id="guc-ident-file" xreflabel="ident-file">
+      <term><varname>ident_file</varname> (<type>string</type>)</term>
+      <listitem>
+       <para>
+         Specifies the configuration file for
          <application>ident</> authentication.
-         This option can only be set at server start or in the
-         <filename>postgresql.conf</filename> file.
+         This option can only be set at server start.
        </para>
       </listitem>
      </varlistentry>
 
-     <varlistentry id="external-pidfile" xreflabel="external-pidfile">
-      <term><varname>external_pidfile</varname> (<type>string</type>)</term>
+     <varlistentry id="external-pid-file" xreflabel="external-pid-file">
+      <term><varname>external_pid_file</varname> (<type>string</type>)</term>
       <listitem>
        <para>
-         Specifies the location of an additional <application>postmaster</>
-         process-id (PID) file for use by server administration programs.
+         Specifies that the <application>postmaster</> should create an
+	 additional process-id (PID) file for use by server administration
+	 programs.
          This option can only be set at server start.
        </para>
       </listitem>
@@ -616,11 +625,10 @@ SET ENABLE_SEQSCAN TO OFF;
 
      <para>
       In a default installation, none of the above options is set explicitly
-      in the <filename>postgresql.conf</filename> file.  In this case, the
+      in the <filename>postgresql.conf</filename> file.  Instead, the
       data directory is specified by the <option>-D</option> command-line
-      option or the <envar>PGDATA</envar> environment variable; there is no
-      default for it.  The configuration files are all placed within the
-      data directory.
+      option or the <envar>PGDATA</envar> environment variable, and the
+      configuration files are all placed within the data directory.
      </para>
 
      <para>
@@ -630,27 +638,29 @@ SET ENABLE_SEQSCAN TO OFF;
       when they are kept separate.)  To do this, the <option>-D</option>
       command-line option or <envar>PGDATA</envar> environment variable
       must point to the directory containing the configuration files,
-      and the <varname>pgdata</> option is set in
+      and the <varname>data_directory</> option is set in
       <filename>postgresql.conf</filename> (or on the command line) to show
-      where the data directory is actually located.
+      where the data directory is actually located.  Notice that
+      <varname>data_directory</> overrides <option>-D</option> for the location
+      of the data directory, but not for the location of the configuration
+      files.
      </para>
 
      <para>
-      If you wish, you can also make the <option>-D</option>
-      command-line option or <envar>PGDATA</envar> environment variable
-      point directly to the master configuration file (which then need not be
-      named <filename>postgresql.conf</filename>).  The <varname>pgdata</>
-      option must be set to determine the data directory location.
-      The other configuration files will by default be sought
-      in the data directory.
+      If you wish, you can specify the configuration file names and locations
+      individually using the options <varname>config_file</>,
+      <varname>hba_file</> and/or <varname>ident_file</>.
+      <varname>config_file</> can only be specified on the 
+      <command>postmaster</command> command line, but the others can be
+      set within the main configuration file.  If all three options plus
+      <varname>data_directory</> are explicitly set, then it is not necessary
+      to specify <option>-D</option> or <envar>PGDATA</envar>.
      </para>
 
      <para>
-      With any of these approaches, you can specify the locations of the
-      secondary configuration files (<filename>pg_hba.conf</> and
-      <filename>pg_ident.conf</>) by setting <varname>hba_conf</> and/or
-      <varname>ident_conf</> in the master configuration file.  These options
-      override the normal locations and names of the secondary files.
+      When setting any of these options, a relative path will be interpreted
+      with respect to the directory in which the <command>postmaster</command>
+      is started.
      </para>
    </sect2>
 
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 0699868bfab1b00d6f976968f54a1599d05175a1..1e73efbcdfaa8f4981f3f152ed5f5c3458ed022d 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.131 2004/10/08 01:36:34 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.132 2004/10/09 23:12:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,12 +44,6 @@
 /* Standard TCP port number for Ident service.	Assigned by IANA */
 #define IDENT_PORT 113
 
-/* Name of the config file	*/
-#define CONF_FILE "pg_hba.conf"
-
-/* Name of the usermap file */
-#define USERMAP_FILE "pg_ident.conf"
-
 /* This is used to separate values in multi-valued column strings */
 #define MULTI_VALUE_SEP "\001"
 
@@ -65,11 +59,11 @@
  * one token, since blank lines are not entered in the data structure.
  */
 
-/* pre-parsed content of CONF_FILE and corresponding line #s */
+/* pre-parsed content of HBA config file and corresponding line #s */
 static List *hba_lines = NIL;
 static List *hba_line_nums = NIL;
 
-/* pre-parsed content of USERMAP_FILE and corresponding line #s */
+/* pre-parsed content of ident usermap file and corresponding line #s */
 static List *ident_lines = NIL;
 static List *ident_line_nums = NIL;
 
@@ -743,8 +737,9 @@ parse_hba(List *line, int line_num, hbaPort *port,
 		{
 			ereport(LOG,
 					(errcode(ERRCODE_CONFIG_FILE_ERROR),
-					 errmsg("invalid IP address \"%s\" in pg_hba.conf file line %d: %s",
-							token, line_num, gai_strerror(ret))));
+					 errmsg("invalid IP address \"%s\" in \"%s\" line %d: %s",
+							token, HbaFileName, line_num,
+							gai_strerror(ret))));
 			if (cidr_slash)
 				*cidr_slash = '/';
 			if (gai_result)
@@ -777,8 +772,9 @@ parse_hba(List *line, int line_num, hbaPort *port,
 			{
 				ereport(LOG,
 						(errcode(ERRCODE_CONFIG_FILE_ERROR),
-						 errmsg("invalid IP mask \"%s\" in pg_hba.conf file line %d: %s",
-								token, line_num, gai_strerror(ret))));
+						 errmsg("invalid IP mask \"%s\" in \"%s\" line %d: %s",
+								token, HbaFileName, line_num,
+								gai_strerror(ret))));
 				if (gai_result)
 					freeaddrinfo_all(hints.ai_family, gai_result);
 				goto hba_other_error;
@@ -791,8 +787,8 @@ parse_hba(List *line, int line_num, hbaPort *port,
 			{
 				ereport(LOG,
 						(errcode(ERRCODE_CONFIG_FILE_ERROR),
-						 errmsg("IP address and mask do not match in pg_hba.conf file line %d",
-								line_num)));
+						 errmsg("IP address and mask do not match in \"%s\" line %d",
+								HbaFileName, line_num)));
 				goto hba_other_error;
 			}
 		}
@@ -849,13 +845,14 @@ hba_syntax:
 	if (line_item)
 		ereport(LOG,
 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
-				 errmsg("invalid entry in pg_hba.conf file at line %d, token \"%s\"",
-						line_num, (char *) lfirst(line_item))));
+				 errmsg("invalid entry in \"%s\" at line %d, token \"%s\"",
+						HbaFileName, line_num,
+						(char *) lfirst(line_item))));
 	else
 		ereport(LOG,
 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
-			errmsg("missing field in pg_hba.conf file at end of line %d",
-				   line_num)));
+			errmsg("missing field in \"%s\" at end of line %d",
+				   HbaFileName, line_num)));
 
 	/* Come here if suitable message already logged */
 hba_other_error:
@@ -1030,42 +1027,25 @@ load_user(void)
 
 /*
  * Read the config file and create a List of Lists of tokens in the file.
- * If we find a file by the old name of the config file (pg_hba), we issue
- * an error message because it probably needs to be converted.	He didn't
- * follow directions and just installed his old hba file in the new database
- * system.
  */
 void
 load_hba(void)
 {
-	FILE	   *file;			/* The config file we have to read */
-	char	   *conf_file;		/* The name of the config file */
+	FILE	   *file;
 
 	if (hba_lines || hba_line_nums)
 		free_lines(&hba_lines, &hba_line_nums);
 
-	if (guc_hbafile)
-	{
-		/* HBA filename specified in config file */
-		conf_file = pstrdup(guc_hbafile);
-	}
-	else
-	{
-		/* put together the full pathname to the config file */
-		conf_file = palloc(strlen(ConfigDir) + strlen(CONF_FILE) + 2);
-		sprintf(conf_file, "%s/%s", ConfigDir, CONF_FILE);
-	}
-
-	file = AllocateFile(conf_file, "r");
+	file = AllocateFile(HbaFileName, "r");
+	/* Failure is fatal since with no HBA entries we can do nothing... */
 	if (file == NULL)
 		ereport(FATAL,
 				(errcode_for_file_access(),
 				 errmsg("could not open configuration file \"%s\": %m",
-						conf_file)));
+						HbaFileName)));
 
 	tokenize_file(file, &hba_lines, &hba_line_nums);
 	FreeFile(file);
-	pfree(conf_file);
 }
 
 
@@ -1121,13 +1101,14 @@ ident_syntax:
 	if (line_item)
 		ereport(LOG,
 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
-				 errmsg("invalid entry in pg_ident.conf file at line %d, token \"%s\"",
-						line_number, (const char *) lfirst(line_item))));
+				 errmsg("invalid entry in \"%s\" at line %d, token \"%s\"",
+						IdentFileName, line_number,
+						(const char *) lfirst(line_item))));
 	else
 		ereport(LOG,
 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
-		  errmsg("missing entry in pg_ident.conf file at end of line %d",
-				 line_number)));
+		  errmsg("missing entry in \"%s\" at end of line %d",
+				 IdentFileName, line_number)));
 
 	*error_p = true;
 }
@@ -1191,38 +1172,25 @@ check_ident_usermap(const char *usermap_name,
 void
 load_ident(void)
 {
-	FILE	   *file;			/* The map file we have to read */
-	char	   *map_file;		/* The name of the map file we have to
-								 * read */
+	FILE	   *file;
 
 	if (ident_lines || ident_line_nums)
 		free_lines(&ident_lines, &ident_line_nums);
 
-	if (guc_identfile)
-	{
-		/* IDENT filename specified in config file */
-		map_file = pstrdup(guc_identfile);
-	}
-	else
-	{
-		map_file = palloc(strlen(ConfigDir) + strlen(USERMAP_FILE) + 2);
-		sprintf(map_file, "%s/%s", ConfigDir, USERMAP_FILE);
-	}
-
-	file = AllocateFile(map_file, "r");
+	file = AllocateFile(IdentFileName, "r");
 	if (file == NULL)
 	{
+		/* not fatal ... we just won't do any special ident maps */
 		ereport(LOG,
 				(errcode_for_file_access(),
 				 errmsg("could not open Ident usermap file \"%s\": %m",
-						map_file)));
+						IdentFileName)));
 	}
 	else
 	{
 		tokenize_file(file, &ident_lines, &ident_line_nums);
 		FreeFile(file);
 	}
-	pfree(map_file);
 }
 
 
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 95e74eb30b567369cf60d57f50c6384da4ed99b8..1cbe405ea5792d227540dbb833742ff742fa5452 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.430 2004/10/08 01:36:34 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.431 2004/10/09 23:13:02 tgl Exp $
  *
  * NOTES
  *
@@ -537,10 +537,6 @@ PostmasterMain(int argc, char *argv[])
 	/* Verify that DataDir looks reasonable */
 	checkDataDir();
 
-#ifdef EXEC_BACKEND
-	write_nondefault_variables(PGC_POSTMASTER);
-#endif
-
 	/*
 	 * Check for invalid combinations of GUC settings.
 	 */
@@ -782,12 +778,16 @@ PostmasterMain(int argc, char *argv[])
 	if (!CreateOptsFile(argc, argv, my_exec_path))
 		ExitPostmaster(1);
 
+#ifdef EXEC_BACKEND
+	write_nondefault_variables(PGC_POSTMASTER);
+#endif
+
 	/*
 	 * Write the external PID file if requested
 	 */
-	if (external_pidfile)
+	if (external_pid_file)
 	{
-		FILE	   *fpidfile = fopen(external_pidfile, "w");
+		FILE	   *fpidfile = fopen(external_pid_file, "w");
 
 		if (fpidfile)
 		{
@@ -797,7 +797,7 @@ PostmasterMain(int argc, char *argv[])
 		}
 		else
 			write_stderr("%s: could not write external pid file \"%s\": %s\n",
-						 progname, external_pidfile, strerror(errno));
+						 progname, external_pid_file, strerror(errno));
 	}
 
 	/*
@@ -860,10 +860,6 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	StartupPID = StartupDataBase();
 
-#ifdef EXEC_BACKEND
-	write_nondefault_variables(PGC_POSTMASTER);
-#endif
-
 	status = ServerLoop();
 
 	/*
@@ -3390,12 +3386,6 @@ write_backend_variables(char *filename, Port *port)
 	StrNCpy(str_buf, DataDir, MAXPGPATH);
 	write_array_var(str_buf, fp);
 
-	StrNCpy(str_buf, ConfigDir, MAXPGPATH);
-	write_array_var(str_buf, fp);
-
-	StrNCpy(str_buf, ConfigFileName, MAXPGPATH);
-	write_array_var(str_buf, fp);
-
 	write_array_var(ListenSocket, fp);
 
 	write_var(MyCancelKey, fp);
@@ -3470,12 +3460,6 @@ read_backend_variables(char *filename, Port *port)
 	read_array_var(str_buf, fp);
 	SetDataDir(str_buf);
 
-	read_array_var(str_buf, fp);
-	ConfigDir = strdup(str_buf);
-
-	read_array_var(str_buf, fp);
-	ConfigFileName = strdup(str_buf);
-
 	read_array_var(ListenSocket, fp);
 
 	read_var(MyCancelKey, fp);
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 346ae3b9516f2b30608db7455fa2b84896b27494..5a81c0467b30c311ecdaa9966cb8cfd18feeac13 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.134 2004/10/04 14:55:17 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.135 2004/10/09 23:13:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -171,7 +171,34 @@ SetDataDir(const char *dir)
 	AssertArg(dir);
 
 	/* If presented path is relative, convert to absolute */
-	if (!is_absolute_path(dir))
+	new = make_absolute_path(dir);
+
+	if (DataDir)
+		free(DataDir);
+	DataDir = new;
+}
+
+/*
+ * If the given pathname isn't already absolute, make it so, interpreting
+ * it relative to the current working directory.
+ *
+ * Also canonicalizes the path.  The result is always a malloc'd copy.
+ *
+ * Note: it is probably unwise to use this in running backends, since they
+ * have chdir'd to a database-specific subdirectory; the results would not be
+ * consistent across backends.  Currently this is used only during postmaster
+ * or standalone-backend startup.
+ */
+char *
+make_absolute_path(const char *path)
+{
+	char	   *new;
+
+	/* Returning null for null input is convenient for some callers */
+	if (path == NULL)
+		return NULL;
+
+	if (!is_absolute_path(path))
 	{
 		char	   *buf;
 		size_t		buflen;
@@ -200,28 +227,27 @@ SetDataDir(const char *dir)
 			}
 		}
 
-		new = malloc(strlen(buf) + 1 + strlen(dir) + 1);
+		new = malloc(strlen(buf) + strlen(path) + 2);
 		if (!new)
 			ereport(FATAL,
 					(errcode(ERRCODE_OUT_OF_MEMORY),
 					 errmsg("out of memory")));
-		sprintf(new, "%s/%s", buf, dir);
+		sprintf(new, "%s/%s", buf, path);
 		free(buf);
 	}
 	else
 	{
-		new = strdup(dir);
+		new = strdup(path);
 		if (!new)
 			ereport(FATAL,
 					(errcode(ERRCODE_OUT_OF_MEMORY),
 					 errmsg("out of memory")));
 	}
 
+	/* Make sure punctuation is canonical, too */
 	canonicalize_path(new);
 
-	if (DataDir)
-		free(DataDir);
-	DataDir = new;
+	return new;
 }
 
 
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 8e2deeeb007aaff3e5cc34e4afeddfd27e3ee6f0..a788e53266efb3bc315d2d890e3583160fe4ce97 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.240 2004/10/08 01:36:35 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.241 2004/10/09 23:13:10 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -64,7 +64,9 @@
 #define PG_KRB_SRVTAB ""
 #endif
 
-#define CONFIG_FILENAME "postgresql.conf"
+#define CONFIG_FILENAME	"postgresql.conf"
+#define HBA_FILENAME	"pg_hba.conf"
+#define IDENT_FILENAME	"pg_ident.conf"
 
 #ifdef EXEC_BACKEND
 #define CONFIG_EXEC_PARAMS "global/config_exec_params"
@@ -113,13 +115,6 @@ static bool assign_transaction_read_only(bool newval, bool doit, GucSource sourc
 static const char *assign_canonical_path(const char *newval, bool doit, GucSource source);
 
 
-/*
- * These are initialized by SelectConfigFiles.
- */
-char	   *ConfigDir = NULL;
-char	   *ConfigFileName = NULL;
-
-
 /*
  * GUC option variables that are exported from this module
  */
@@ -154,9 +149,10 @@ int			client_min_messages = NOTICE;
 
 int			log_min_duration_statement = -1;
 
-char	   *guc_hbafile;
-char	   *guc_identfile;
-char	   *external_pidfile;
+char	   *ConfigFileName;
+char	   *HbaFileName;
+char	   *IdentFileName;
+char	   *external_pid_file;
 
 
 /*
@@ -183,7 +179,7 @@ static char *server_encoding_string;
 static char *server_version_string;
 static char *timezone_string;
 static char *XactIsoLevel_string;
-static char *guc_pgdata;
+static char *data_directory;
 static char *custom_variable_classes;
 static int	max_function_args;
 static int	max_index_keys;
@@ -1685,11 +1681,11 @@ static struct config_string ConfigureNamesString[] =
 	{
 		{"log_directory", PGC_SIGHUP, LOGGING_WHERE,
 			gettext_noop("Sets the destination directory for log files."),
-			gettext_noop("May be specified as relative to the cluster directory "
+			gettext_noop("May be specified as relative to the data directory "
 						 "or as absolute path.")
 		},
 		&Log_directory,
-		"pg_log", NULL, NULL
+		"pg_log", assign_canonical_path, NULL
 	},
 	{
 		{"log_filename", PGC_SIGHUP, LOGGING_WHERE,
@@ -1789,38 +1785,48 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
-		{"pgdata", PGC_POSTMASTER, FILE_LOCATIONS,
-		 gettext_noop("Sets the location of the data directory"),
+		{"data_directory", PGC_POSTMASTER, FILE_LOCATIONS,
+		 gettext_noop("Sets the server's data directory"),
 		 NULL
 		},
-		&guc_pgdata,
-		NULL, assign_canonical_path, NULL
+		&data_directory,
+		NULL, NULL, NULL
 	},
 
 	{
-		{"hba_conf", PGC_SIGHUP, FILE_LOCATIONS,
-		 gettext_noop("Sets the location of the \"hba\" configuration file"),
+		{"config_file", PGC_POSTMASTER, FILE_LOCATIONS,
+		 gettext_noop("Sets the server's main configuration file"),
+		 NULL,
+		 GUC_DISALLOW_IN_FILE
+		},
+		&ConfigFileName,
+		NULL, NULL, NULL
+	},
+
+	{
+		{"hba_file", PGC_POSTMASTER, FILE_LOCATIONS,
+		 gettext_noop("Sets the server's \"hba\" configuration file"),
 		 NULL
 		},
-		&guc_hbafile,
-		NULL, assign_canonical_path, NULL
+		&HbaFileName,
+		NULL, NULL, NULL
 	},
 
 	{
-		{"ident_conf", PGC_SIGHUP, FILE_LOCATIONS,
-		 gettext_noop("Sets the location of the \"ident\" configuration file"),
+		{"ident_file", PGC_POSTMASTER, FILE_LOCATIONS,
+		 gettext_noop("Sets the server's \"ident\" configuration file"),
 		 NULL
 		},
-		&guc_identfile,
-		NULL, assign_canonical_path, NULL
+		&IdentFileName,
+		NULL, NULL, NULL
 	},
 
 	{
-		{"external_pidfile", PGC_POSTMASTER, FILE_LOCATIONS,
+		{"external_pid_file", PGC_POSTMASTER, FILE_LOCATIONS,
 		 gettext_noop("Writes the postmaster PID to the specified file"),
 		 NULL
 		},
-		&external_pidfile,
+		&external_pid_file,
 		NULL, assign_canonical_path, NULL
 	},
 
@@ -2453,47 +2459,52 @@ InitializeGUCOptions(void)
 bool
 SelectConfigFiles(const char *userDoption, const char *progname)
 {
-	char   *Doption;
+	char	   *configdir;
+	char	   *fname;
 	struct stat stat_buf;
 
-	/* If user did not specify -D, it defaults to $PGDATA */
-	if (!userDoption)
-		userDoption = getenv("PGDATA");
-
-	/* If no PGDATA either, we are completely lost */
-	if (!userDoption)
-	{
-		write_stderr("%s does not know where to find the database system data.\n"
-					 "You must specify the -D invocation option or set the "
-					 "PGDATA environment variable.\n",
-					 progname);
-		return false;
-	}
-
-	/* Get a writable copy and canonicalize the path */
-	Doption = guc_strdup(FATAL, userDoption);
-	canonicalize_path(Doption);
+	/* configdir is -D option, or $PGDATA if no -D */
+	if (userDoption)
+		configdir = make_absolute_path(userDoption);
+	else
+		configdir = make_absolute_path(getenv("PGDATA"));
 
 	/*
-	 * If it is a directory, point ConfigDir to it, and expect to
-	 * find postgresql.conf within.  Otherwise it had better be
-	 * the actual config file, and the file had better set "pgdata".
+	 * Find the configuration file: if config_file was specified on the
+	 * command line, use it, else use configdir/postgresql.conf.  In any
+	 * case ensure the result is an absolute path, so that it will be
+	 * interpreted the same way by future backends.
 	 */
-	if (stat(Doption, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode))
+	if (ConfigFileName)
+		fname = make_absolute_path(ConfigFileName);
+	else if (!configdir)
 	{
-		ConfigDir = Doption;
-		ConfigFileName = guc_malloc(FATAL,
-							strlen(ConfigDir) + strlen(CONFIG_FILENAME) + 2);
-		sprintf(ConfigFileName, "%s/%s", ConfigDir, CONFIG_FILENAME);
+		write_stderr("%s does not know where to find the server configuration file.\n"
+					 "You must specify the --config_file or -D invocation "
+					 "option or set the PGDATA environment variable.\n",
+					 progname);
+		return false;
 	}
 	else
 	{
-		ConfigFileName = Doption;
+		fname = guc_malloc(FATAL,
+						   strlen(configdir) + strlen(CONFIG_FILENAME) + 2);
+		sprintf(fname, "%s/%s", configdir, CONFIG_FILENAME);
 	}
 
+	/*
+	 * Set the ConfigFileName GUC variable to its final value, ensuring
+	 * that it can't be overridden later.
+	 */
+	SetConfigOption("config_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
+	free(fname);
+
+	/*
+	 * Now read the config file for the first time.
+	 */
 	if (stat(ConfigFileName, &stat_buf) != 0)
 	{
-		write_stderr("%s cannot access the data directory or configuration file \"%s\": %s\n",
+		write_stderr("%s cannot access the server configuration file \"%s\": %s\n",
 					 progname, ConfigFileName, strerror(errno));
 		return false;
 	}
@@ -2501,32 +2512,81 @@ SelectConfigFiles(const char *userDoption, const char *progname)
 	ProcessConfigFile(PGC_POSTMASTER);
 
 	/*
-	 * If the config file specified pgdata, use that as DataDir;
-	 * otherwise use ConfigDir (the original Doption) if set;
-	 * else punt.
+	 * If the data_directory GUC variable has been set, use that as DataDir;
+	 * otherwise use configdir if set; else punt.
 	 *
-	 * Note: SetDataDir will copy and canonicalize its argument,
+	 * Note: SetDataDir will copy and absolute-ize its argument,
 	 * so we don't have to.
 	 */
-	if (guc_pgdata)
-		SetDataDir(guc_pgdata);
-	else if (ConfigDir)
-		SetDataDir(ConfigDir);
+	if (data_directory)
+		SetDataDir(data_directory);
+	else if (configdir)
+		SetDataDir(configdir);
 	else
 	{
 		write_stderr("%s does not know where to find the database system data.\n"
-					 "This should be specified as \"pgdata\" in \"%s\".\n",
+					 "This can be specified as \"data_directory\" in \"%s\", "
+					 "or by the -D invocation option, or by the "
+					 "PGDATA environment variable.\n",
+					 progname, ConfigFileName);
+		return false;
+	}
+
+	/*
+	 * Reflect the final DataDir value back into the data_directory GUC var.
+	 * (If you are wondering why we don't just make them a single variable,
+	 * it's because the EXEC_BACKEND case needs DataDir to be transmitted to
+	 * child backends specially.)
+	 */
+	SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);
+
+	/*
+	 * Figure out where pg_hba.conf is, and make sure the path is absolute.
+	 */
+	if (HbaFileName)
+		fname = make_absolute_path(HbaFileName);
+	else if (!configdir)
+	{
+		write_stderr("%s does not know where to find the \"hba\" configuration file.\n"
+					 "This can be specified as \"hba_file\" in \"%s\", "
+					 "or by the -D invocation option, or by the "
+					 "PGDATA environment variable.\n",
 					 progname, ConfigFileName);
 		return false;
 	}
+	else
+	{
+		fname = guc_malloc(FATAL,
+						   strlen(configdir) + strlen(HBA_FILENAME) + 2);
+		sprintf(fname, "%s/%s", configdir, HBA_FILENAME);
+	}
+	SetConfigOption("hba_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
+	free(fname);
 
 	/*
-	 * Set ConfigDir as DataDir unless we had another value (which is to say,
-	 * Doption pointed to a directory).  This determines the default location
-	 * of secondary configuration files that will be read later.
+	 * Likewise for pg_ident.conf.
 	 */
-	if (!ConfigDir)
-		ConfigDir = DataDir;
+	if (IdentFileName)
+		fname = make_absolute_path(IdentFileName);
+	else if (!configdir)
+	{
+		write_stderr("%s does not know where to find the \"ident\" configuration file.\n"
+					 "This can be specified as \"ident_file\" in \"%s\", "
+					 "or by the -D invocation option, or by the "
+					 "PGDATA environment variable.\n",
+					 progname, ConfigFileName);
+		return false;
+	}
+	else
+	{
+		fname = guc_malloc(FATAL,
+						   strlen(configdir) + strlen(IDENT_FILENAME) + 2);
+		sprintf(fname, "%s/%s", configdir, IDENT_FILENAME);
+	}
+	SetConfigOption("ident_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
+	free(fname);
+
+	free(configdir);
 
 	/* If timezone is not set, determine what the OS uses */
 	pg_timezone_initialize();
@@ -5703,7 +5763,6 @@ assign_canonical_path(const char *newval, bool doit, GucSource source)
 {
 	if (doit)
 	{
-		/* We have to create a new pointer to force the change */
 		char	   *canon_val = guc_strdup(ERROR, newval);
 
 		canonicalize_path(canon_val);
@@ -5713,4 +5772,5 @@ assign_canonical_path(const char *newval, bool doit, GucSource source)
 		return newval;
 }
 
+
 #include "guc-file.c"
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 3c689c7eacbad8d4f20df366b54eca7e3aebd60d..59004a73c058d1f89801b9fb674a117b74fd60ff 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -30,13 +30,13 @@
 #---------------------------------------------------------------------------
 
 # The default values of these variables are driven from the -D command line
-# switch or PGDATA environment variable, represented here as $PGDATA.
-# pgdata = '$PGDATA'			# use data in another directory
-# hba_conf = '$PGDATA/pg_hba.conf'	# the host-based authentication file
-# ident_conf = '$PGDATA/pg_ident.conf'	# the IDENT configuration file
+# switch or PGDATA environment variable, represented here as ConfigDir.
+# data_directory = 'ConfigDir'		# use data in another directory
+# hba_file = 'ConfigDir/pg_hba.conf'	# the host-based authentication file
+# ident_file = 'ConfigDir/pg_ident.conf'  # the IDENT configuration file
 
-# If external_pidfile is not explicitly set, no extra pid file is written.
-# external_pidfile = '(none)'		# write an extra pid file
+# If external_pid_file is not explicitly set, no extra pid file is written.
+# external_pid_file = '(none)'		# write an extra pid file
 
 
 #---------------------------------------------------------------------------
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 4130bf14bd1addc7205400e21cff8f63aaac04e9..c09bfe332318a5968731464b945605fd9ae3b907 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.168 2004/09/06 23:55:34 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.169 2004/10/09 23:13:14 tgl Exp $
  *
  * NOTES
  *	  some of the information in this file should be moved to other files.
@@ -241,6 +241,7 @@ extern void InitializeSessionUserIdStandalone(void);
 extern void SetSessionAuthorization(AclId userid, bool is_superuser);
 
 extern void SetDataDir(const char *dir);
+extern char *make_absolute_path(const char *path);
 
 /* in utils/misc/superuser.c */
 extern bool superuser(void);	/* current user is superuser */
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 0639f19da90f036b8606ed3bb444506cc995cf1c..38eba48aae63e86516d83fb2185dcf24c5145e1a 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -7,7 +7,7 @@
  * Copyright (c) 2000-2004, PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
- * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.52 2004/10/08 01:36:36 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.53 2004/10/09 23:13:22 tgl Exp $
  *--------------------------------------------------------------------
  */
 #ifndef GUC_H
@@ -135,11 +135,10 @@ extern int	log_min_messages;
 extern int	client_min_messages;
 extern int	log_min_duration_statement;
 
-extern char *ConfigDir;
 extern char *ConfigFileName;
-extern char *guc_hbafile;
-extern char *guc_identfile;
-extern char *external_pidfile;
+extern char *HbaFileName;
+extern char *IdentFileName;
+extern char *external_pid_file;
 
 
 extern void SetConfigOption(const char *name, const char *value,