diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 8539537f5195da4975b7e4f3fd96eefd3ba890d0..13ca093f746b9f5aeab64333f4c18236af7f1ee2 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.159 2003/05/28 16:03:55 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.160 2003/05/28 18:19:09 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -838,7 +838,7 @@ BootstrapAlreadySeen(Oid id)
  * ----------------
  */
 static void
-cleanup()
+cleanup(void)
 {
 	static int	beenhere = 0;
 
@@ -846,13 +846,13 @@ cleanup()
 		beenhere = 1;
 	else
 	{
-		elog(FATAL, "Memory manager fault: cleanup called twice.\n");
+		elog(FATAL, "Memory manager fault: cleanup called twice");
 		proc_exit(1);
 	}
 	if (boot_reldesc != NULL)
 		closerel(NULL);
 	CommitTransactionCommand();
-	proc_exit(Warnings);
+	proc_exit(Warnings ? 1 : 0);
 }
 
 /* ----------------
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index fd6d35bb5ad95db4741b341a4631aa1e0a906c28..9d371a5a26d05c98f34e3bb59b2ab96c31eac02d 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.110 2003/05/28 17:25:02 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.111 2003/05/28 18:19:09 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -410,18 +410,28 @@ errfinish(int dummy, ...)
 		/*
 		 * For a FATAL error, we let proc_exit clean up and exit.
 		 *
-		 * If we have not yet entered the main backend loop (ie, we are in
-		 * the postmaster or in backend startup), we also go directly to
-		 * proc_exit.  The same is true if anyone tries to report an error
-		 * after proc_exit has begun to run.  (It's proc_exit's
-		 * responsibility to see that this doesn't turn into infinite
-		 * recursion!)	But in the latter case, we exit with nonzero exit
-		 * code to indicate that something's pretty wrong.  We also want
-		 * to exit with nonzero exit code if not running under the
-		 * postmaster (for example, if we are being run from the initdb
-		 * script, we'd better return an error status).
+		 * There are several other cases in which we treat ERROR as FATAL
+		 * and go directly to proc_exit:
+		 *
+		 * 1. ExitOnAnyError mode switch is set (initdb uses this).
+		 * 
+		 * 2. we have not yet entered the main backend loop (ie, we are in
+		 * the postmaster or in backend startup); we have noplace to recover.
+		 *
+		 * 3. the error occurred after proc_exit has begun to run.  (It's
+		 * proc_exit's responsibility to see that this doesn't turn into
+		 * infinite recursion!)
+		 *
+		 * In the last case, we exit with nonzero exit code to indicate that
+		 * something's pretty wrong.  We also want to exit with nonzero exit
+		 * code if not running under the postmaster (for example, if we are
+		 * being run from the initdb script, we'd better return an error
+		 * status).
 		 */
-		if (elevel == FATAL || !Warn_restart_ready || proc_exit_inprogress)
+		if (elevel == FATAL ||
+			ExitOnAnyError ||
+			!Warn_restart_ready ||
+			proc_exit_inprogress)
 		{
 			/*
 			 * fflush here is just to improve the odds that we get to see
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index a4b0889e4fa5cc57e6a3f79a8bf861009f7f6df4..0a53556ec3a7769c87e64c193d8e5bb43aa32659 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.70 2003/05/28 17:25:02 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.71 2003/05/28 18:19:09 tgl Exp $
  *
  * NOTES
  *	  Globals used all over the place should be declared here and not
@@ -61,6 +61,8 @@ Oid			MyDatabaseId = InvalidOid;
 bool		IsPostmasterEnvironment = false;
 bool		IsUnderPostmaster = false;
 
+bool		ExitOnAnyError = false;
+
 int			DateStyle = USE_ISO_DATES;
 bool		EuroDates = false;
 bool		HasCTZSet = false;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 06eab76b9894d9a6115aba0cfe4577a153a2e7ff..4d700b4af6c71d11d00a427299cc2399d3189be0 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.126 2003/05/27 17:55:50 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.127 2003/05/28 18:19:09 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -399,6 +399,12 @@ static struct config_bool
 	},
 #endif
 
+	{
+		/* currently undocumented, so don't show in SHOW ALL */
+		{"exit_on_error", PGC_USERSET, GUC_NO_SHOW_ALL}, &ExitOnAnyError,
+		false, NULL, NULL
+	},
+
 	{
 		{"log_statement", PGC_SUSET}, &log_statement,
 		false, NULL, NULL
diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh
index 67ae4b00052215f26000c832f35c7bf1cb09e366..aa5e17aa64dd186b6d3aec3f4846698338530449 100644
--- a/src/bin/initdb/initdb.sh
+++ b/src/bin/initdb/initdb.sh
@@ -27,7 +27,7 @@
 # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.190 2003/05/28 17:25:02 tgl Exp $
+# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.191 2003/05/28 18:19:09 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -612,7 +612,7 @@ echo "ok"
 # To break an SQL command across lines in this script, backslash-escape all
 # internal newlines in the command.
 
-PGSQL_OPT="$PGSQL_OPT -O -c search_path=pg_catalog"
+PGSQL_OPT="$PGSQL_OPT -O -c search_path=pg_catalog -c exit_on_error=true"
 
 $ECHO_N "initializing pg_shadow... "$ECHO_C
 
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 8621722bad2a5d96099956ea5f836da66f586a2b..1ea326e197363e5931c36bc73e4ec340494b76dc 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: miscadmin.h,v 1.122 2003/05/28 17:25:02 tgl Exp $
+ * $Id: miscadmin.h,v 1.123 2003/05/28 18:19:09 tgl Exp $
  *
  * NOTES
  *	  some of the information in this file should be moved to
@@ -104,8 +104,6 @@ extern void ProcessInterrupts(void);
 /*
  * from postmaster/postmaster.c
  */
-extern bool IsPostmasterEnvironment;
-extern bool IsUnderPostmaster;
 extern bool ClientAuthInProgress;
 extern const bool ExecBackend;
 
@@ -115,6 +113,11 @@ extern void ClosePostmasterPorts(bool pgstat_too);
 /*
  * from utils/init/globals.c
  */
+extern bool IsPostmasterEnvironment;
+extern bool IsUnderPostmaster;
+
+extern bool ExitOnAnyError;
+
 extern bool Noversion;
 extern char *DataDir;