etcupdate: Gracefully handle SIGINT when building trees.

Run the 'build_tree' function inside of a subshell and trap SIGINT to
return an error to the caller.  This allows callers to gracefully
cleanup a partially created tree.

While here, redirect stdout/stderr of the subshell to the log file
instead of applying redirections individually to each command executed
while building the tree.

Reviewed by:	imp
Differential Revision:	https://reviews.freebsd.org/D29844

(cherry picked from commit 1f7afa9364)
This commit is contained in:
John Baldwin 2021-04-20 13:22:11 -07:00
parent 5452cb6bf9
commit 6d55189fe7

View file

@ -179,17 +179,21 @@ always_install()
return 1
}
# Build a new tree
# Build a new tree. This runs inside a subshell to trap SIGINT.
#
# $1 - directory to store new tree in
build_tree()
{
(
local destdir dir file make
make="make $MAKE_OPTIONS -DNO_FILEMON"
log "Building tree at $1 with $make"
mkdir -p $1/usr/obj >&3 2>&1
exec >&3 2>&1
trap 'return 1' INT
mkdir -p $1/usr/obj
destdir=`realpath $1`
if [ -n "$preworld" ]; then
@ -197,34 +201,33 @@ build_tree()
# crucial to installworld.
for file in $PREWORLD_FILES; do
name=$(basename $file)
mkdir -p $1/etc >&3 2>&1 || return 1
mkdir -p $1/etc || return 1
cp -p $SRCDIR/$file $1/etc/$name || return 1
done
elif ! [ -n "$nobuild" ]; then
(cd $SRCDIR; $make DESTDIR=$destdir distrib-dirs &&
MAKEOBJDIRPREFIX=$destdir/usr/obj $make _obj SUBDIR_OVERRIDE=etc &&
MAKEOBJDIRPREFIX=$destdir/usr/obj $make everything SUBDIR_OVERRIDE=etc &&
MAKEOBJDIRPREFIX=$destdir/usr/obj $make DESTDIR=$destdir distribution) \
>&3 2>&1 || return 1
MAKEOBJDIRPREFIX=$destdir/usr/obj $make DESTDIR=$destdir distribution) || \
return 1
else
(cd $SRCDIR; $make DESTDIR=$destdir distrib-dirs &&
$make DESTDIR=$destdir distribution) >&3 2>&1 || return 1
$make DESTDIR=$destdir distribution) || return 1
fi
chflags -R noschg $1 >&3 2>&1 || return 1
rm -rf $1/usr/obj >&3 2>&1 || return 1
chflags -R noschg $1 || return 1
rm -rf $1/usr/obj || return 1
# Purge auto-generated files. Only the source files need to
# be updated after which these files are regenerated.
rm -f $1/etc/*.db $1/etc/passwd $1/var/db/services.db >&3 2>&1 || \
return 1
rm -f $1/etc/*.db $1/etc/passwd $1/var/db/services.db || return 1
# Remove empty files. These just clutter the output of 'diff'.
find $1 -type f -size 0 -delete >&3 2>&1 || return 1
find $1 -type f -size 0 -delete || return 1
# Trim empty directories.
find -d $1 -type d -empty -delete >&3 2>&1 || return 1
find -d $1 -type d -empty -delete || return 1
return 0
}
)
# Generate a new tree. If tarball is set, then the tree is
# extracted from the tarball. Otherwise the tree is built from a