trap commands in auxiliary scripts

Bruno Haible via Discussion list for automake <[email protected]> Sat, 30 May 2026 00:29:32 +0200
Newsgroups gmane.comp.sysutils.automake.general
Organization GNU
Message-ID <15756765.tv2OnDr8pf@nimes>
This is a multi-part message in MIME format.

--nextPart4377417.1IzOArtZ34
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"

'trap' commands in shell scripts present a dilemma:

  - If we use double-quotes to delimit the command
      trap "rmdir '$lockdir'; exit 1" 1 2 15
    we get undefined behaviour if $lockdir contains a single-quote,
    and also some backslashes might be needed here and there, for
    quoting.

  - If we use single-quotes to delimit the command
      trap 'rmdir "$lockdir"; exit 1' 1 2 15
    we soon get into a quoting trouble if the command contains single-quotes.

The best way out, for safety AND maintainability, is to move the bulk
of the command's body into a shell function and then just invoke that
shell function. Then, no unusual quoting is needed at all.

Here's a proposed patch.


--nextPart4377417.1IzOArtZ34
Content-Disposition: attachment;
 filename="0001-compile-depcomp-ylwrap-Fix-quoting-bug-in-trap-comma.patch"
Content-Transfer-Encoding: quoted-printable
Content-Type: text/x-patch; charset="x-UTF_8J";
 name="0001-compile-depcomp-ylwrap-Fix-quoting-bug-in-trap-comma.patch"

=46rom 3b488dd30879405759622d9ba66771119691b014 Mon Sep 17 00:00:00 2001
=46rom: Bruno Haible <[email protected]>
Date: Fri, 29 May 2026 15:55:27 +0200
Subject: [PATCH] compile, depcomp, ylwrap: Fix quoting bug in 'trap' comman=
d.
MIME-Version: 1.0
Content-Type: text/plain; charset=3DUTF-8
Content-Transfer-Encoding: 8bit

Reported by an AI tool in the name of Micha=C5=82 Majchrowicz.

Based on the idea from Autoconf commit 416b8f50c9bd4e38f9bc48b946505d2a18f6=
b1fd:
Use a shell function to avoid quoting hassles inside a 'trap' argument.

* lib/compile (cleanup): New function.
(trap): Use it.
* lib/depcomp (cleanup): New function.
(trap): Use it.
* lib/ylwrap (origdirname): New variable.
(cleanup): New function.
(do_exit): Use it.
=2D--
 lib/compile | 5 ++++-
 lib/depcomp | 8 ++++----
 lib/ylwrap  | 6 +++++-
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/lib/compile b/lib/compile
index 02ff093c3..1feb2a2d2 100755
=2D-- a/lib/compile
+++ b/lib/compile
@@ -338,7 +338,10 @@ while true; do
   sleep 1
 done
 # FIXME: race condition here if user kills between mkdir and trap.
=2Dtrap "rmdir '$lockdir'; exit 1" 1 2 15
+cleanup () {
+  rmdir "$lockdir"
+}
+trap "cleanup; exit 1" 1 2 15
=20
 # Run the compile.
 "$@"
diff --git a/lib/depcomp b/lib/depcomp
index 9f6725b9e..ed5bef5f0 100755
=2D-- a/lib/depcomp
+++ b/lib/depcomp
@@ -383,11 +383,11 @@ pgcc)
   # problems in parallel builds.  Use a locking strategy to avoid stomping=
 on
   # the same $tmpdepfile.
   lockdir=3D$base.d-lock
=2D  trap "
+  cleanup () {
     echo '$0: caught signal, cleaning up...' >&2
=2D    rmdir '$lockdir'
=2D    exit 1
=2D  " 1 2 13 15
+    rmdir "$lockdir"
+  }
+  trap "cleanup; exit 1" 1 2 13 15
   numtries=3D100
   i=3D$numtries
   while test $i -gt 0; do
diff --git a/lib/ylwrap b/lib/ylwrap
index 62aed82da..1d3117bf9 100755
=2D-- a/lib/ylwrap
+++ b/lib/ylwrap
@@ -159,8 +159,12 @@ case $prog in
   *[\\/]*) prog=3D`pwd`/$prog ;;
 esac
=20
+origdirname=3D`pwd`
 dirname=3Dylwrap$$
=2Ddo_exit=3D"cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret)=
; exit $ret'
+cleanup () {
+  cd "$origdirname" && rm -rf $dirname > /dev/null 2>&1
+}
+do_exit=3D'cleanup; (exit $ret); exit $ret'
 trap "ret=3D129; $do_exit" 1
 trap "ret=3D130; $do_exit" 2
 trap "ret=3D141; $do_exit" 13
=2D-=20
2.54.0


--nextPart4377417.1IzOArtZ34--