diff --git a/doc/src/sgml/ref/pg_ctl-ref.sgml b/doc/src/sgml/ref/pg_ctl-ref.sgml
index 7b628ead9371566534d72052d4873e36cade6397..617a070d6e40d09e8911aa7f4436bdfd3568ed9a 100644
--- a/doc/src/sgml/ref/pg_ctl-ref.sgml
+++ b/doc/src/sgml/ref/pg_ctl-ref.sgml
@@ -1,11 +1,11 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_ctl-ref.sgml,v 1.5 2000/12/25 23:15:26 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_ctl-ref.sgml,v 1.6 2001/02/08 19:39:24 petere Exp $
 Postgres documentation
 -->
 
 <refentry id="app-pg-ctl">
  <docinfo>
-  <date>2000-11-25</date>
+  <date>2001-02-08</date>
  </docinfo>
 
  <refmeta>
@@ -25,12 +25,13 @@ Postgres documentation
    <arg choice="plain">start</arg>
    <arg>-w</arg>
    <arg>-D <replaceable>datadir</replaceable></arg>
-   <arg>-p <replaceable>path</replaceable></arg>
+   <arg>-l <replaceable>filename</replaceable></arg>
    <arg>-o <replaceable>options</replaceable></arg>
+   <arg>-p <replaceable>path</replaceable></arg>
    <sbr>
    <command>pg_ctl</command>
    <arg choice="plain">stop</arg>
-   <arg>-w</arg>
+   <arg>-W</arg>
    <arg>-D <replaceable>datadir</replaceable></arg>
    <arg>-m
      <group choice="plain">
@@ -64,8 +65,52 @@ Postgres documentation
   <title>Description</title>
   <para>
    <application>pg_ctl</application> is a utility for starting,
-   stopping, or restarting the <xref linkend="app-postmaster">, or
-   displaying the status of a running postmaster.
+   stopping, or restarting <xref linkend="app-postmaster">, the
+   <productname>PostgreSQL</productname> backend server, or displaying
+   the status of a running postmaster.  Although the postmaster can be
+   started manually, <application>pg_ctl</application> encapulates
+   tasks such as redirecting log output, properly detaching from the
+   terminal and process group, and additionally provides an option for
+   controlled shut down.
+  </para>
+
+  <para>
+   In <option>start</option> mode, a new postmaster is launched.  The
+   server is started in the background, the standard input attached to
+   <filename>/dev/null</filename>.  The standard output and standard
+   error are either appended to a log file, if the <option>-l</option>
+   option is used, or are redirected to
+   <application>pg_ctl</application>'s standard output (not standard
+   error).  If no log file is chosen, the standard output of
+   <application>pg_ctl</application> should be redirected to a file or
+   piped to another process, for example a log rotating program,
+   otherwise the postmaster will write its output the the controlling
+   terminal (from the background) and will not leave the shell's
+   process group.
+  </para>
+
+  <para>
+   In <option>stop</option> mode, the postmaster that is running on
+   the specified data directory is shut down.  Three different
+   shutdown methods can be selected with the <option>-m</option>
+   option: <quote>Smart</quote> mode waits for all the clients to
+   disconnect.  This is the default.  <quote>Fast</quote> mode does
+   not wait for clients to disconnect.  All active transactions will
+   be rolled back.  <quote>Immediate</quote> mode will abort without
+   complete shutdown.  This will lead to a recovery run on restart.
+   By the default, stop mode waits for the shutdown to complete.
+  </para>
+
+  <para>
+   <option>restart</option> mode effectively executes a stop followed
+   by a start.  This allows the changing of postmaster command line
+   options.
+  </para>
+
+  <para>
+   <option>status</option> mode checks whether a postmaster is running
+   and if so displays the <acronym>PID</acronym> and the command line
+   options that were used to invoke it.
   </para>
 
   <refsect2 id="app-pg-ctl-options">
@@ -74,38 +119,36 @@ Postgres documentation
 
     <variablelist>
      <varlistentry>
-      <term>-w</term>
+      <term>-D <replaceable class="parameter">datadir</replaceable></term>
       <listitem>
        <para>
-	Wait for the database server to come up, by watching for
-	creation of the pid file
-	(<filename><replaceable>PGDATA</replaceable>/postmaster.pid</filename>).
-	Times out after 60 seconds.
+	Specifies the file system location of the database files.  If
+	this is omitted, the environment variable
+	<envar>PGDATA</envar> is used.
        </para>
       </listitem>
      </varlistentry>
 
      <varlistentry>
-      <term>-D <replaceable class="parameter">datadir</replaceable></term>
+      <term>-l <replaceable class="parameter">filename</replaceable></term>
       <listitem>
        <para>
-	Specifies the file system location of the database files.  If
-	this is omitted, the environment variable
-	<envar>PGDATA</envar> is used.
+        Append the server log output to
+        <replaceable>filename</replaceable>.  If the file does not
+        exist, it is created.  The umask is set to 077, so access to
+        the log file from other users is disallowed by default.
        </para>
       </listitem>
      </varlistentry>
 
      <varlistentry>
-      <term>-p <replaceable class="parameter">path</replaceable></term>
+      <term>-m <replaceable class="parameter">mode</replaceable></term>
       <listitem>
        <para>
-	Specifies the location of the <filename>postmaster</filename>
-	executable.  By default the postmaster is taken from the same
-	directory as pg_ctl, or failing that, the hard-wired
-	installation directory.  It is not necessary to use this
-	option unless you are doing something unusual and get errors
-	that the postmaster was not found.
+	Specifies the shutdown mode.  <replaceable>mode</replaceable>
+	may be <literal>smart</literal>, <literal>fast</literal>, or
+	<literal>immediate</literal>, or the first letter of one of
+	these three.
        </para>
       </listitem>
      </varlistentry>
@@ -125,82 +168,35 @@ Postgres documentation
      </varlistentry>
 
      <varlistentry>
-      <term>-m <replaceable class="parameter">mode</replaceable></term>
-      <listitem>
-       <para>
-	Specifies the shutdown mode.
-
-	<variablelist>
-	 <varlistentry>
-	  <term>smart</term>
-	  <term>s</term>
-	  <listitem>
-	   <para>
-	    Smart mode waits for all the clients to disconnect. This
-	    is the default.
-	   </para>
-	  </listitem>
-	 </varlistentry>
-
-	 <varlistentry>
-	  <term>fast</term>
-	  <term>f</term>
-	  <listitem>
-	   <para>
-	    Fast mode does not wait for clients to disconnect.  All
-	    active transactions will be rolled back.
-	   </para>
-	  </listitem>
-	 </varlistentry>
-
-	 <varlistentry>
-	  <term>immediate</term>
-	  <term>i</term>
-	  <listitem>
-	   <para>
-	    Immediate mode will abort without complete shutdown.  This
-	    will lead to a recovery run on restart.
-	   </para>
-	  </listitem>
-	 </varlistentry>
-	</variablelist>
-       </para>
-      </listitem>
-     </varlistentry>
-
-     <varlistentry>
-      <term>start</term>
-      <listitem>
-       <para>
-	Start up <application>postmaster</application>.
-       </para>
-      </listitem>
-     </varlistentry>
-
-     <varlistentry>
-      <term>stop</term>
+      <term>-p <replaceable class="parameter">path</replaceable></term>
       <listitem>
        <para>
-	Shut down <application>postmaster</application>.
+	Specifies the location of the <filename>postmaster</filename>
+	executable.  By default the postmaster is taken from the same
+	directory as pg_ctl, or failing that, the hard-wired
+	installation directory.  It is not necessary to use this
+	option unless you are doing something unusual and get errors
+	that the postmaster was not found.
        </para>
       </listitem>
      </varlistentry>
 
      <varlistentry>
-      <term>restart</term>
+      <term>-w</term>
       <listitem>
        <para>
-	Stop the <application>postmaster</application>, if one is running,
-	and then start it again.
+	Wait for the start or stutdown to complete.  Times out after
+	60 seconds.  This is the default for shutdowns.
        </para>
       </listitem>
      </varlistentry>
 
      <varlistentry>
-      <term>status</term>
+      <term>-W</term>
       <listitem>
        <para>
-	Show the current state of <application>postmaster</application>.
+        Do not wait for start or shutdown to complete.  This is the
+        default for starts and restarts.
        </para>
       </listitem>
      </varlistentry>
@@ -223,7 +219,7 @@ Postgres documentation
 
 
  <refsect1 id="R1-APP-PGCTL-2">
-  <title>Usage</title>
+  <title>Examples</title>
 
   <refsect2 id="R2-APP-PGCTL-3">
    <title>Starting the postmaster</title>
@@ -260,7 +256,6 @@ Postgres documentation
 </screen>
     stops postmaster. Using the <option>-m</option> switch allows one
     to control <emphasis>how</emphasis> the backend shuts down.
-    <option>-w</option> waits for postmaster to shut down.
    </para>
   </refsect2>
 
@@ -312,6 +307,25 @@ Command line was:
    </para>
   </refsect2>
  </refsect1>
+
+ <refsect1>
+  <title>Bugs</title>
+
+  <para>
+   Waiting for complete start is not a well-defined operation and may
+   fail if access control is set up in way that a local client cannot
+   connect without manual interaction.  It should be avoided.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>See Also</title>
+
+  <para>
+   <xref linkend="app-postmaster">, <citetitle>PostgreSQL Administrator's Guide</citetitle>
+  </para>
+ </refsect1>
+
 </refentry>
 
 <!-- Keep this comment at the end of the file
diff --git a/src/bin/pg_ctl/pg_ctl.sh b/src/bin/pg_ctl/pg_ctl.sh
index 8382ef9f6fd6f3046737cb603e6b49edaf7cbc90..6d575c0d64f4fb00c3188af182cf63a5faebac2d 100755
--- a/src/bin/pg_ctl/pg_ctl.sh
+++ b/src/bin/pg_ctl/pg_ctl.sh
@@ -4,11 +4,11 @@
 # pg_ctl.sh--
 #    Start/Stop/Restart/Report status of postmaster
 #
-# Copyright (c) 2000, PostgreSQL Global Development Group
+# Copyright (c) 2001  PostgreSQL Global Development Group
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/bin/pg_ctl/Attic/pg_ctl.sh,v 1.17 2000/12/30 06:10:43 ishii Exp $
+#    $Header: /cvsroot/pgsql/src/bin/pg_ctl/Attic/pg_ctl.sh,v 1.18 2001/02/08 19:39:24 petere Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -19,20 +19,29 @@ $CMDNAME is a utility to start, stop, restart, and report the status
 of a PostgreSQL server.
 
 Usage:
-  $CMDNAME start   [-w] [-D DATADIR] [-p PATH-TO-POSTMASTER] [-o \"OPTIONS\"]
-  $CMDNAME stop    [-w] [-D DATADIR] [-m SHUTDOWN-MODE]
-  $CMDNAME restart [-w] [-D DATADIR] [-m SHUTDOWN-MODE] [-o \"OPTIONS\"]
+  $CMDNAME start   [-w] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]
+  $CMDNAME stop    [-W] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]
+  $CMDNAME restart [-w] [-D DATADIR] [-s] [-m SHUTDOWN-MODE] [-o \"OPTIONS\"]
   $CMDNAME status  [-D DATADIR]
 
-Options:
+Common options:
   -D DATADIR            Location of the database storage area
-  -m SHUTDOWN-MODE      May be 'smart', 'fast', or 'immediate'
+  -s                    Only print errors, no informational messages
+  -w                    Wait until operation completes
+  -W                    Do not wait until operation completes
+(The default is to wait for shutdown, but not for start or restart.)
+
+If the -D option is omitted, the environment variable PGDATA is used.
+
+Options for start or restart:
+  -l FILENAME           Write (or append) server log to FILENAME.  The
+                        use of this option is highly recommended.
   -o OPTIONS            Command line options to pass to the postmaster
                         (PostgreSQL server executable)
   -p PATH-TO-POSTMASTER Normally not necessary
-  -w                    Wait until operation completes
 
-If the -D option is omitted, the environment variable PGDATA is used.
+Options for stop or restart:
+  -m SHUTDOWN-MODE      May be 'smart', 'fast', or 'immediate'
 
 Shutdown modes are:
   smart                 Quit after all clients have disconnected
@@ -50,6 +59,9 @@ Try '$CMDNAME --help' for more information."
 bindir='@bindir@'
 VERSION='@VERSION@'
 
+# protect the log file
+umask 077
+
 # Check for echo -n vs echo \c
 
 if echo '\c' | grep -s c >/dev/null 2>&1
@@ -96,8 +108,11 @@ fi
 
 po_path="$PGPATH/postmaster"
 
-# set default shutdown signal
-sig="-TERM"
+wait=
+wait_seconds=60
+logfile=
+silence_echo=
+shutdown_mode=smart
 
 while [ "$#" -gt 0 ]
 do
@@ -114,34 +129,34 @@ do
 	    shift
 	    PGDATA="$1"
 	    ;;
+	-l)
+	    logfile=$2
+	    shift;;
+	-l*)
+	    logfile=`echo "$1" | sed 's/^-l//'`
+	    ;;
+	-m)
+	    shutdown_mode=$2
+	    shift;;
+	-m*)
+	    shutdown_mode=`echo "$1" | sed 's/^-m//'`
+	    ;;
+	-o)
+	    shift
+	    POSTOPTS="$1"
+	    ;;
 	-p)
 	    shift
 	    po_path="$1"
 	    ;;
-	-m)
-	    shift
-	    case $1 in
-		s|smart)
-		    ;;
-		f|fast)
-		    sig="-INT"
-		    ;;
-		i|immediate)
-		    sig="-QUIT"
-		    ;;
-	    *)
-		echo "$CMDNAME: wrong shutdown mode: $1" 1>&2
-		echo "$advice" 1>&2
-		exit 1
-		;;
-	    esac
+	-s)
+	    silence_echo=:
 	    ;;
 	-w)
-	    wait=1
+	    wait=yes
 	    ;;
-	-o)
-	    shift
-	    POSTOPTS="$1"
+	-W)
+	    wait=no
 	    ;;
 	-*)
 	    echo "$CMDNAME: invalid option: $1" 1>&2
@@ -181,20 +196,47 @@ if [ -z "$PGDATA" ];then
     exit 1
 fi
 
+if [ -z "$wait" ]; then
+    case $op in
+	start)      wait=no;;
+	stop)       wait=yes;;
+	restart)    wait=no;;   # must wait on shutdown anyhow
+    esac
+fi
+
+
+case $shutdown_mode in
+    s|smart)
+	sig="-TERM"
+	;;
+    f|fast)
+	sig="-INT"
+	;;
+    i|immediate)
+	sig="-QUIT"
+	;;
+    *)
+	echo "$CMDNAME: invalid shutdown mode: $1" 1>&2
+	echo "$advice" 1>&2
+	exit 1
+	;;
+esac
+
+
 DEFPOSTOPTS=$PGDATA/postmaster.opts.default
 POSTOPTSFILE=$PGDATA/postmaster.opts
 PIDFILE=$PGDATA/postmaster.pid
 
 if [ $op = "status" ];then
     if [ -f $PIDFILE ];then
-	PID=`head -1 $PIDFILE`
+	PID=`sed -n 1p $PIDFILE`
 	if [ $PID -lt 0 ];then
 	    PID=`expr 0 - $PID`
 	    echo "$CMDNAME: postgres is running (pid: $PID)"
 	else
 	    echo "$CMDNAME: postmaster is running (pid: $PID)"
 	    echo "Command line was:"
-	    echo "`cat $POSTOPTSFILE`"
+	    cat "$POSTOPTSFILE"
 	fi
 	exit 0
     else
@@ -205,29 +247,29 @@ fi
 
 if [ $op = "stop" -o $op = "restart" ];then
     if [ -f $PIDFILE ];then
-	PID=`head -1 $PIDFILE`
+	PID=`sed -n 1p $PIDFILE`
 	if [ $PID -lt 0 ];then
 	    PID=`expr 0 - $PID`
-	    echo "$CMDNAME: Cannot restart postmaster. postgres is running (pid: $PID)"
-	    echo "Please terminate postgres and try again"
+	    echo "$CMDNAME: Cannot restart postmaster.  postgres is running (pid: $PID)" 1>&2
+	    echo "Please terminate postgres and try again." 1>&2
 	    exit 1
 	fi
 
 	kill $sig $PID
 
 	# wait for postmaster to shut down
-	if [ "$wait" = 1 -o $op = "restart" ];then
+	if [ "$wait" = yes -o "$op" = restart ];then
 	    cnt=0
-	    $ECHO_N "Waiting for postmaster to shut down.."$ECHO_C
+	    $silence_echo $ECHO_N "waiting for postmaster to shut down..."$ECHO_C
 
 	    while :
 	    do
 		if [ -f $PIDFILE ];then
-		    $ECHO_N "."$ECHO_C
+		    $silence_echo $ECHO_N "."$ECHO_C
 		    cnt=`expr $cnt + 1`
-		    if [ $cnt -gt 60 ];then
-			echo "failed."
-			echo "postmaster does not shut down."
+		    if [ $cnt -gt $wait_seconds ];then
+			$silence_echo echo " failed"
+			echo "$CMDNAME: postmaster does not shut down" 1>&2
 			exit 1
 		    fi
 		else
@@ -235,76 +277,102 @@ if [ $op = "stop" -o $op = "restart" ];then
 		fi
 		sleep 1
 	    done
-	    echo "done."
+	    $silence_echo echo "done"
 	fi
+	$silence_echo echo "postmaster successfully shut down"
 
-	echo "postmaster successfully shut down."
-
-    else
-	echo "$CMDNAME: cannot find $PIDFILE"
-	echo "Is postmaster running?"
+    else # ! -f $PIDFILE
+	echo "$CMDNAME: cannot find $PIDFILE" 1>&2
+	echo "Is postmaster running?" 1>&2
 	if [ $op = "restart" ];then
-	    echo "starting postmaster anyway..."
+	    echo "starting postmaster anyway" 1>&2
 	else
 	    exit 1
 	fi
     fi
-fi
+fi # stop or restart
 
 if [ $op = "start" -o $op = "restart" ];then
     if [ -f $PIDFILE ];then
-	echo "$CMDNAME: It seems another postmaster is running. Trying to start postmaster anyway."
-	pid=`head -1 $PIDFILE`
+	echo "$CMDNAME: It seems another postmaster is running.  Trying to start postmaster anyway." 1>&2
+	pid=`sed -n 1p $PIDFILE`
+    fi
+
+    unset logopt
+    if [ -n "$logfile" ]; then
+        logopt='</dev/null >>$logfile 2>&1'
+    else
+        # when starting without log file, redirect stderr to stdout, so
+        # pg_ctl can be invoked with >$logfile and still have pg_ctl's
+        # stderr on the terminal.
+        logopt='</dev/null 2>&1'
     fi
 
     # no -o given
     if [ -z "$POSTOPTS" ];then
 	if [ $op = "start" ];then
 	    # if we are in start mode, then look for postmaster.opts.default
-	    if [ -f $DEFPOSTOPTS ];then
-		$po_path -D $PGDATA `cat $DEFPOSTOPTS` &
-	    else
-		$po_path -D $PGDATA &
+	    if [ -f $DEFPOSTOPTS ]; then
+		POSTOPTS=`cat $DEFPOSTOPTS`
 	    fi
+	    POSTOPTS="-D $PGDATA $POSTOPTS"
 	else
-	    # if we are in restart mode, then look postmaster.opts
-	    `cat $POSTOPTSFILE` &
+	    # if we are in restart mode, then look for postmaster.opts
+	    set X `cat $POSTOPTSFILE`
+	    shift
+            po_path=$1
+            shift
+	    POSTOPTS=$@
 	fi
-    else
-    # -o given
-	$po_path -D $PGDATA $POSTOPTS &
+    else # -o given
+        POSTOPTS="-D $PGDATA $POSTOPTS"
     fi
 
+    eval '$po_path' '$POSTOPTS' $logopt '&'
+
     if [ -f $PIDFILE ];then
-	if [ "`head -1 $PIDFILE`" = "$pid" ];then
-	    echo "$CMDNAME: Cannot start postmaster. Is another postmaster is running?"
+	if [ "`sed -n 1p $PIDFILE`" = "$pid" ];then
+	    echo "$CMDNAME: cannot start postmaster" 1>&2
+	    echo "Examine the log output." 1>&2
 	    exit 1
         fi
     fi
 
-    # wait for postmaster to start up
-    if [ "$wait" = 1 ];then
+    # wait for postmaster to start
+    if [ "$wait" = yes ];then
 	cnt=0
-	$ECHO_N "Waiting for postmaster to start up.."$ECHO_C
+	$silence_echo $ECHO_N "waiting for postmaster to start..."$ECHO_C
 	while :
 	do
+# FIXME:  This is horribly misconceived.
+# 1) If password authentication is set up, the connection will fail.
+# 2) If a virtual host is set up, the connection may fail.
+# 3) If network traffic filters are set up tight enough, the connection
+#    may fail.
+# 4) When no Unix domain sockets are available, the connection will
+#    fail.  (Using TCP/IP by default ain't better.)
+# 5) When a different port is configured, the connection will fail
+#    or go to the wrong server.
+# 6) If the dynamic loader is not set up correctly (for this user/at
+#    this time), psql will fail (to find libpq).
+# 7) If psql is misconfigured, this may fail.
 	    if "$PGPATH/psql" -l >/dev/null 2>&1
 	    then
 		break;
 	    else
-		$ECHO_N "."$ECHO_C
+		$silence_echo $ECHO_N "."$ECHO_C
 		cnt=`expr $cnt + 1`
-		if [ $cnt -gt 60 ];then
-		    echo "$CMDNAME: postmaster does not start up"
+		if [ $cnt -gt $wait_seconds ];then
+		    $silence_echo echo "failed"
+		    echo "$CMDNAME: postmaster does not start" 1>&2
 		    exit 1
 		fi
 		sleep 1
 	    fi
 	done
-	echo "done"
+	$silence_echo echo "done"
     fi
-
-    echo "postmaster successfully started up"
-fi
+    $silence_echo echo "postmaster successfully started"
+fi # start or restart
 
 exit 0