From 29ed8efb3b1e834a5c6f4726fa2516a5af3266a9 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 20 Apr 2021 13:22:11 -0700 Subject: [PATCH] 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 1f7afa9364805a912270c9d6a70dc4a889d47a4e) --- usr.sbin/etcupdate/etcupdate.sh | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/usr.sbin/etcupdate/etcupdate.sh b/usr.sbin/etcupdate/etcupdate.sh index a8432389082..f64e58e4ecd 100755 --- a/usr.sbin/etcupdate/etcupdate.sh +++ b/usr.sbin/etcupdate/etcupdate.sh @@ -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 dir=`dirname /$file` - mkdir -p $1/$dir >&3 2>&1 || return 1 + mkdir -p $1/$dir || return 1 cp -p $SRCDIR/$file $1/$file || 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 -- 2.45.0