diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 010adfe7963c1e386bf1f04c39a11f7354789e97..7e6c02e76a22234f28269e5dba3f4dc8077b00d5 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.318 2003/05/02 22:01:51 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.319 2003/05/02 22:02:47 momjian Exp $
  *
  * NOTES
  *
@@ -256,11 +256,12 @@ static void dummy_handler(SIGNAL_ARGS);
 static void CleanupProc(int pid, int exitstatus);
 static void LogChildExit(int lev, const char *procname,
 			 int pid, int exitstatus);
-static int	DoBackend(Port *port);
+static int	BackendFinalize(Port *port);
 void		ExitPostmaster(int status);
 static void usage(const char *);
 static int	ServerLoop(void);
 static int	BackendStartup(Port *port);
+static void BackendFork(Port *port, Backend *bn);
 static int	ProcessStartupPacket(Port *port, bool SSLdone);
 static void processCancelRequest(Port *port, void *pkt);
 static int	initMasks(fd_set *rmask, fd_set *wmask);
@@ -570,6 +571,9 @@ PostmasterMain(int argc, char *argv[])
 	SetDataDir(potential_DataDir);
 
 	ProcessConfigFile(PGC_POSTMASTER);
+#ifdef EXEC_BACKEND
+	write_nondefault_variables(PGC_POSTMASTER);
+#endif
 
 	/*
 	 * Check for invalid combinations of GUC settings.
@@ -1231,7 +1235,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
 	 * Now fetch parameters out of startup packet and save them into the
 	 * Port structure.  All data structures attached to the Port struct
 	 * must be allocated in TopMemoryContext so that they won't disappear
-	 * when we pass them to PostgresMain (see DoBackend).  We need not worry
+	 * when we pass them to PostgresMain (see BackendFinalize).  We need not worry
 	 * about leaking this storage on failure, since we aren't in the postmaster
 	 * process anymore.
 	 */
@@ -1568,6 +1572,9 @@ SIGHUP_handler(SIGNAL_ARGS)
 		elog(LOG, "Received SIGHUP, reloading configuration files");
 		SignalChildren(SIGHUP);
 		ProcessConfigFile(PGC_SIGHUP);
+#ifdef EXEC_BACKEND
+		write_nondefault_variables(PGC_SIGHUP);
+#endif
 		load_hba();
 		load_ident();
 	}
@@ -2053,28 +2060,7 @@ BackendStartup(Port *port)
 	pid = fork();
 
 	if (pid == 0)				/* child */
-	{
-		int			status;
-
-#ifdef LINUX_PROFILE
-		setitimer(ITIMER_PROF, &prof_itimer, NULL);
-#endif
-
-#ifdef __BEOS__
-		/* Specific beos backend startup actions */
-		beos_backend_startup();
-#endif
-		free(bn);
-
-		status = DoBackend(port);
-		if (status != 0)
-		{
-			elog(LOG, "connection startup failed");
-			proc_exit(status);
-		}
-		else
-			proc_exit(0);
-	}
+		BackendFork(port, bn);	/* never returns */
 
 	/* in parent, error */
 	if (pid < 0)
@@ -2108,6 +2094,31 @@ BackendStartup(Port *port)
 }
 
 
+static void
+BackendFork(Port *port, Backend *bn)
+{
+	int			status;
+
+#ifdef LINUX_PROFILE
+	setitimer(ITIMER_PROF, &prof_itimer, NULL);
+#endif
+
+#ifdef __BEOS__
+	/* Specific beos backend startup actions */
+	beos_backend_startup();
+#endif
+	free(bn);
+
+	status = BackendFinalize(port);
+	if (status != 0)
+	{
+		elog(LOG, "connection startup failed");
+		proc_exit(status);
+	}
+	else
+		proc_exit(0);
+}
+
 /*
  * Try to report backend fork() failure to client before we close the
  * connection.	Since we do not care to risk blocking the postmaster on
@@ -2173,7 +2184,7 @@ split_opts(char **argv, int *argcp, char *s)
 }
 
 /*
- * DoBackend -- perform authentication, and if successful, set up the
+ * BackendFinalize -- perform authentication, and if successful, set up the
  *		backend's argument list and invoke backend main().
  *
  * This used to perform an execv() but we no longer exec the backend;
@@ -2184,7 +2195,7 @@ split_opts(char **argv, int *argcp, char *s)
  *		If PostgresMain() fails, return status.
  */
 static int
-DoBackend(Port *port)
+BackendFinalize(Port *port)
 {
 	char	   *remote_host;
 	char	  **av;
@@ -2221,6 +2232,10 @@ DoBackend(Port *port)
 	/* Reset MyProcPid to new backend's pid */
 	MyProcPid = getpid();
 
+#ifdef EXEC_BACKEND
+	read_nondefault_variables();
+#endif
+
 	/*
 	 * Initialize libpq and enable reporting of elog errors to the client.
 	 * Must do this now because authentication uses libpq to send
@@ -2248,7 +2263,7 @@ DoBackend(Port *port)
 		unsigned short remote_port;
 		char	   *host_addr;
 #ifdef HAVE_IPV6
-		char	   ip_hostinfo[INET6_ADDRSTRLEN]; 
+		char	   ip_hostinfo[INET6_ADDRSTRLEN];
 #else
 		char	   ip_hostinfo[INET_ADDRSTRLEN];
 #endif
@@ -2294,7 +2309,7 @@ DoBackend(Port *port)
 	}
 	else
 	{
-		/* not AF_INET */
+	   	/* not AF_INET */
 		remote_host = "[local]";
 
 		if (Log_connections)
@@ -2318,7 +2333,7 @@ DoBackend(Port *port)
 	 * indefinitely.  PreAuthDelay doesn't count against the time limit.
 	 */
 	if (!enable_sig_alarm(AuthenticationTimeout * 1000, false))
-		elog(FATAL, "DoBackend: Unable to set timer for auth timeout");
+		elog(FATAL, "BackendFinalize: Unable to set timer for auth timeout");
 
 	/*
 	 * Receive the startup packet (which might turn out to be a cancel
@@ -2347,7 +2362,7 @@ DoBackend(Port *port)
 	 * SIGTERM/SIGQUIT again until backend startup is complete.
 	 */
 	if (!disable_sig_alarm(false))
-		elog(FATAL, "DoBackend: Unable to disable timer for auth timeout");
+		elog(FATAL, "BackendFinalize: Unable to disable timer for auth timeout");
 	PG_SETMASK(&BlockSig);
 
 	if (Log_connections)
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 60f640639ef8c4694fdb0952b218eeac4e2a6776..77cf062685a81ccc7d4bf9f64c9b791f6d688d07 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
- *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.121 2003/05/02 22:01:51 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.122 2003/05/02 22:02:47 momjian Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -60,6 +60,9 @@
 #define PG_KRB_SRVTAB ""
 #endif
 
+#ifdef EXEC_BACKEND
+#define CONFIG_EXEC_PARAMS "global/config_exec_params"
+#endif
 
 /* XXX these should appear in other modules' header files */
 extern bool Log_connections;
@@ -2801,6 +2804,204 @@ _ShowOption(struct config_generic * record)
 }
 
 
+#ifdef EXEC_BACKEND
+/*
+ *	This routine dumps out all non-default GUC options into a binary
+ *	file that is read by all exec'ed backends.  The format is:
+ *
+ *		variable name, string, null terminated
+ *		variable value, string, null terminated
+ *		variable source, integer
+ */
+void
+write_nondefault_variables(GucContext context)
+{
+	int i;
+	char *new_filename, *filename;
+	int elevel;
+	FILE *fp;
+
+	Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
+	Assert(DataDir);
+	elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
+
+	/*
+	 * Open file
+	 */
+	new_filename = malloc(strlen(DataDir) + strlen(CONFIG_EXEC_PARAMS) +
+							strlen(".new") + 2);
+	filename = malloc(strlen(DataDir) + strlen(CONFIG_EXEC_PARAMS) + 2);
+	if (new_filename == NULL || filename == NULL)
+	{
+		elog(elevel, "out of memory");
+		return;
+	}
+	sprintf(new_filename, "%s/" CONFIG_EXEC_PARAMS ".new", DataDir);
+	sprintf(filename, "%s/" CONFIG_EXEC_PARAMS, DataDir);
+
+    fp = AllocateFile(new_filename, "w");
+    if (!fp)
+    {
+ 		free(new_filename);
+		free(filename);
+		elog(elevel, "could not write exec config params file `"
+					CONFIG_EXEC_PARAMS "': %s", strerror(errno));
+		return;
+	}
+
+	for (i = 0; i < num_guc_variables; i++)
+	{
+		struct config_generic *gconf = guc_variables[i];
+
+		if (gconf->source != PGC_S_DEFAULT)
+		{
+			fprintf(fp, "%s", gconf->name);
+			fputc(0, fp);
+
+			switch (gconf->vartype)
+			{
+				case PGC_BOOL:
+					{
+						struct config_bool *conf = (struct config_bool *) gconf;
+
+						if (*conf->variable == 0)
+							fprintf(fp, "false");
+						else
+							fprintf(fp, "true");
+					}
+					break;
+
+				case PGC_INT:
+					{
+						struct config_int *conf = (struct config_int *) gconf;
+
+						fprintf(fp, "%d", *conf->variable);
+					}
+					break;
+
+				case PGC_REAL:
+					{
+						struct config_real *conf = (struct config_real *) gconf;
+
+						/* Could lose precision here? */
+						fprintf(fp, "%f", *conf->variable);
+					}
+					break;
+
+				case PGC_STRING:
+					{
+						struct config_string *conf = (struct config_string *) gconf;
+
+						fprintf(fp, "%s", *conf->variable);
+					}
+					break;
+			}
+
+			fputc(0, fp);
+
+			fwrite(&gconf->source, sizeof(gconf->source), 1, fp);
+		}
+	}
+
+	FreeFile(fp);
+	/* Put new file in place, this could delay on Win32 */
+	rename(new_filename, filename);
+	free(new_filename);
+	free(filename);
+	return;
+}
+
+
+/*
+ *	Read string, including null byte from file
+ *
+ *	Return NULL on EOF and nothing read
+ */
+static char *
+read_string_with_null(FILE *fp)
+{
+	int i = 0, ch, maxlen = 256;
+	char *str = NULL;
+
+	do
+	{
+		if ((ch = fgetc(fp)) == EOF)
+		{
+			if (i == 0)
+				return NULL;
+			else
+				elog(FATAL, "Invalid format of exec config params file");
+		}
+		if (i == 0)
+			str = malloc(maxlen);
+		else if (i == maxlen)
+			str = realloc(str, maxlen *= 2);
+		str[i++] = ch;
+	} while (ch != 0);
+
+	return str;
+}
+
+
+/*
+ *	This routine loads a previous postmaster dump of its non-default
+ *	settings.
+ */
+void
+read_nondefault_variables(void)
+{
+	char *filename;
+	FILE *fp;
+	char *varname, *varvalue;
+	int varsource;
+
+	Assert(DataDir);
+
+	/*
+	 * Open file
+	 */
+	filename = malloc(strlen(DataDir) + strlen(CONFIG_EXEC_PARAMS) + 2);
+	if (filename == NULL)
+	{
+		elog(ERROR, "out of memory");
+		return;
+	}
+	sprintf(filename, "%s/" CONFIG_EXEC_PARAMS, DataDir);
+
+    fp = AllocateFile(filename, "r");
+    if (!fp)
+    {
+		free(filename);
+        /* File not found is fine */
+        if (errno != ENOENT)
+            elog(FATAL, "could not read exec config params file `"
+					CONFIG_EXEC_PARAMS "': %s", strerror(errno));
+		return;
+    }
+
+    while (1)
+	{
+		if ((varname = read_string_with_null(fp)) == NULL)
+			break;
+
+		if ((varvalue = read_string_with_null(fp)) == NULL)
+			elog(FATAL, "Invalid format of exec config params file");
+ 		if (fread(&varsource, sizeof(varsource), 1, fp) == 0)
+			elog(FATAL, "Invalid format of exec config params file");
+
+		(void) set_config_option(varname, varvalue, PGC_POSTMASTER,
+				varsource, false, true);
+		free(varname);
+		free(varvalue);
+	}
+
+	FreeFile(fp);
+	free(filename);
+	return;
+}
+#endif
+
+
 /*
  * A little "long argument" simulation, although not quite GNU
  * compliant. Takes a string of the form "some-option=some value" and
@@ -3203,3 +3404,4 @@ assign_msglvl(int *var, const char *newval, bool doit, bool interactive)
 
 
 #include "guc-file.c"
+
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 4c1dd86f2dd054a1cf2af7ffb33b19a166924aa5..359adaabcf0f18817246a1860ac48e31227d81b5 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -7,7 +7,7 @@
  * Copyright 2000-2003 by PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
- * $Id: guc.h,v 1.29 2003/05/02 22:01:51 momjian Exp $
+ * $Id: guc.h,v 1.30 2003/05/02 22:02:47 momjian Exp $
  *--------------------------------------------------------------------
  */
 #ifndef GUC_H
@@ -135,4 +135,9 @@ extern void ProcessGUCArray(ArrayType *array, GucSource source);
 extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *value);
 extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name);
 
+#ifdef EXEC_BACKEND
+void write_nondefault_variables(GucContext context);
+void read_nondefault_variables(void);
+#endif
+
 #endif   /* GUC_H */