← Commit list

7473045ad

Thorsten B
Thorsten B
2026-08-10
SUCCESS Duration: 150s

Subject

tar: fix verbose output with extract-to-stdout

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0
gcc -Wp,-MD,applets/.usage.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer      -Iinclude -Iinclude -o applets/usage applets/usage.c

Build Log

(log yok)

Commit Diff GitHub →

archival/ar.c+2 -1
@@ -194,8 +194,9 @@ static int write_ar_archive(archive_handle_t *handle)
}
#endif /* FEATURE_AR_CREATE */
-static void FAST_FUNC header_verbose_list_ar(const file_header_t *file_header)
+static void FAST_FUNC header_verbose_list_ar(archive_handle_t *archive_handle)
{
+ const file_header_t *file_header = archive_handle->file_header;
char mode[12];
char *mtime;
archival/libarchive/get_header_ar.c+1 -1
@@ -124,7 +124,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)
typed->name[strcspn(typed->name, " /")] = '\0';
if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) {
- archive_handle->action_header(typed);
+ archive_handle->action_header(archive_handle);
#if ENABLE_DPKG || ENABLE_DPKG_DEB
if (archive_handle->dpkg__sub_archive) {
struct archive_handle_t *sa = archive_handle->dpkg__sub_archive;
archival/libarchive/get_header_cpio.c+1 -1
@@ -125,7 +125,7 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
//cpio: etc/hosts not created: newer or same age file exists
//etc/hosts <-- should NOT show it
//2 blocks <-- should say "0 blocks"
- archive_handle->action_header(file_header);
+ archive_handle->action_header(archive_handle);
} else {
data_skip(archive_handle);
}
archival/libarchive/get_header_tar.c+1 -1
@@ -469,7 +469,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
cp = last_char_is(file_header->name, '/');
if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) {
- archive_handle->action_header(/*archive_handle->*/ file_header);
+ archive_handle->action_header(archive_handle);
/* Note that we kill the '/' only after action_header() */
/* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */
if (cp)
archival/libarchive/header_list.c+7 -2
@@ -5,8 +5,13 @@
#include "libbb.h"
#include "bb_archive.h"
-void FAST_FUNC header_list(const file_header_t *file_header)
+void FAST_FUNC header_list(archive_handle_t *archive_handle)
{
//TODO: cpio -vp DIR should output "DIR/NAME", not just "NAME" */
- puts(printable_string(file_header->name));
+
+ const file_header_t *file_header = archive_handle->file_header;
+ /* "tar xvOf TARFILE >OUTFILE" should use stderr for file list output: */
+ FILE *fp = (archive_handle->action_data == data_extract_to_stdout) ? stderr : stdout;
+
+ fprintf(fp, "%s\n", printable_string(file_header->name));
}
archival/libarchive/header_skip.c+1 -1
@@ -5,6 +5,6 @@
#include "libbb.h"
#include "bb_archive.h"
-void FAST_FUNC header_skip(const file_header_t *file_header UNUSED_PARAM)
+void FAST_FUNC header_skip(archive_handle_t *archive_handle UNUSED_PARAM)
{
}
archival/libarchive/header_verbose_list.c+9 -6
@@ -5,11 +5,14 @@
#include "libbb.h"
#include "bb_archive.h"
-void FAST_FUNC header_verbose_list(const file_header_t *file_header)
+void FAST_FUNC header_verbose_list(archive_handle_t *archive_handle)
{
+ const file_header_t *file_header = archive_handle->file_header;
struct tm tm_time;
struct tm *ptm = &tm_time; //localtime(&file_header->mtime);
char modestr[12];
+ /* "tar xvvOf TARFILE >OUTFILE" should use stderr for file list output: */
+ FILE *fp = (archive_handle->action_data == data_extract_to_stdout) ? stderr : stdout;
#if ENABLE_FEATURE_TAR_UNAME_GNAME
char uid[sizeof(int)*3 + 2];
@@ -29,7 +32,7 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header)
/*sprintf(gid, "%u", (unsigned)file_header->gid);*/
group = utoa(file_header->gid);
}
- printf("%s %s/%s %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s",
+ fprintf(fp, "%s %s/%s %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s",
bb_mode_string(modestr, file_header->mode),
user,
group,
@@ -40,13 +43,13 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header)
ptm->tm_hour,
ptm->tm_min,
ptm->tm_sec,
- file_header->name);
+ printable_string(file_header->name));
#else /* !FEATURE_TAR_UNAME_GNAME */
localtime_r(&file_header->mtime, ptm);
- printf("%s %u/%u %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s",
+ fprintf(fp, "%s %u/%u %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s",
bb_mode_string(modestr, file_header->mode),
(unsigned)file_header->uid,
(unsigned)file_header->gid,
@@ -63,7 +66,7 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header)
/* NB: GNU tar shows "->" for symlinks and "link to" for hardlinks */
if (file_header->link_target) {
- printf(" -> %s", printable_string(file_header->link_target));
+ fprintf(fp, " -> %s", printable_string(file_header->link_target));
}
- bb_putchar('\n');
+ putc('\n', fp);
}
include/bb_archive.h+4 -4
@@ -68,7 +68,7 @@ typedef struct archive_handle_t {
llist_t *link_placeholders;
/* Process the header component, e.g. tar -t */
- void FAST_FUNC (*action_header)(const file_header_t *);
+ void FAST_FUNC (*action_header)(struct archive_handle_t *);
/* Process the data component, e.g. extract to filesystem */
void FAST_FUNC (*action_data)(struct archive_handle_t *);
@@ -187,9 +187,9 @@ void data_extract_all(archive_handle_t *archive_handle) FAST_FUNC;
void data_extract_to_stdout(archive_handle_t *archive_handle) FAST_FUNC;
void data_extract_to_command(archive_handle_t *archive_handle) FAST_FUNC;
-void header_skip(const file_header_t *file_header) FAST_FUNC;
-void header_list(const file_header_t *file_header) FAST_FUNC;
-void header_verbose_list(const file_header_t *file_header) FAST_FUNC;
+void header_skip(archive_handle_t *archive_handle) FAST_FUNC;
+void header_list(archive_handle_t *archive_handle) FAST_FUNC;
+void header_verbose_list(archive_handle_t *archive_handle) FAST_FUNC;
char get_header_ar(archive_handle_t *archive_handle) FAST_FUNC;
char get_header_cpio(archive_handle_t *archive_handle) FAST_FUNC;
testsuite/tar.tests+24 -0
@@ -205,6 +205,30 @@ SKIP=
}
cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+mkdir tar.tempdir && cd tar.tempdir || exit 1
+optional FEATURE_TAR_CREATE
+testing "tar xvO sends file list to stderr" '\
+echo "data1" >file1.txt
+echo "data2" >file2.txt
+echo "data3" >file3.txt
+tar cf test.tar file1.txt file2.txt file3.txt
+tar xvOf test.tar >out 2>err
+echo OUT:; cat out
+echo ERR:; cat err
+' "\
+OUT:
+data1
+data2
+data3
+ERR:
+file1.txt
+file2.txt
+file3.txt
+" \
+"" ""
+SKIP=
+cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+
mkdir tar.tempdir && cd tar.tempdir || exit 1
# Had a bug where on extract autodetect first "switched off" -z
# and then failed to recognize .tgz extension