diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 2b34921e70b3eced925b605a35b9388574cb8938..7a44f074a8605579c0d2f7d3fe98c1d1bc3f0e80 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.223 2009/08/04 16:08:35 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.224 2009/08/24 20:08:31 tgl Exp $ -->
 
 <chapter Id="runtime-config">
   <title>Server Configuration</title>
@@ -2588,7 +2588,37 @@ local0.*    /var/log/postgresql
         </para>
        </listitem>
       </varlistentry>
-      
+
+     <varlistentry id="guc-silent-mode" xreflabel="silent_mode">
+      <term><varname>silent_mode</varname> (<type>boolean</type>)</term>
+      <indexterm>
+       <primary><varname>silent_mode</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        Runs the server silently. If this parameter is set, the server
+        will automatically run in background and disassociate from the
+        controlling terminal.
+        This parameter can only be set at server start.
+       </para>
+
+       <caution>
+       <para>
+        When this parameter is set,
+        the server's standard output and standard error are redirected
+        to the file <filename>postmaster.log</> within the data directory.
+        There is no provision for rotating this file, so it will grow
+        indefinitely unless server log output is redirected elsewhere
+        by other settings.  It is recommended that <varname>log_destination</>
+        be set to <literal>syslog</> or that <varname>logging_collector</> be
+        enabled when using this option.  Even with those measures, errors
+        reported early during startup may appear in
+        <filename>postmaster.log</> rather than the normal log destination.
+       </para>
+       </caution>
+      </listitem>
+     </varlistentry>
+
       </variablelist>
     </sect2>
      <sect2 id="runtime-config-logging-when">
@@ -2722,26 +2752,6 @@ local0.*    /var/log/postgresql
        </listitem>
       </varlistentry>
 
-     <varlistentry id="guc-silent-mode" xreflabel="silent_mode">
-      <term><varname>silent_mode</varname> (<type>boolean</type>)</term>
-      <indexterm>
-       <primary><varname>silent_mode</> configuration parameter</primary>
-      </indexterm>
-      <listitem>
-       <para>
-        Runs the server silently. If this parameter is set, the server
-        will automatically run in background and any controlling
-        terminals are disassociated.
-        The server's standard output and standard error are redirected
-        to <literal>/dev/null</>, so any messages sent to them will be lost.
-        Unless <application>syslog</> logging is selected or
-        <varname>logging_collector</> is enabled, using this parameter
-        is discouraged because it makes it impossible to see error messages.
-        This parameter can only be set at server start.
-       </para>
-      </listitem>
-     </varlistentry>
-
      </variablelist>
 
     <para>
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index cabd61fc0f3458f2303a5877d16b483697856651..7c96d978a0d129490e9031525b6cec089ff0316b 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.589 2009/08/24 18:09:37 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.590 2009/08/24 20:08:32 tgl Exp $
  *
  * NOTES
  *
@@ -191,7 +191,7 @@ static int	SendStop = false;
 
 /* still more option variables */
 bool		EnableSSL = false;
-bool		SilentMode = false; /* silent mode (-S) */
+bool		SilentMode = false; /* silent_mode */
 
 int			PreAuthDelay = 0;
 int			AuthenticationTimeout = 60;
@@ -744,7 +744,7 @@ PostmasterMain(int argc, char *argv[])
 	}
 
 	/*
-	 * Fork away from controlling terminal, if -S specified.
+	 * Fork away from controlling terminal, if silent_mode specified.
 	 *
 	 * Must do this before we grab any interlock files, else the interlocks
 	 * will show the wrong PID.
@@ -894,20 +894,6 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	set_max_safe_fds();
 
-	/*
-	 * Load configuration files for client authentication.
-	 */
-	if (!load_hba())
-	{
-		/*
-		 * It makes no sense continue if we fail to load the HBA file, since
-		 * there is no way to connect to the database in this case.
-		 */
-		ereport(FATAL,
-				(errmsg("could not load pg_hba.conf")));
-	}
-	load_ident();
-
 	/*
 	 * Initialize the list of active backends.
 	 */
@@ -1023,6 +1009,20 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	autovac_init();
 
+	/*
+	 * Load configuration files for client authentication.
+	 */
+	if (!load_hba())
+	{
+		/*
+		 * It makes no sense to continue if we fail to load the HBA file,
+		 * since there is no way to connect to the database in this case.
+		 */
+		ereport(FATAL,
+				(errmsg("could not load pg_hba.conf")));
+	}
+	load_ident();
+
 	/*
 	 * Remember postmaster startup time
 	 */
@@ -1204,15 +1204,46 @@ reg_reply(DNSServiceRegistrationReplyErrorType errorCode, void *context)
 
 
 /*
- * Fork away from the controlling terminal (-S option)
+ * Fork away from the controlling terminal (silent_mode option)
+ *
+ * Since this requires disconnecting from stdin/stdout/stderr (in case they're
+ * linked to the terminal), we re-point stdin to /dev/null and stdout/stderr
+ * to "postmaster.log" in the data directory, where we're already chdir'd.
  */
 static void
 pmdaemonize(void)
 {
 #ifndef WIN32
-	int			i;
+	const char *pmlogname = "postmaster.log";
+	int			dvnull;
+	int			pmlog;
 	pid_t		pid;
+	int			res;
+
+	/*
+	 * Make sure we can open the files we're going to redirect to.  If this
+	 * fails, we want to complain before disconnecting.  Mention the full path
+	 * of the logfile in the error message, even though we address it by
+	 * relative path.
+	 */
+	dvnull = open(DEVNULL, O_RDONLY, 0);
+	if (dvnull < 0)
+	{
+		write_stderr("%s: could not open file \"%s\": %s\n",
+					 progname, DEVNULL, strerror(errno));
+		ExitPostmaster(1);
+	}
+	pmlog = open(pmlogname, O_CREAT | O_WRONLY | O_APPEND, 0600);
+	if (pmlog < 0)
+	{
+		write_stderr("%s: could not open log file \"%s/%s\": %s\n",
+					 progname, DataDir, pmlogname, strerror(errno));
+		ExitPostmaster(1);
+	}
 
+	/*
+	 * Okay to fork.
+	 */
 	pid = fork_process();
 	if (pid == (pid_t) -1)
 	{
@@ -1231,8 +1262,8 @@ pmdaemonize(void)
 	MyStartTime = time(NULL);
 
 	/*
-	 * GH: If there's no setsid(), we hopefully don't need silent mode. Until
-	 * there's a better solution.
+	 * Some systems use setsid() to dissociate from the TTY's process group,
+	 * while on others it depends on stdin/stdout/stderr.  Do both if possible.
 	 */
 #ifdef HAVE_SETSID
 	if (setsid() < 0)
@@ -1242,14 +1273,26 @@ pmdaemonize(void)
 		ExitPostmaster(1);
 	}
 #endif
-	i = open(DEVNULL, O_RDWR, 0);
-	dup2(i, 0);
-	dup2(i, 1);
-	dup2(i, 2);
-	close(i);
+
+	/*
+	 * Reassociate stdin/stdout/stderr.  fork_process() cleared any pending
+	 * output, so this should be safe.  The only plausible error is EINTR,
+	 * which just means we should retry.
+	 */
+	do {
+		res = dup2(dvnull, 0);
+	} while (res < 0 && errno == EINTR);
+	close(dvnull);
+	do {
+		res = dup2(pmlog, 1);
+	} while (res < 0 && errno == EINTR);
+	do {
+		res = dup2(pmlog, 2);
+	} while (res < 0 && errno == EINTR);
+	close(pmlog);
 #else							/* WIN32 */
 	/* not supported */
-	elog(FATAL, "SilentMode not supported under WIN32");
+	elog(FATAL, "silent_mode is not supported under Windows");
 #endif   /* WIN32 */
 }
 
@@ -3241,8 +3284,8 @@ BackendInitialize(Port *port)
 	if (!load_hba())
 	{
 		/*
-		 * It makes no sense continue if we fail to load the HBA file, since
-		 * there is no way to connect to the database in this case.
+		 * It makes no sense to continue if we fail to load the HBA file,
+		 * since there is no way to connect to the database in this case.
 		 */
 		ereport(FATAL,
 				(errmsg("could not load pg_hba.conf")));
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 264b45451a966e2c959170f8303030813c3dde90..0fe3b4b98cf1e34d9f60c9cc44896a66ff687639 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.510 2009/08/04 16:08:36 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.511 2009/08/24 20:08:32 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -734,7 +734,7 @@ static struct config_bool ConfigureNamesBool[] =
 		true, NULL, NULL
 	},
 	{
-		{"silent_mode", PGC_POSTMASTER, LOGGING_WHEN,
+		{"silent_mode", PGC_POSTMASTER, LOGGING_WHERE,
 			gettext_noop("Runs the server silently."),
 			gettext_noop("If this parameter is set, the server will automatically run in the "
 				 "background and any controlling terminals are dissociated.")
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 41488e264f06a11a7a757fb13c71a218c3c1a3e2..c6c02fcd812ab8d4186cbc1b7dbd0b383ef3e771 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -265,6 +265,11 @@
 #syslog_facility = 'LOCAL0'
 #syslog_ident = 'postgres'
 
+#silent_mode = off			# Run server silently.
+					# DO NOT USE without syslog or
+					# logging_collector
+					# (change requires restart)
+
 
 # - When to Log -
 
@@ -314,9 +319,6 @@
 					# statements running at least this number
 					# of milliseconds
 
-#silent_mode = off			# DO NOT USE without syslog or
-					# logging_collector
-					# (change requires restart)
 
 # - What to Log -