In rc.subr, add _have_rc_postprocessor function and use it instead of
inline tests like [ -n "${_rc_postprocessor_fd}" ]. The new function performs a few new tests, including verifying that /etc/rc is still running (using a new _rc_pid variable set by /etc/rc). This is intended to deal with the case that a script run from /etc/rc spawns a background process, then /etc/rc exits, but the background process still has environment variables inherited from /etc/rc. Fixes PR 46546.
This commit is contained in:
parent
e3566c1bef
commit
7bc384757f
3
etc/rc
3
etc/rc
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: rc,v 1.168 2014/04/09 12:45:05 apb Exp $
|
||||
# $NetBSD: rc,v 1.169 2014/07/27 07:46:46 apb Exp $
|
||||
#
|
||||
# rc --
|
||||
# Run the scripts in /etc/rc.d with rcorder, and log output
|
||||
|
@ -84,6 +84,7 @@ rc_real_work()
|
|||
# with redirected output.
|
||||
#
|
||||
_rc_postprocessor_fd=9 ; export _rc_postprocessor_fd
|
||||
_rc_pid=$$ ; export _rc_pid
|
||||
eval "exec ${_rc_postprocessor_fd}>&1"
|
||||
|
||||
# Print a metadata line when we exit
|
||||
|
|
49
etc/rc.subr
49
etc/rc.subr
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: rc.subr,v 1.93 2014/07/22 17:11:09 wiz Exp $
|
||||
# $NetBSD: rc.subr,v 1.94 2014/07/27 07:46:46 apb Exp $
|
||||
#
|
||||
# Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
|
@ -785,6 +785,35 @@ $command $rc_flags $command_args"
|
|||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# _have_rc_postprocessor
|
||||
# Test whether the current script is running in a context that
|
||||
# was invoked from /etc/rc with a postprocessor.
|
||||
#
|
||||
# If the test fails, some variables may be unset to make
|
||||
# such tests more efficient in future.
|
||||
#
|
||||
_have_rc_postprocessor()
|
||||
{
|
||||
# Cheap tests that fd and pid are set, fd is writable.
|
||||
[ -n "${_rc_postprocessor_fd}" ] || return 1
|
||||
[ -n "${_rc_pid}" ] || return 1
|
||||
eval ": >&${_rc_postprocessor_fd}" 2>/dev/null || return 1
|
||||
|
||||
# More expensive test that pid is running.
|
||||
# Unset _rc_pid if this fails.
|
||||
kill -0 "${_rc_pid}" 2>/dev/null \
|
||||
|| { unset _rc_pid; return 1; }
|
||||
|
||||
# More expensive test that pid appears to be
|
||||
# a shell running an rc script.
|
||||
# Unset _rc_pid if this fails.
|
||||
expr "$(ps -p "${_rc_pid}" -o command=)" : ".*sh .*/rc.*" >/dev/null \
|
||||
|| { unset _rc_pid; return 1; }
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# run_rc_script file arg
|
||||
# Start the script `file' with `arg', and correctly handle the
|
||||
|
@ -794,9 +823,8 @@ $command $rc_flags $command_args"
|
|||
# executable run as a child process.
|
||||
#
|
||||
# If `file' contains "KEYWORD: interactive" and if we are
|
||||
# running inside /etc/rc with postprocessing (as signified by
|
||||
# _rc_postprocessor_fd being defined) then the script's stdout
|
||||
# and stderr are redirected to $_rc_original_stdout_fd and
|
||||
# running inside /etc/rc with postprocessing, then the script's
|
||||
# stdout and stderr are redirected to $_rc_original_stdout_fd and
|
||||
# $_rc_original_stderr_fd, so the output will be displayed on the
|
||||
# console but not intercepted by /etc/rc's postprocessor.
|
||||
#
|
||||
|
@ -816,7 +844,7 @@ run_rc_script()
|
|||
eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd
|
||||
|
||||
_must_redirect=false
|
||||
if [ -n "${_rc_postprocessor_fd}" ] \
|
||||
if _have_rc_postprocessor \
|
||||
&& _has_rcorder_keyword interactive $_file
|
||||
then
|
||||
_must_redirect=true
|
||||
|
@ -1114,7 +1142,7 @@ print_rc_metadata()
|
|||
# _rc_postprocessor fd, if defined, is the fd to which we must
|
||||
# print, prefixing the output with $_rc_metadata_prefix.
|
||||
#
|
||||
if [ -n "$_rc_postprocessor_fd" ]; then
|
||||
if _have_rc_postprocessor; then
|
||||
command printf "%s%s\n" "$rc_metadata_prefix" "$1" \
|
||||
>&${_rc_postprocessor_fd}
|
||||
fi
|
||||
|
@ -1154,10 +1182,11 @@ _flush_rc_output()
|
|||
#
|
||||
print_rc_normal()
|
||||
{
|
||||
# If _rc_postprocessor_fd is defined, then it is the fd
|
||||
# to which we must print; otherwise print to stdout.
|
||||
# print to stdout or _rc_postprocessor_fd, depending on
|
||||
# whether not we have an rc postprocessor.
|
||||
#
|
||||
local fd="${_rc_postprocessor_fd:-1}"
|
||||
local fd=1
|
||||
_have_rc_postprocessor && fd="${_rc_postprocessor_fd}"
|
||||
case "$1" in
|
||||
"-n")
|
||||
command printf "%s" "$2" >&${fd}
|
||||
|
@ -1186,7 +1215,7 @@ print_rc_normal()
|
|||
#
|
||||
no_rc_postprocess()
|
||||
{
|
||||
if [ -n "${_rc_postprocessor_fd}" ]; then
|
||||
if _have_rc_postprocessor; then
|
||||
"$@" >&${_rc_original_stdout_fd} 2>&${_rc_original_stderr_fd}
|
||||
else
|
||||
"$@"
|
||||
|
|
Loading…
Reference in New Issue