diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index a3ed96689d7b8dc734f9a1088f49db528824fecd..75092fc4a4511dc7608c045ec9f8d6800e0abbea 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.571 2009/08/29 19:26:51 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.572 2009/09/01 00:09:42 tgl Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -2862,7 +2862,7 @@ get_stats_option_name(const char *arg)
  * from the client's startup packet.  The latter have the same syntax but
  * may be restricted in what they can do.
  *
- * argv[0] is the program name either way.
+ * argv[0] is ignored in either case (it's assumed to be the program name).
  *
  * ctx is PGC_POSTMASTER for secure options, PGC_BACKEND for insecure options
  * coming from the client, or PGC_SUSET for insecure options coming from
@@ -2871,11 +2871,10 @@ get_stats_option_name(const char *arg)
  * Returns the database name extracted from the command line, if any.
  * ----------------------------------------------------------------
  */
-static const char *
+const char *
 process_postgres_switches(int argc, char *argv[], GucContext ctx)
 {
 	const char *dbname;
-	const char *argv0 = argv[0];
 	bool		secure = (ctx == PGC_POSTMASTER);
 	int			errs = 0;
 	GucSource	gucsource;
@@ -3073,13 +3072,13 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx)
 			ereport(FATAL,
 					(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("invalid command-line arguments for server process"),
-			   errhint("Try \"%s --help\" for more information.", argv0)));
+			   errhint("Try \"%s --help\" for more information.", progname)));
 		else
 			ereport(FATAL,
 					(errcode(ERRCODE_SYNTAX_ERROR),
 					 errmsg("%s: invalid command-line arguments",
-							argv0),
-			   errhint("Try \"%s --help\" for more information.", argv0)));
+							progname),
+			   errhint("Try \"%s --help\" for more information.", progname)));
 	}
 
 	if (argc - optind == 1)
@@ -3114,8 +3113,6 @@ int
 PostgresMain(int argc, char *argv[], const char *username)
 {
 	const char *dbname;
-	bool		am_superuser;
-	GucContext	ctx;
 	int			firstchar;
 	char		stack_base;
 	StringInfoData input_message;
@@ -3176,13 +3173,13 @@ PostgresMain(int argc, char *argv[], const char *username)
 			ereport(FATAL,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("%s: no database nor user name specified",
-						argv[0])));
+						progname)));
 	}
 
 	/* Acquire configuration parameters, unless inherited from postmaster */
 	if (!IsUnderPostmaster)
 	{
-		if (!SelectConfigFiles(userDoption, argv[0]))
+		if (!SelectConfigFiles(userDoption, progname))
 			proc_exit(1);
 		/* If timezone is not set, determine what the OS uses */
 		pg_timezone_initialize();
@@ -3314,7 +3311,7 @@ PostgresMain(int argc, char *argv[], const char *username)
 	 * it inside InitPostgres() instead.  In particular, anything that
 	 * involves database access should be there, not here.
 	 */
-	am_superuser = InitPostgres(dbname, InvalidOid, username, NULL);
+	InitPostgres(dbname, InvalidOid, username, NULL);
 
 	/*
 	 * If the PostmasterContext is still around, recycle the space; we don't
@@ -3331,70 +3328,6 @@ PostgresMain(int argc, char *argv[], const char *username)
 
 	SetProcessingMode(NormalProcessing);
 
-	set_ps_display("startup", false);
-
-	/*
-	 * Now that we know if client is a superuser, we can try to apply any
-	 * command-line options passed in the startup packet.
-	 */
-	ctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
-
-	if (MyProcPort != NULL &&
-		MyProcPort->cmdline_options != NULL)
-	{
-		/*
-		 * The maximum possible number of commandline arguments that could
-		 * come from MyProcPort->cmdline_options is (strlen + 1) / 2; see
-		 * pg_split_opts().
-		 */
-		char	  **av;
-		int			maxac;
-		int			ac;
-
-		maxac = 2 + (strlen(MyProcPort->cmdline_options) + 1) / 2;
-
-		av = (char **) palloc(maxac * sizeof(char *));
-		ac = 0;
-
-		av[ac++] = argv[0];
-
-		/* Note this mangles MyProcPort->cmdline_options */
-		pg_split_opts(av, &ac, MyProcPort->cmdline_options);
-
-		av[ac] = NULL;
-
-		Assert(ac < maxac);
-
-		(void) process_postgres_switches(ac, av, ctx);
-	}
-
-	/*
-	 * Process any additional GUC variable settings passed in startup packet.
-	 * These are handled exactly like command-line variables.
-	 */
-	if (MyProcPort != NULL)
-	{
-		ListCell   *gucopts = list_head(MyProcPort->guc_options);
-
-		while (gucopts)
-		{
-			char	   *name;
-			char	   *value;
-
-			name = lfirst(gucopts);
-			gucopts = lnext(gucopts);
-
-			value = lfirst(gucopts);
-			gucopts = lnext(gucopts);
-
-			SetConfigOption(name, value, ctx, PGC_S_CLIENT);
-		}
-	}
-
-	/* Apply PostAuthDelay as soon as we've read all options */
-	if (PostAuthDelay > 0)
-		pg_usleep(PostAuthDelay * 1000000L);
-
 	/*
 	 * Now all GUC states are fully set up.  Report them to client if
 	 * appropriate.
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 2d7253312f5f93c42caf344a5624cbc94626b765..5321afc1b8d4da0bd50f0c18384132aa3e0bcb92 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.196 2009/08/31 19:41:00 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.197 2009/09/01 00:09:42 tgl Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -44,11 +44,13 @@
 #include "storage/procsignal.h"
 #include "storage/sinvaladt.h"
 #include "storage/smgr.h"
+#include "tcop/tcopprot.h"
 #include "utils/acl.h"
 #include "utils/fmgroids.h"
 #include "utils/guc.h"
 #include "utils/pg_locale.h"
 #include "utils/portal.h"
+#include "utils/ps_status.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
 #include "utils/tqual.h"
@@ -217,6 +219,8 @@ PerformAuthentication(Port *port)
 				(errmsg("connection authorized: user=%s database=%s",
 						port->user_name, port->database_name)));
 
+	set_ps_display("startup", false);
+
 	ClientAuthInProgress = false;		/* client_min_messages is active now */
 }
 
@@ -256,7 +260,7 @@ CheckMyDatabase(const char *name, bool am_superuser)
 	 * a way to recover from disabling all access to all databases, for
 	 * example "UPDATE pg_database SET datallowconn = false;".
 	 *
-	 * We do not enforce them for the autovacuum worker processes either.
+	 * We do not enforce them for autovacuum worker processes either.
 	 */
 	if (IsUnderPostmaster && !IsAutoVacuumWorkerProcess())
 	{
@@ -464,10 +468,6 @@ BaseInit(void)
  * doesn't use any parameters either, because it only goes far enough to be
  * able to read pg_database; it doesn't connect to any particular database.
  *
- * The return value indicates whether the userID is a superuser.  (That
- * can only be tested inside a transaction, so we want to do it during
- * the startup transaction rather than doing a separate one in postgres.c.)
- *
  * As of PostgreSQL 8.2, we expect InitProcess() was already called, so we
  * already have a PGPROC struct ... but it's not completely filled in yet.
  *
@@ -475,13 +475,13 @@ BaseInit(void)
  *		Be very careful with the order of calls in the InitPostgres function.
  * --------------------------------
  */
-bool
+void
 InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 			 char *out_dbname)
 {
 	bool		bootstrap = IsBootstrapProcessingMode();
-	bool		autovacuum = IsAutoVacuumWorkerProcess();
 	bool		am_superuser;
+	GucContext	gucctx;
 	char	   *fullpath;
 	char		dbname[NAMEDATALEN];
 
@@ -558,7 +558,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 
 	/* The autovacuum launcher is done here */
 	if (IsAutoVacuumLauncherProcess())
-		return true;			/* result doesn't matter */
+		return;
 
 	/*
 	 * Start a new transaction here before first access to db, and get a
@@ -706,12 +706,12 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 
 	/*
 	 * Perform client authentication if necessary, then figure out our
-	 * postgres user id, and see if we are a superuser.
+	 * postgres user ID, and see if we are a superuser.
 	 *
-	 * In standalone mode and in the autovacuum process, we use a fixed id,
-	 * otherwise we figure it out from the authenticated user name.
+	 * In standalone mode and in autovacuum worker processes, we use a fixed
+	 * ID, otherwise we figure it out from the authenticated user name.
 	 */
-	if (bootstrap || autovacuum)
+	if (bootstrap || IsAutoVacuumWorkerProcess())
 	{
 		InitializeSessionUserIdStandalone();
 		am_superuser = true;
@@ -724,7 +724,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 			ereport(WARNING,
 					(errcode(ERRCODE_UNDEFINED_OBJECT),
 					 errmsg("no roles are defined in this database system"),
-					 errhint("You should immediately run CREATE USER \"%s\" CREATEUSER;.",
+					 errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
 							 username)));
 	}
 	else
@@ -768,6 +768,69 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 				(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
 				 errmsg("connection limit exceeded for non-superusers")));
 
+	/*
+	 * Now process any command-line switches that were included in the startup
+	 * packet, if we are in a regular backend.  We couldn't do this before
+	 * because we didn't know if client is a superuser.
+	 */
+	gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
+
+	if (MyProcPort != NULL &&
+		MyProcPort->cmdline_options != NULL)
+	{
+		/*
+		 * The maximum possible number of commandline arguments that could
+		 * come from MyProcPort->cmdline_options is (strlen + 1) / 2; see
+		 * pg_split_opts().
+		 */
+		char	  **av;
+		int			maxac;
+		int			ac;
+
+		maxac = 2 + (strlen(MyProcPort->cmdline_options) + 1) / 2;
+
+		av = (char **) palloc(maxac * sizeof(char *));
+		ac = 0;
+
+		av[ac++] = "postgres";
+
+		/* Note this mangles MyProcPort->cmdline_options */
+		pg_split_opts(av, &ac, MyProcPort->cmdline_options);
+
+		av[ac] = NULL;
+
+		Assert(ac < maxac);
+
+		(void) process_postgres_switches(ac, av, gucctx);
+	}
+
+	/*
+	 * Process any additional GUC variable settings passed in startup packet.
+	 * These are handled exactly like command-line variables.
+	 */
+	if (MyProcPort != NULL)
+	{
+		ListCell   *gucopts = list_head(MyProcPort->guc_options);
+
+		while (gucopts)
+		{
+			char	   *name;
+			char	   *value;
+
+			name = lfirst(gucopts);
+			gucopts = lnext(gucopts);
+
+			value = lfirst(gucopts);
+			gucopts = lnext(gucopts);
+
+			SetConfigOption(name, value, gucctx, PGC_S_CLIENT);
+		}
+	}
+
+	/* Apply PostAuthDelay as soon as we've read all options */
+	if (PostAuthDelay > 0)
+		pg_usleep(PostAuthDelay * 1000000L);
+
 	/*
 	 * Initialize various default states that can't be set up until we've
 	 * selected the active user and gotten the right GUC settings.
@@ -786,8 +849,6 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 	/* close the transaction we started above */
 	if (!bootstrap)
 		CommitTransactionCommand();
-
-	return am_superuser;
 }
 
 
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index cd787b87da7b3bdbecd5dbf3ae8a73ae56d4d809..ae73f91edd3c59e7e29dfa65fa9f296545e32eaa 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.213 2009/08/29 19:26:51 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.214 2009/09/01 00:09:42 tgl Exp $
  *
  * NOTES
  *	  some of the information in this file should be moved to other files.
@@ -324,7 +324,7 @@ extern ProcessingMode Mode;
 
 /* in utils/init/postinit.c */
 extern void pg_split_opts(char **argv, int *argcp, char *optstr);
-extern bool InitPostgres(const char *in_dbname, Oid dboid, const char *username,
+extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 			 char *out_dbname);
 extern void BaseInit(void);
 
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 674e68028443eeae1035464bd907e0ca66bd6913..b1c8b77bd5c35101ca893b3e0646c020a8fac77d 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.99 2009/08/29 19:26:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.100 2009/09/01 00:09:42 tgl Exp $
  *
  * OLD COMMENTS
  *	  This file was created so that other c files could get the two
@@ -62,6 +62,8 @@ extern void StatementCancelHandler(SIGNAL_ARGS);
 extern void FloatExceptionHandler(SIGNAL_ARGS);
 extern void prepare_for_client_read(void);
 extern void client_read_ended(void);
+extern const char *process_postgres_switches(int argc, char *argv[],
+											 GucContext ctx);
 extern int	PostgresMain(int argc, char *argv[], const char *username);
 extern long get_stack_depth_rlimit(void);
 extern void ResetUsage(void);