I'd like to try the approach a bit more (especially as this prompted me to simplify it a bit :-). So I installed the first attached patch to Gnulib, to work around the bug in BusyBox 'sed'.

This 'sed' bug was new to me, so I installed the second attached patch to Autoconf, to document the portability problem.

Also, I emailed a bug report to the BusyBox maintainers <http://lists.busybox.net/pipermail/busybox/2022-January/089400.html>.
From 75541c6adaf6fc45541a35d2c8803b9b68f2a7fc Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sat, 1 Jan 2022 15:30:38 -0800
Subject: [PATCH] =?UTF-8?q?gen-header:=20port=20to=20BusyBox=20=E2=80=98se?=
 =?UTF-8?q?d=E2=80=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by Tim Rühsen in:
https://lists.gnu.org/r/bug-gnulib/2022-01/msg00004.html
* modules/gen-header (SED_HEADER_NOEDIT): Replace instead of prepend.
(SED_HEADER_STDOUT, SED_HEADER_TO_AT_t): Adjust to that change.
Do not use ‘w foo’ twice in the same script, as BusyBox ‘sed’
mistakenly opens ‘foo’ for output twice, thus losing some output.
---
 ChangeLog          | 10 ++++++++++
 modules/gen-header | 17 +++++------------
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 21390af8fd..3d837b1c18 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2022-01-01  Paul Eggert  <egg...@cs.ucla.edu>
+
+	gen-header: port to BusyBox ‘sed’
+	Problem reported by Tim Rühsen in:
+	https://lists.gnu.org/r/bug-gnulib/2022-01/msg00004.html
+	* modules/gen-header (SED_HEADER_NOEDIT): Replace instead of prepend.
+	(SED_HEADER_STDOUT, SED_HEADER_TO_AT_t): Adjust to that change.
+	Do not use ‘w foo’ twice in the same script, as BusyBox ‘sed’
+	mistakenly opens ‘foo’ for output twice, thus losing some output.
+
 2022-01-01  Bruno Haible  <br...@clisp.org>
 
 	striconveh: Support an error handler that produces a Unicode U+FFFD.
diff --git a/modules/gen-header b/modules/gen-header
index ab1858d65f..feb711b5c6 100644
--- a/modules/gen-header
+++ b/modules/gen-header
@@ -11,24 +11,17 @@ Depends-on:
 configure.ac:
 
 Makefile.am:
-# In 'sed', prepend a "DO NOT EDIT" comment to the pattern space.
-SED_HEADER_NOEDIT = s,^,/* DO NOT EDIT! GENERATED AUTOMATICALLY! */,
+# In 'sed', replace the pattern space with a "DO NOT EDIT" comment.
+SED_HEADER_NOEDIT = s,.*,/* DO NOT EDIT! GENERATED AUTOMATICALLY! */,
 
 # '$(SED_HEADER_STDOUT) -e "..."' runs 'sed' but first outputs "DO NOT EDIT".
-SED_HEADER_STDOUT = sed \
-  -e x \
-  -e '1$(SED_HEADER_NOEDIT)p' \
-  -e x
+SED_HEADER_STDOUT = sed -e 1h -e '1$(SED_HEADER_NOEDIT)' -e 1G
 
 # '$(SED_HEADER_TO_AT_t) FILE' copies FILE to $@-t, prepending a leading
 # "DO_NOT_EDIT".  Although this could be done more simply via:
 #	SED_HEADER_TO_AT_t = $(SED_HEADER_STDOUT) > $@-t
-# the -n and 'w's avoid a fork+exec, at least when GNU Make is used.
-SED_HEADER_TO_AT_t = sed -n \
-  -e x \
-  -e '1$(SED_HEADER_NOEDIT)w $@-t' \
-  -e x \
-  -e 'w $@-t'
+# the -n and 'w' avoid a fork+exec, at least when GNU Make is used.
+SED_HEADER_TO_AT_t = $(SED_HEADER_STDOUT) -n -e 'w $@-t'
 
 # Use $(gl_V_at) instead of $(AM_V_GEN) or $(AM_V_at) on a line that
 # is its recipe's first line if and only if @NMD@ lines are absent.
-- 
2.32.0

From 1953a1461fee16e0fa4502156fb43e941920ca03 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sat, 1 Jan 2022 18:08:15 -0800
Subject: [PATCH] doc: document BusyBox sed w bug

---
 doc/autoconf.texi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 17a6326e..04730dcc 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -20170,6 +20170,30 @@ s/.*/deleted/g
 :end
 @end example
 
+@item @command{sed} (@samp{w})
+@c ---------------------------
+@prindex @command{sed} (@samp{w})
+
+When a script contains multiple commands to write lines to the same
+output file, BusyBox @command{sed} mistakenly opens a separate output
+stream for each command.  This can cause one of the commands to ``win''
+and the others to ``lose'', in the sense that their output is discarded.
+For example:
+
+@example
+sed -n -e '
+  /a/w xxx
+  /b/w xxx
+' <<EOF
+a
+b
+EOF
+@end example
+
+This might output only @samp{a} to @file{xxx}; the @samp{b} is lost.
+To avoid the problem, a portable script should contain at most one
+@samp{w} or @samp{s/.../.../w} command per output file.
+
 @item @command{sleep}
 @c ------------------
 @prindex @command{sleep}
-- 
2.32.0

Reply via email to