Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Allow "echo -n" to work as expected in rc.d scripts that are...



details:   https://anonhg.NetBSD.org/src/rev/d7d25b35621d
branches:  trunk
changeset: 768211:d7d25b35621d
user:      apb <apb%NetBSD.org@localhost>
date:      Thu Aug 11 22:52:46 2011 +0000

description:
Allow "echo -n" to work as expected in rc.d scripts that are executed
by /etc/rc.  Similarly for printf with a format that does not end with
"\n".  Previously, the partial line would not be visible on the console
until a newline was printed, possibly after an annoying delay.

This is done by adding echo() and printf() shell functions to rc.subr,
so that naive use of the echo and printf commands in rc.d scripts will
call these functions instead of the underlying commands.  These shell
functions send a new "nop" metadata message after the partial line, and
the rc_postprocess function in /etc/rc disentangles the partial line of
plain output from the metadata "nop".

Also add a "-n" option to the print_rc_normal function in rc.subr,
and make some cosmetic changes.

diffstat:

 etc/rc                   |  43 +++++++++++++++++++++--
 etc/rc.subr              |  89 +++++++++++++++++++++++++++++++++++++++--------
 share/man/man8/rc.subr.8 |  37 ++++++++++++++-----
 3 files changed, 139 insertions(+), 30 deletions(-)

diffs (truncated from 313 to 300 lines):

diff -r 4fce1ed0997e -r d7d25b35621d etc/rc
--- a/etc/rc    Thu Aug 11 22:38:25 2011 +0000
+++ b/etc/rc    Thu Aug 11 22:52:46 2011 +0000
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $NetBSD: rc,v 1.165 2010/06/04 18:42:54 christos Exp $
+# $NetBSD: rc,v 1.166 2011/08/11 22:52:47 apb Exp $
 #
 # rc --
 #      Run the scripts in /etc/rc.d with rcorder, and log output
@@ -24,6 +24,10 @@
 
 : ${RC_LOG_FILE:="/var/run/rc.log"}
 
+# rc.subr redefines echo and printf.  Undo that here.
+unset echo ; unalias echo
+unset printf ; unalias printf
+
 if ! checkyesno rc_configured; then
        echo "/etc/rc.conf is not configured.  Multiuser boot aborted."
        exit 1
@@ -194,9 +198,10 @@
                        ;;
                *"${rc_metadata_prefix}"*)
                        # magic string is present, but not at the start of
-                       # the line.  Treat it like two separate lines.
+                       # the line.  Treat it as a partial line of
+                       # ordinary data, followed by a line of metadata.
                        before="${line%"${rc_metadata_prefix}"*}"
-                       rc_postprocess_plain_line "${before}"
+                       rc_postprocess_partial_line "${before}"
                        after="${line#*"${rc_metadata_prefix}"}"
                        rc_postprocess_metadata "${after}"
                        ;;
@@ -233,6 +238,22 @@
 }
 
 #
+# rc_postprocess_partial_line string
+#      This is just like rc_postprocess_plain_line, except that
+#      a newline is not appended to the string.
+#
+rc_postprocess_partial_line()
+{
+       local line="$1"
+       rc_log_message_n "${line}"
+       if $rc_silent; then
+               eval "$rc_silent_cmd"
+       else
+               printf "%s" "${line}"
+       fi
+}
+
+#
 # rc_postprocess_metadata string
 #      $1 is a string containing metadata from the rc_real_work()
 #      function.  The rc_metadata_prefix marker should already
@@ -284,6 +305,9 @@
                        ;;
                esac
                ;;
+       nop)
+               # Do nothing.
+               ;;
        note)
                rc_log_message "[NOTE: $args]"
                ;;
@@ -323,7 +347,8 @@
 
 #
 # rc_log_message string [...]
-#      write a message to the log file, or buffer it for later.
+#      Write a message to the log file, or buffer it for later.
+#      This function appends a newline to the message.
 #
 rc_log_message()
 {
@@ -332,6 +357,16 @@
 }
 
 #
+# rc_log_message_n string [...]
+#      Just like rc_log_message, except without appending a newline.
+#
+rc_log_message_n()
+{
+       _rc_log_buffer="${_rc_log_buffer}${*}"
+       rc_log_flush
+}
+
+#
 # rc_log_flush [OK|FORCE]
 #      save outstanding messages from $_rc_log_buffer to $RC_LOG_FILE.
 #
diff -r 4fce1ed0997e -r d7d25b35621d etc/rc.subr
--- a/etc/rc.subr       Thu Aug 11 22:38:25 2011 +0000
+++ b/etc/rc.subr       Thu Aug 11 22:52:46 2011 +0000
@@ -1,6 +1,6 @@
-# $NetBSD: rc.subr,v 1.87 2011/06/09 14:52:01 christos Exp $
+# $NetBSD: rc.subr,v 1.88 2011/08/11 22:52:47 apb Exp $
 #
-# Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
+# Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
 # All rights reserved.
 #
 # This code is derived from software contributed to The NetBSD Foundation
@@ -542,9 +542,11 @@
                        fi
                        for _elem in $_keywords; do
                                if [ "$_elem" = "$rc_arg" ]; then
-                                       echo 1>&2 "\$${rcvar} is not enabled - see ${rcvar_manpage}."
-                                       echo 1>&2 "Use the following if you wish to perform the operation:"
-                                       echo 1>&2 "  $0 one${rc_arg}"
+                                       cat 1>&2 <<EOF
+\$${rcvar} is not enabled - see ${rcvar_manpage}.
+Use the following if you wish to perform the operation:
+  $0 one${rc_arg}
+EOF
                                        exit 1
                                fi
                        done
@@ -1113,28 +1115,58 @@
        # print, prefixing the output with $_rc_metadata_prefix.
        #
        if [ -n "$_rc_postprocessor_fd" ]; then
-               printf "%s%s\n" "$rc_metadata_prefix" "$1" \
+               command printf "%s%s\n" "$rc_metadata_prefix" "$1" \
                        >&${_rc_postprocessor_fd}
        fi
 }
 
 #
-# print_rc_normal string
+# _flush_rc_output
+#      Arrange for output to be flushed, if we are running
+#      inside /etc/rc with postprocessing.
+#
+_flush_rc_output()
+{
+       print_rc_metadata "nop"
+}
+
+#
+# print_rc_normal [-n] string
 #      Print the specified string in such way that it is treated as
 #      normal output, regardless of whether or not we are running
 #      inside /etc/rc with post-processing.
 #
-#      Ths intent is that a script that is run via the
-#      no_rc_postprocess() function (so its output would ordinarily be
-#      invisible to the post-processor) can nevertheless arrange for
-#      the post-processor to see things printed with print_rc_normal().
+#      If "-n" is specified in $1, then the string in $2 is printed
+#      without a newline; otherwise, the string in $1 is printed
+#      with a newline.
+#
+#      Intended use cases include:
+#
+#      o   An rc.d script can use ``print_rc_normal -n'' to print a
+#          partial line in such a way that it appears immediately
+#          instead of being buffered by rc(8)'s post-processor.
+#
+#      o   An rc.d script that is run via the no_rc_postprocess
+#          function (so most of its output is invisible to rc(8)'s
+#          post-processor) can use print_rc_normal to force some of its
+#          output to be seen by the post-processor.
+#
 #
 print_rc_normal()
 {
        # If _rc_postprocessor_fd is defined, then it is the fd
-       # to shich we must print; otherwise print to stdout.
+       # to which we must print; otherwise print to stdout.
        #
-       printf "%s\n" "$1" >&${_rc_postprocessor_fd:-1}
+       local fd="${_rc_postprocessor_fd:-1}"
+       case "$1" in
+       "-n")
+               command printf "%s" "$2" >&${fd}
+               _flush_rc_output
+               ;;
+       *)
+               command printf "%s\n" "$1" >&${fd}
+               ;;
+       esac
 }
 
 #
@@ -1178,7 +1210,7 @@
        '\')    _next='|' ;;
        *)      _next='/' ;;
        esac
-       printf "%s\b" "$_next" >/dev/tty
+       command printf "%s\b" "$_next" >/dev/tty
        _twiddle_state="$_next"
 }
 
@@ -1214,14 +1246,39 @@
                case "$line" in
                *\\)
                        # print it, without the backslash or newline
-                       printf "%s" "${line%?}"
+                       command printf "%s" "${line%?}"
                        ;;
                *)
                        # print it, with a newline
-                       printf "%s\n" "${line}"
+                       command printf "%s\n" "${line}"
                        ;;
                esac
        done
 }
 
+# Override the normal "echo" and "printf" commands, so that
+# partial lines printed by rc.d scripts appear immediately,
+# instead of being buffered by rc(8)'s post-processor.
+#
+# Naive use of the echo or printf commands from rc.d scripts,
+# elsewhere in rc.subr, or anything else that sources rc.subr,
+# will call these functions.  To call the real echo and printf
+# commands, use "command echo" or "command printf".
+#
+echo()
+{
+       command echo "$@"
+       case "$1" in
+       '-n')   _flush_rc_output ;;
+       esac
+}
+printf()
+{
+       command printf "$@"
+       case "$1" in
+       *'\n')  : ;;
+       *)      _flush_rc_output ;;
+       esac
+}
+
 _rc_subr_loaded=:
diff -r 4fce1ed0997e -r d7d25b35621d share/man/man8/rc.subr.8
--- a/share/man/man8/rc.subr.8  Thu Aug 11 22:38:25 2011 +0000
+++ b/share/man/man8/rc.subr.8  Thu Aug 11 22:52:46 2011 +0000
@@ -1,6 +1,6 @@
-.\"    $NetBSD: rc.subr.8,v 1.28 2010/09/26 18:52:52 apb Exp $
+.\"    $NetBSD: rc.subr.8,v 1.29 2011/08/11 22:52:46 apb Exp $
 .\"
-.\" Copyright (c) 2002-2004 The NetBSD Foundation, Inc.
+.\" Copyright (c) 2002-2011 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This code is derived from software contributed to The NetBSD Foundation
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd September 26, 2010
+.Dd August 11, 2011
 .Dt RC.SUBR 8
 .Os
 .Sh NAME
@@ -60,7 +60,7 @@
 .It
 .Ic print_rc_metadata Ar string
 .It
-.Ic print_rc_normal Ar string
+.Ic print_rc_normal Oo Fl n Oc Ar string
 .It
 .Ic rc_usage Ar command Op Ar ...
 .It
@@ -315,7 +315,7 @@
 .Xr rc 8
 and
 .Nm .
-.It Ic print_rc_normal Ar string
+.It Ic print_rc_normal Oo Fl n Oc Ar string
 Print the specified
 .Ar string
 in such a way that it should be handled as normal output by the
@@ -327,11 +327,28 @@
 .Ar string
 is printed to standard output.
 .Pp
-Ths intent is that a script that is run via the
-.Fn no_rc_postprocess
-function (so its output would ordinarily be invisible to the post-processor)
-can nevertheless arrange for the post-processor to see things printed with
-.Fn print_rc_normal.
+If the
+.Fl n
+flag is specified, then the string is printed without a newline.
+.Pp
+Intended use cases include:
+.Bl -bullet
+.It
+An rc.d script can use
+.Dq Sy print_rc_normal Fl n
+to print a partial line in such a way that it appears
+immediately instead of being buffered by
+.Xr rc 8 Ap s



Home | Main Index | Thread Index | Old Index