Re: [PATCH] tar: fix verbose output with extract-to-stdout
Guillermo Rodriguez Garcia via busybox <[email protected]> Fri, 31 Jul 2026 00:29:50 +0200
| Newsgroups | gmane.linux.busybox |
|---|---|
| Message-ID | <CABDcavb+F6aavj4JVON+fo_6wNm1wCYBJi8W09qD-CVOwj8syA@mail.gmail.com> |
--===============3375394289143833788== Content-Type: multipart/alternative; boundary="000000000000efaf420657db9c4e" --000000000000efaf420657db9c4e Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Wouldn=E2=80=99t it make more sense to do as GNU tar and write verbose outp= ut to stderr instead when -O is used ? Guillermo Rodriguez Garcia [email protected] El El jue, 30 jul 2026 a las 20:03, ThorstenB via busybox < [email protected]> escribi=C3=B3: > Combining the verbose (-v) and extract-to-stdout (-O) options caused > verbose output and extracted file data to be interleaved unpredictably on > stdout. Verbose listing uses buffered stdio (printf()/puts()), while file > contents are written directly to the stdout file descriptor. > > GNU tar also combines buffered verbose output with unbuffered writes for > "-vO", however, GNU tar writes verbose output to stderr, so the two strea= ms > remain separate and consistent. BusyBox tar writes both to stdout, making > the interaction between buffered and unbuffered output visible. > > Patch only affects the extract-to-stdout ("-O") path, and only when > combined with verbose output. It flushes stdout before writing file > contents so that, for each archive member, verbose output is emitted > before the corresponding file data. > > Includes two test cases. > > function old new delta > data_extract_to_stdout 19 36 +17 > > -------------------------------------------------------------------------= ----- > (add/remove: 0/0 grow/shrink: 1/0 up/down: 17/0) Total: 17 > bytes > > Signed-off-by: ThorstenB <[email protected]> > --- > archival/libarchive/data_extract_to_stdout.c | 3 +++ > .../tar/tar-verbose-extract-to-standard-output | 18 ++++++++++++++++++ > ...tar-very-verbose-extract-to-standard-output | 18 ++++++++++++++++++ > 3 files changed, 39 insertions(+) > create mode 100644 testsuite/tar/tar-verbose-extract-to-standard-output > create mode 100644 > testsuite/tar/tar-very-verbose-extract-to-standard-output > > diff --git a/archival/libarchive/data_extract_to_stdout.c > b/archival/libarchive/data_extract_to_stdout.c > index 520041329..167a15e7c 100644 > --- a/archival/libarchive/data_extract_to_stdout.c > +++ b/archival/libarchive/data_extract_to_stdout.c > @@ -7,6 +7,9 @@ > > void FAST_FUNC data_extract_to_stdout(archive_handle_t *archive_handle) > { > + // flush buffered stdout before writing directly to STDOUT_FILENO > + fflush(stdout); > + > bb_copyfd_exact_size(archive_handle->src_fd, > STDOUT_FILENO, > archive_handle->file_header->size); > diff --git a/testsuite/tar/tar-verbose-extract-to-standard-output > b/testsuite/tar/tar-verbose-extract-to-standard-output > new file mode 100644 > index 000000000..702dac92e > --- /dev/null > +++ b/testsuite/tar/tar-verbose-extract-to-standard-output > @@ -0,0 +1,18 @@ > +# FEATURE: CONFIG_FEATURE_TAR_CREATE > +echo "data 1" > file1.txt > +echo "data 2" > file2.txt > +echo "data 3" > file3.txt > + > +busybox tar cf test.tar file1.txt file2.txt file3.txt > +busybox tar xvOf test.tar > output.txt > + > +cat > expected.txt << 'EOF' > +file1.txt > +data 1 > +file2.txt > +data 2 > +file3.txt > +data 3 > +EOF > + > +cmp expected.txt output.txt > diff --git a/testsuite/tar/tar-very-verbose-extract-to-standard-output > b/testsuite/tar/tar-very-verbose-extract-to-standard-output > new file mode 100644 > index 000000000..b743d3994 > --- /dev/null > +++ b/testsuite/tar/tar-very-verbose-extract-to-standard-output > @@ -0,0 +1,18 @@ > +# FEATURE: CONFIG_FEATURE_TAR_CREATE > +echo "data 1" > file1.txt > +echo "data 2" > file2.txt > +echo "data 3" > file3.txt > + > +busybox tar cf test.tar file1.txt file2.txt file3.txt > +busybox tar xvvOf test.tar > output.txt > + > +# create expected output > +busybox tar tvvf test.tar file1.txt > expected.txt > +cat file1.txt >> expected.txt > +busybox tar tvvf test.tar file2.txt >> expected.txt > +cat file2.txt >> expected.txt > +busybox tar tvvf test.tar file3.txt >> expected.txt > +cat file3.txt >> expected.txt > + > +cmp expected.txt output.txt > + > -- > 2.51.0 > > _______________________________________________ > busybox mailing list > [email protected] > https://lists.busybox.net/mailman/listinfo/busybox > --000000000000efaf420657db9c4e Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"auto">Wouldn=E2=80=99t it make more sense to do as GNU tar and = write verbose output to stderr instead when -O is used ?</div><div><br clea= r=3D"all"><div><div dir=3D"ltr" class=3D"gmail_signature" data-smartmail=3D= "gmail_signature">Guillermo Rodriguez Garcia<br><a href=3D"mailto:guille.ro= [email protected]" target=3D"_blank">[email protected]</a></div></= div></div><div><br><div class=3D"gmail_quote gmail_quote_container"><div di= r=3D"ltr" class=3D"gmail_attr">El El jue, 30 jul 2026 a las 20:03, Thorsten= B via busybox <<a href=3D"mailto:[email protected]">[email protected]= t</a>> escribi=C3=B3:<br></div><blockquote class=3D"gmail_quote" style= =3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Combinin= g the verbose (-v) and extract-to-stdout (-O) options caused<br> verbose output and extracted file data to be interleaved unpredictably on<b= r> stdout. Verbose listing uses buffered stdio (printf()/puts()), while file<b= r> contents are written directly to the stdout file descriptor.<br> <br> GNU tar also combines buffered verbose output with unbuffered writes for<br= > "-vO", however, GNU tar writes verbose output to stderr, so the t= wo streams<br> remain separate and consistent. BusyBox tar writes both to stdout, making<b= r> the interaction between buffered and unbuffered output visible.<br> <br> Patch only affects the extract-to-stdout ("-O") path, and only wh= en<br> combined with verbose output. It flushes stdout before writing file<br> contents so that, for each archive member, verbose output is emitted<br> before the corresponding file data.<br> <br> Includes two test cases.<br> <br> function=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0old=C2=A0 =C2=A0 =C2=A0new=C2=A0 =C2=A0delta<br> data_extract_to_stdout=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 19=C2=A0 =C2=A0= =C2=A0 36=C2=A0 =C2=A0 =C2=A0+17<br> ---------------------------------------------------------------------------= ---<br> (add/remove: 0/0 grow/shrink: 1/0 up/down: 17/0)=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0Total: 17 bytes<br> <br> Signed-off-by: ThorstenB <<a href=3D"mailto:[email protected]" target=3D"= _blank">[email protected]</a>><br> ---<br> =C2=A0archival/libarchive/data_extract_to_stdout.c=C2=A0 =C2=A0|=C2=A0 3 ++= +<br> =C2=A0.../tar/tar-verbose-extract-to-standard-output | 18 +++++++++++++++++= +<br> =C2=A0...tar-very-verbose-extract-to-standard-output | 18 +++++++++++++++++= +<br> =C2=A03 files changed, 39 insertions(+)<br> =C2=A0create mode 100644 testsuite/tar/tar-verbose-extract-to-standard-outp= ut<br> =C2=A0create mode 100644 testsuite/tar/tar-very-verbose-extract-to-standard= -output<br> <br> diff --git a/archival/libarchive/data_extract_to_stdout.c b/archival/libarc= hive/data_extract_to_stdout.c<br> index 520041329..167a15e7c 100644<br> --- a/archival/libarchive/data_extract_to_stdout.c<br> +++ b/archival/libarchive/data_extract_to_stdout.c<br> @@ -7,6 +7,9 @@<br> <br> =C2=A0void FAST_FUNC data_extract_to_stdout(archive_handle_t *archive_handl= e)<br> =C2=A0{<br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0// flush buffered stdout before writing directl= y to STDOUT_FILENO<br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0fflush(stdout);<br> +<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 bb_copyfd_exact_size(archive_handle->src_fd,= <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 STDOUT_FILENO,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 archive_handle->file_header->size);<br> diff --git a/testsuite/tar/tar-verbose-extract-to-standard-output b/testsui= te/tar/tar-verbose-extract-to-standard-output<br> new file mode 100644<br> index 000000000..702dac92e<br> --- /dev/null<br> +++ b/testsuite/tar/tar-verbose-extract-to-standard-output<br> @@ -0,0 +1,18 @@<br> +# FEATURE: CONFIG_FEATURE_TAR_CREATE<br> +echo "data 1" > file1.txt<br> +echo "data 2" > file2.txt<br> +echo "data 3" > file3.txt<br> +<br> +busybox tar cf test.tar file1.txt file2.txt file3.txt<br> +busybox tar xvOf test.tar > output.txt<br> +<br> +cat > expected.txt << 'EOF'<br> +file1.txt<br> +data 1<br> +file2.txt<br> +data 2<br> +file3.txt<br> +data 3<br> +EOF<br> +<br> +cmp expected.txt output.txt<br> diff --git a/testsuite/tar/tar-very-verbose-extract-to-standard-output b/te= stsuite/tar/tar-very-verbose-extract-to-standard-output<br> new file mode 100644<br> index 000000000..b743d3994<br> --- /dev/null<br> +++ b/testsuite/tar/tar-very-verbose-extract-to-standard-output<br> @@ -0,0 +1,18 @@<br> +# FEATURE: CONFIG_FEATURE_TAR_CREATE<br> +echo "data 1" > file1.txt<br> +echo "data 2" > file2.txt<br> +echo "data 3" > file3.txt<br> +<br> +busybox tar cf test.tar file1.txt file2.txt file3.txt<br> +busybox tar xvvOf test.tar > output.txt<br> +<br> +# create expected output<br> +busybox tar tvvf test.tar file1.txt > expected.txt<br> +cat file1.txt >> expected.txt<br> +busybox tar tvvf test.tar file2.txt >> expected.txt<br> +cat file2.txt >> expected.txt<br> +busybox tar tvvf test.tar file3.txt >> expected.txt<br> +cat file3.txt >> expected.txt<br> +<br> +cmp expected.txt output.txt<br> +<br> -- <br> 2.51.0<br> <br> _______________________________________________<br> busybox mailing list<br> <a href=3D"mailto:[email protected]" target=3D"_blank">[email protected]= t</a><br> <a href=3D"https://lists.busybox.net/mailman/listinfo/busybox" rel=3D"noref= errer" target=3D"_blank">https://lists.busybox.net/mailman/listinfo/busybox= </a><br> </blockquote></div></div> --000000000000efaf420657db9c4e-- --===============3375394289143833788== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ busybox mailing list [email protected] https://lists.busybox.net/mailman/listinfo/busybox --===============3375394289143833788==--