From brehmt at gmail.com Sat Aug 1 10:13:28 2026 From: brehmt at gmail.com (ThorstenB) Date: Sat, 1 Aug 2026 12:13:28 +0200 Subject: [PATCH v2] tar/cpio: fix verbose output with to-stdout option Message-ID: <20260801101328.14064-1-brehmt@gmail.com> When verbose/-v and -O/--to-stdout options are combined, verbose output needs to be sent to stderr instead. Verbose output also needs to be line-buffered, so for each archive member, verbose output is emitted before extracting the corresponding file data (tar), (after the file data for cpio). Aligns the behavior with the GNU tar/cpio utilities. Includes test cases. function old new delta cpio_main 565 603 +38 header_list 17 52 +35 header_verbose_list 283 305 +22 tar_main 1195 1210 +15 init_handle 69 80 +11 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/0 up/down: 121/0) Total: 121 bytes Signed-off-by: ThorstenB --- archival/cpio.c | 5 ++- archival/libarchive/header_list.c | 4 +- archival/libarchive/header_verbose_list.c | 11 +++-- archival/libarchive/init_handle.c | 1 + archival/tar.c | 5 ++- include/bb_archive.h | 1 + .../cpio/cpio-verbose-to-standard-output | 44 +++++++++++++++++++ .../tar-verbose-extract-to-standard-output | 41 +++++++++++++++++ ...ar-very-verbose-extract-to-standard-output | 39 ++++++++++++++++ 9 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 testsuite/cpio/cpio-verbose-to-standard-output 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/cpio.c b/archival/cpio.c index b033b3733..eb7a2eeaa 100644 --- a/archival/cpio.c +++ b/archival/cpio.c @@ -543,8 +543,11 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) } if (opt & OPT_EXTRACT) { archive_handle->action_data = data_extract_all; - if (opt & OPT_2STDOUT) + if (opt & OPT_2STDOUT) { archive_handle->action_data = data_extract_to_stdout; + /* If data goes to stdout, verbose goes to stderr */ + archive_handle->file_header->verbose_fp = stderr; + } } if (opt & OPT_UNCONDITIONAL) { archive_handle->ah_flags |= ARCHIVE_UNLINK_OLD; diff --git a/archival/libarchive/header_list.c b/archival/libarchive/header_list.c index 9490b3635..c2105d223 100644 --- a/archival/libarchive/header_list.c +++ b/archival/libarchive/header_list.c @@ -8,5 +8,7 @@ void FAST_FUNC header_list(const file_header_t *file_header) { //TODO: cpio -vp DIR should output "DIR/NAME", not just "NAME" */ - puts(printable_string(file_header->name)); + fputs(printable_string(file_header->name), file_header->verbose_fp); + fputc('\n', file_header->verbose_fp); + fflush(file_header->verbose_fp); } diff --git a/archival/libarchive/header_verbose_list.c b/archival/libarchive/header_verbose_list.c index e7a09430d..303606b9c 100644 --- a/archival/libarchive/header_verbose_list.c +++ b/archival/libarchive/header_verbose_list.c @@ -29,7 +29,8 @@ 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(file_header->verbose_fp, + "%s %s/%s %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s", bb_mode_string(modestr, file_header->mode), user, group, @@ -46,7 +47,8 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header) localtime_r(&file_header->mtime, ptm); - printf("%s %u/%u %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s", + fprintf(file_header->verbose_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 +65,8 @@ 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(file_header->verbose_fp, " -> %s", printable_string(file_header->link_target)); } - bb_putchar('\n'); + fputc('\n', file_header->verbose_fp); + fflush(file_header->verbose_fp); } diff --git a/archival/libarchive/init_handle.c b/archival/libarchive/init_handle.c index 4c64dac58..14a8fe9c3 100644 --- a/archival/libarchive/init_handle.c +++ b/archival/libarchive/init_handle.c @@ -12,6 +12,7 @@ archive_handle_t* FAST_FUNC init_handle(void) /* Initialize default values */ archive_handle = xzalloc(sizeof(archive_handle_t)); archive_handle->file_header = xzalloc(sizeof(file_header_t)); + archive_handle->file_header->verbose_fp = stdout; archive_handle->action_header = header_skip; archive_handle->action_data = data_skip; archive_handle->filter = filter_accept_all; diff --git a/archival/tar.c b/archival/tar.c index 87ad7bb49..54f59d527 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -1075,8 +1075,11 @@ int tar_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_EXTRACT) tar_handle->action_data = data_extract_all; - if (opt & OPT_2STDOUT) + if (opt & OPT_2STDOUT) { tar_handle->action_data = data_extract_to_stdout; + /* If archive goes to stdout, verbose goes to stderr */ + tar_handle->file_header->verbose_fp = stderr; + } if (opt & OPT_2COMMAND) { putenv((char*)"TAR_FILETYPE=f"); diff --git a/include/bb_archive.h b/include/bb_archive.h index 1dc77f31d..aeca1daef 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h @@ -41,6 +41,7 @@ typedef struct file_header_t { mode_t mode; time_t mtime; dev_t device; + FILE* verbose_fp; } file_header_t; struct hardlinks_t; diff --git a/testsuite/cpio/cpio-verbose-to-standard-output b/testsuite/cpio/cpio-verbose-to-standard-output new file mode 100644 index 000000000..9c8267bff --- /dev/null +++ b/testsuite/cpio/cpio-verbose-to-standard-output @@ -0,0 +1,44 @@ +##################################################### +# create test archive +##################################################### +echo "data 1" > file1.txt +echo "data 2" > file2.txt +echo "data 3" > file3.txt +printf '%s\n' file1.txt file2.txt file3.txt | busybox cpio -o -H newc > archive.cpio + +mkdir output +cd output + +##################################################### +# cpio -v --to-stdout: verbose goes to to stderr instead +##################################################### +busybox cpio -iv --to-stdout < ../archive.cpio 2> stderr.txt > /dev/null + +cat > expected.txt << 'EOF' +file1.txt +file2.txt +file3.txt +1 blocks +EOF + +cmp expected.txt stderr.txt + +rm -f file1.txt file2.txt file3.txt + +##################################################### +# is stdout/stderr properly synchronized? +##################################################### +busybox cpio -iv --to-stdout < ../archive.cpio > output.txt 2>&1 + +cat > expected.txt << 'EOF' +data 1 +file1.txt +data 2 +file2.txt +data 3 +file3.txt +1 blocks +EOF + +cmp expected.txt output.txt + 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..3433920e2 --- /dev/null +++ b/testsuite/tar/tar-verbose-extract-to-standard-output @@ -0,0 +1,41 @@ +# FEATURE: CONFIG_FEATURE_TAR_CREATE + +##################################################### +# create test tar +##################################################### +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 + + +##################################################### +# tar vO: verbose goes to to stderr instead +##################################################### +busybox tar xvOf test.tar 2> stderr.txt > /dev/null + +cat > expected.txt << 'EOF' +file1.txt +file2.txt +file3.txt +EOF + +cmp expected.txt stderr.txt + + +##################################################### +# is stdout/stderr properly synchronized? +##################################################### +busybox tar xvOf test.tar > output.txt 2>&1 + +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..82f88eddc --- /dev/null +++ b/testsuite/tar/tar-very-verbose-extract-to-standard-output @@ -0,0 +1,39 @@ +# FEATURE: CONFIG_FEATURE_TAR_CREATE + +##################################################### +# create test tar +##################################################### +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 + + +##################################################### +# tar vvO: very verbose output goes to to stderr +##################################################### +busybox tar xvvOf test.tar 2> stderr.txt > /dev/null + +# create expected output +busybox tar tvvf test.tar file1.txt > expected.txt +busybox tar tvvf test.tar file2.txt >> expected.txt +busybox tar tvvf test.tar file3.txt >> expected.txt + +cmp expected.txt stderr.txt + + +##################################################### +# is stdout/stderr properly synchronized? +##################################################### +busybox tar xvvOf test.tar > output.txt 2>&1 + +# 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 From g.branden.robinson at gmail.com Fri Aug 7 02:30:33 2026 From: g.branden.robinson at gmail.com (G. Branden Robinson) Date: Thu, 6 Aug 2026 21:30:33 -0500 Subject: busybox sed not POSIX-conforming? (was: groff 1.25.0.rc2 on Alpine Linux) In-Reply-To: <3359335.uoxibFcf9D@cagnes> References: <20260802021622.tuqhdcsans6z5sib@illithid> <4185359.N7aMVyhfb1@cagnes> <3359335.uoxibFcf9D@cagnes> Message-ID: <20260807023033.nl4wt67fgjnol2jw@illithid> [looping in busybox mailing list; Bruno found a sed portability problem] Background: https://savannah.gnu.org/bugs/?68601 Hi Bruno, At 2026-08-06T18:07:55+0200, Bruno Haible wrote: > I wrote: > > The reason is that the 'sed' program on this platform (from BusyBox) > > ignores '-e' options when a '-f' option is present, regardless > > whether the '-e' options come before or after the '-f' option. > > Addendum: This is not the case in general, but is the case with this > particular '-f' script and these particular '-e' options. I didn't experiment to determine the issue, but the following change in wording from POSIX Issue 4 to Issue 8 might account for the discrepancy. Issue 4: ?f script_file Add the editing commands in the file script_file to the end of the script. Issue 8: ?f script_file Add the editing commands in the file script_file to the end of the script of editing commands. I wonder what alternative script the Busybox developers have in mind. Regards, Branden -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From vda.linux at googlemail.com Sun Aug 9 04:37:20 2026 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sun, 9 Aug 2026 06:37:20 +0200 Subject: [PATCH] patch: handle files with no final newline In-Reply-To: <69e49a5c.6on5uZJ9HGFbVESa%rmy@pobox.com> References: <69e49a5c.6on5uZJ9HGFbVESa%rmy@pobox.com> Message-ID: Applied, thank you. On Sun, Apr 19, 2026 at 11:03?AM Ron Yorston via busybox wrote: > > GNU and BSD patch both handle patches which include the annotation > '\ No newline at end of file'. BusyBox patch doesn't, even though > its diff emits it. > > Implement this feature and add some tests. > > function old new delta > patch_main 1912 2002 +90 > do_line 88 116 +28 > ------------------------------------------------------------------------------ > (add/remove: 0/0 grow/shrink: 2/0 up/down: 118/0) Total: 118 bytes > > Signed-off-by: Ron Yorston > --- > editors/patch.c | 33 ++++++++++++++++++++--- > testsuite/patch.tests | 63 +++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 92 insertions(+), 4 deletions(-) > > diff --git a/editors/patch.c b/editors/patch.c > index 5a768b23f..ee0ccd384 100644 > --- a/editors/patch.c > +++ b/editors/patch.c > @@ -57,6 +57,7 @@ struct double_list { > struct double_list *next; > struct double_list *prev; > char *data; > + int no_newline; > }; > > // Free all the elements of a linked list > @@ -76,7 +77,7 @@ static void dlist_free(struct double_list *list, void (*freeit)(void *data)) > static struct double_list *dlist_add(struct double_list **list, char *data) > { > struct double_list *llist; > - struct double_list *line = xmalloc(sizeof(*line)); > + struct double_list *line = xzalloc(sizeof(*line)); > > line->data = data; > llist = *list; > @@ -140,7 +141,8 @@ static void do_line(void *data) > > if (TT.state > 1 && *dlist->data != TT.state) > fdprintf(TT.state == 2 ? 2 : TT.fileout, > - "%s\n", dlist->data + (TT.state > 3 ? 1 : 0)); > + dlist->no_newline && TT.state != 2 ? "%s" : "%s\n", > + dlist->data + (TT.state > 3 ? 1 : 0)); > > if (PATCH_DEBUG) fdprintf(2, "DO %d: %s\n", TT.state, dlist->data); > > @@ -433,7 +435,17 @@ int patch_main(int argc UNUSED_PARAM, char **argv) > > // Are we assembling a hunk? > if (state >= 2) { > - if (*patchline == ' ' || *patchline == '+' || *patchline == '-') { > + switch (*patchline) { > + case '\\': > + // '\ No newline at end of file' detected, mark > + // previous line, if it exists. > + if (TT.current_hunk->prev) > + TT.current_hunk->prev->no_newline = TRUE; > + free(patchline); > + continue; > + case ' ': > + case '+': > + case '-': > dlist_add(&TT.current_hunk, patchline); > > if (*patchline != '+') oldlen--; > @@ -445,7 +457,20 @@ int patch_main(int argc UNUSED_PARAM, char **argv) > > // If we've consumed all expected hunk lines, apply the hunk. > > - if (!oldlen && !newlen) state = apply_one_hunk(); > + if (!oldlen && !newlen) { > + // Peek ahead for '\ No newline at end of file', mark > + // previous line, if it exists. > + int c = getchar(); > + ungetc(c, stdin); > + if (c == '\\') { > + if (TT.current_hunk->prev) > + TT.current_hunk->prev->no_newline = TRUE; > + do { > + c = getchar(); > + } while (c != EOF && c != '\n'); > + } > + state = apply_one_hunk(); > + } > continue; > } > fail_hunk(); > diff --git a/testsuite/patch.tests b/testsuite/patch.tests > index 1d48e90be..1a786aa71 100755 > --- a/testsuite/patch.tests > +++ b/testsuite/patch.tests > @@ -287,6 +287,69 @@ bar > 2.9.2 > " \ > > +# testing "test name" "command(s)" "expected result" "file input" "stdin" > +testing "patch file with no last newline" \ > + 'patch 2>&1; cat input' \ > +"\ > +patching file input > +first line > +last line with newline > +" \ > +"\ > +first line > +last line with no newline" \ > +"\ > +--- input > ++++ input > +@@ -1,2 +1,2 @@ > + first line > +-last line with no newline > +\ No newline at end of file > ++last line with newline > +" \ > + > +# testing "test name" "command(s)" "expected result" "file input" "stdin" > +testing "patch -R to revert previous test" \ > + 'patch -R 2>&1; cat input' \ > +"\ > +patching file input > +first line > +last line with no newline" \ > +"\ > +first line > +last line with newline > +" \ > +"\ > +--- input > ++++ input > +@@ -1,2 +1,2 @@ > + first line > +-last line with no newline > +\ No newline at end of file > ++last line with newline > +" \ > + > +# testing "test name" "command(s)" "expected result" "file input" "stdin" > +testing "patch file so it has no last newline" \ > + 'patch 2>&1; cat input' \ > +"\ > +patching file input > +first line > +last line with no newline" \ > +"\ > +first line > +last line with newline > +" \ > +"\ > +--- input > ++++ input > +@@ -1,2 +1,2 @@ > + first line > +-last line with newline > ++last line with no newline > +\ No newline at end of file > +" \ > + > rm input.orig 2>/dev/null > > exit $FAILCOUNT > -- > 2.53.0 > > _______________________________________________ > busybox mailing list > busybox at busybox.net > https://lists.busybox.net/mailman/listinfo/busybox From vda.linux at googlemail.com Mon Aug 10 03:29:39 2026 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 10 Aug 2026 05:29:39 +0200 Subject: [PATCH] rpm2cpio: print name of unknown compression method In-Reply-To: <69c27941.Og9mG89bdD6S+WFv%rmy@pobox.com> References: <69c27941.Og9mG89bdD6S+WFv%rmy@pobox.com> Message-ID: Applied, thank you. On Tue, Mar 24, 2026 at 12:51?PM Ron Yorston via busybox wrote: > > Commit f13f68288 (rpm2cpio: extract cpio even if compression is > not known) added an error message if the compression method was > unknown. When support for lzma was disabled this resulted in a > null pointer being passed to bb_error_msg(). > > The call to rpm_getstr0() to fetch the name of the compression > method shouldn't depend on lzma being supported. > > This doesn't affect the size of a default build. In a build with > lzma disabled: > > function old new delta > rpm2cpio_main 110 121 +11 > ------------------------------------------------------------------------------ > (add/remove: 0/0 grow/shrink: 1/0 up/down: 11/0) Total: 11 bytes > > Signed-off-by: Ron Yorston > --- > archival/rpm.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/archival/rpm.c b/archival/rpm.c > index 95a8c79b6..899587751 100644 > --- a/archival/rpm.c > +++ b/archival/rpm.c > @@ -533,9 +533,9 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) > // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ > // signal(SIGCHLD, check_errors_in_children); > > - str = NULL; > + str = rpm_getstr0(TAG_PAYLOADCOMPRESSOR); > if (ENABLE_FEATURE_SEAMLESS_LZMA > - && (str = rpm_getstr0(TAG_PAYLOADCOMPRESSOR)) != NULL > + && str != NULL > && strcmp(str, "lzma") == 0 > ) { > // lzma compression can't be detected > -- > 2.53.0 > > _______________________________________________ > busybox mailing list > busybox at busybox.net > https://lists.busybox.net/mailman/listinfo/busybox From vda.linux at googlemail.com Mon Aug 10 04:28:37 2026 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 10 Aug 2026 06:28:37 +0200 Subject: [PATCH] tar: fix verbose output with extract-to-stdout In-Reply-To: <20260730180315.8304-1-brehmt@gmail.com> References: <20260730180315.8304-1-brehmt@gmail.com> Message-ID: Applied in modified form (making "tar xvO" follow GNU tar behavior). Thank you. On Thu, Jul 30, 2026 at 8:03?PM ThorstenB via busybox wrote: > > 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 streams > 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 > --- > 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 > busybox at busybox.net > https://lists.busybox.net/mailman/listinfo/busybox From foss at romainguyard.com Tue Aug 11 05:22:58 2026 From: foss at romainguyard.com (Romain Guyard) Date: Tue, 11 Aug 2026 14:22:58 +0900 Subject: [PATCH] hdparm: fix printing of ATA identification strings In-Reply-To: References: Message-ID: <2501238b-ea3e-4913-b459-4190660e2234@romainguyard.com> Hello! In the hdparm applet, print_ascii() is intended to skip leading spaces before printing ATA IDENTIFY strings, but its condition is inverted, causing it to skip non-space characters instead. This causes left-justified serial numbers and firmware revisions to be printed as empty, and truncates model strings at their first embedded space. The attached patch fixes the condition and adds a regression test using synthetic ATA IDENTIFY data. It was also tested on real hardware. Thanks, -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-hdparm-fix-ATA-identification-string-output.patch Type: text/x-patch Size: 4488 bytes Desc: not available URL: From farmatito at tiscali.it Tue Aug 11 08:15:03 2026 From: farmatito at tiscali.it (tito) Date: Tue, 11 Aug 2026 10:15:03 +0200 Subject: [PATCH] hdparm: fix printing of ATA identification strings In-Reply-To: <2501238b-ea3e-4913-b459-4190660e2234@romainguyard.com> References: <2501238b-ea3e-4913-b459-4190660e2234@romainguyard.com> Message-ID: <20260811101503.73d6ce73@devuan> On Tue, 11 Aug 2026 14:22:58 +0900 Romain Guyard via busybox wrote: > Hello! > > In the hdparm applet, print_ascii() is intended to skip leading > spaces before printing ATA IDENTIFY strings, but its condition > is inverted, causing it to skip non-space characters instead. > > This causes left-justified serial numbers and firmware revisions to be > printed as empty, and truncates model strings at their first embedded > space. > > The attached patch fixes the condition and adds a regression test using > synthetic ATA IDENTIFY data. It was also tested on real hardware. > > Thanks, Hi, to be honest the hdparm applet seems to be totally broken with latest git: ./busybox hdparm -I /dev/sdb /dev/sdb: hdparm: HDIO_DRIVE_CMD: Invalid argument hdparm -I /dev/sdb /dev/sdb: ATA device, with non-removable media Model Number: WDC WD5003ABYZ-011FA0 git rev-parse --short HEAD 7473045ad Ciao, Tito From farmatito at tiscali.it Tue Aug 11 08:20:26 2026 From: farmatito at tiscali.it (tito) Date: Tue, 11 Aug 2026 10:20:26 +0200 Subject: [BUG] busybox tc doesn't compile with kernel 6.12.103 Message-ID: <20260811102026.01f333d9@devuan> Hi, I've noticed that the tc applet doesn't compile with linux kernel 6.12.103 and git rev-parse --short HEAD 7473045ad Ciao, Tito make SPLIT include/autoconf.h -> include/config/* GEN include/bbconfigopts.h GEN include/common_bufsiz.h GEN include/embedded_scripts.h HOSTCC applets/usage GEN include/usage_compressed.h HOSTCC applets/applet_tables GEN include/applet_tables.h include/NUM_APPLETS.h GEN include/applet_tables.h include/NUM_APPLETS.h CC applets/applets.o LD applets/built-in.o HOSTCC applets/usage_pod CC libbb/appletlib.o CC libbb/lineedit.o CC libbb/vfork_daemon_rexec.o AR libbb/lib.a CC networking/tc.o networking/tc.c: In function ?cbq_print_opt?: networking/tc.c:236:27: error: ?TCA_CBQ_MAX? undeclared (first use in this function); did you mean ?TCA_CBS_MAX?? 236 | struct rtattr *tb[TCA_CBQ_MAX+1]; | ^~~~~~~~~~~ | TCA_CBS_MAX networking/tc.c:236:27: note: each undeclared identifier is reported only once for each function it appears in networking/tc.c:249:16: error: ?TCA_CBQ_RATE? undeclared (first use in this function); did you mean ?TCA_TBF_RATE64?? 249 | if (tb[TCA_CBQ_RATE]) { | ^~~~~~~~~~~~ | TCA_TBF_RATE64 networking/tc.c:255:16: error: ?TCA_CBQ_LSSOPT? undeclared (first use in this function) 255 | if (tb[TCA_CBQ_LSSOPT]) { | ^~~~~~~~~~~~~~ networking/tc.c:256:61: error: invalid application of ?sizeof? to incomplete type ?struct tc_cbq_lssopt? 256 | if (RTA_PAYLOAD(tb[TCA_CBQ_LSSOPT]) < sizeof(*lss)) | ^ networking/tc.c:261:16: error: ?TCA_CBQ_WRROPT? undeclared (first use in this function) 261 | if (tb[TCA_CBQ_WRROPT]) { | ^~~~~~~~~~~~~~ networking/tc.c:262:61: error: invalid application of ?sizeof? to incomplete type ?struct tc_cbq_wrropt? 262 | if (RTA_PAYLOAD(tb[TCA_CBQ_WRROPT]) < sizeof(*wrr)) | ^ networking/tc.c:267:16: error: ?TCA_CBQ_FOPT? undeclared (first use in this function) 267 | if (tb[TCA_CBQ_FOPT]) { | ^~~~~~~~~~~~ networking/tc.c:268:59: error: invalid application of ?sizeof? to incomplete type ?struct tc_cbq_fopt? 268 | if (RTA_PAYLOAD(tb[TCA_CBQ_FOPT]) < sizeof(*fopt)) | ^ networking/tc.c:273:16: error: ?TCA_CBQ_OVL_STRATEGY? undeclared (first use in this function) 273 | if (tb[TCA_CBQ_OVL_STRATEGY]) { | ^~~~~~~~~~~~~~~~~~~~ networking/tc.c:274:67: error: invalid application of ?sizeof? to incomplete type ?struct tc_cbq_ovl? 274 | if (RTA_PAYLOAD(tb[TCA_CBQ_OVL_STRATEGY]) < sizeof(*ovl)) | ^ networking/tc.c:277:50: error: invalid application of ?sizeof? to incomplete type ?struct tc_cbq_ovl? 277 | (unsigned) sizeof(*ovl)); | ^ networking/tc.c:293:23: error: invalid use of undefined type ?struct tc_cbq_lssopt? 293 | if (lss && lss->flags) { | ^~ networking/tc.c:296:24: error: invalid use of undefined type ?struct tc_cbq_lssopt? 296 | if (lss->flags&TCF_CBQ_LSS_BOUNDED) { | ^~ networking/tc.c:296:32: error: ?TCF_CBQ_LSS_BOUNDED? undeclared (first use in this function) 296 | if (lss->flags&TCF_CBQ_LSS_BOUNDED) { | ^~~~~~~~~~~~~~~~~~~ networking/tc.c:300:24: error: invalid use of undefined type ?struct tc_cbq_lssopt? 300 | if (lss->flags&TCF_CBQ_LSS_ISOLATED) { | ^~ networking/tc.c:300:32: error: ?TCF_CBQ_LSS_ISOLATED? undeclared (first use in this function) 300 | if (lss->flags&TCF_CBQ_LSS_ISOLATED) { | ^~~~~~~~~~~~~~~~~~~~ networking/tc.c:308:24: error: invalid use of undefined type ?struct tc_cbq_wrropt? 308 | if (wrr->priority != TC_CBQ_MAXPRIO) | ^~ networking/tc.c:308:38: error: ?TC_CBQ_MAXPRIO? undeclared (first use in this function) 308 | if (wrr->priority != TC_CBQ_MAXPRIO) | ^~~~~~~~~~~~~~ networking/tc.c:309:46: error: invalid use of undefined type ?struct tc_cbq_wrropt? 309 | printf("prio %u", wrr->priority); | ^~ networking/tc.c:313:43: error: invalid use of undefined type ?struct tc_cbq_wrropt? 313 | printf("/%u ", wrr->cpriority); | ^~ networking/tc.c:314:32: error: invalid use of undefined type ?struct tc_cbq_wrropt? 314 | if (wrr->weight != 1) { | ^~ networking/tc.c:315:65: error: invalid use of undefined type ?struct tc_cbq_wrropt? 315 | print_rate(buf, sizeof(buf), wrr->weight); | ^~ networking/tc.c:318:32: error: invalid use of undefined type ?struct tc_cbq_wrropt? 318 | if (wrr->allot) | ^~ networking/tc.c:319:57: error: invalid use of undefined type ?struct tc_cbq_wrropt? 319 | printf("allot %ub ", wrr->allot); | ^~ networking/tc.c:236:24: warning: unused variable ?tb? [-Wunused-variable] 236 | struct rtattr *tb[TCA_CBQ_MAX+1]; | ^~ make[1]: *** [scripts/Makefile.build:198: networking/tc.o] Error 1 make: *** [Makefile:749: networking] Error 2 From farmatito at tiscali.it Tue Aug 11 22:06:11 2026 From: farmatito at tiscali.it (tito) Date: Wed, 12 Aug 2026 00:06:11 +0200 Subject: [PATCH] hdparm: fix printing of ATA identification strings In-Reply-To: References: <2501238b-ea3e-4913-b459-4190660e2234@romainguyard.com> <20260811101503.73d6ce73@devuan> Message-ID: <20260812000611.19b4754f@devuan> On Tue, 11 Aug 2026 11:33:24 +0200 "Roberto A. Foglietta" wrote: > On Tue, 11 Aug 2026 at 11:18, Roberto A. Foglietta > wrote: > > > > On Tue, 11 Aug 2026 at 10:20, tito via busybox wrote: > > > > > > On Tue, 11 Aug 2026 14:22:58 +0900 > > > Romain Guyard via busybox wrote: > > > > > > > Hello! > > > > > > > > In the hdparm applet, print_ascii() is intended to skip leading > > > > spaces before printing ATA IDENTIFY strings, but its condition > > > > is inverted, causing it to skip non-space characters instead. > > > > > > > > This causes left-justified serial numbers and firmware revisions to be > > > > printed as empty, and truncates model strings at their first embedded > > > > space. > > > > > > > > The attached patch fixes the condition and adds a regression test using > > > > synthetic ATA IDENTIFY data. It was also tested on real hardware. > > > > > > > > Thanks, > > > Hi, > > > to be honest the hdparm applet seems to be totally broken > > > with latest git: > > > > Please, try without this: > > > > + 36eed984b - 2026-02-04 - fdisk: several fixes for 4K sector size > > > > Whatever that commit or the previous ones, on Linux 6.8 (Ubuntu) the > result is always the same (while the GNU counter part does something > more): > > roberto at x280[2]:~/robang74/busybox$ sudo ./busybox hdparm -Ii /dev/sda > > /dev/sda: > hdparm: ioctl 0x304 failed: Invalid argument > hdparm: HDIO_GET_IDENTITY: Invalid argument > hdparm: HDIO_DRIVE_CMD: Invalid argument > > roberto at x280[2]:~/robang74/busybox$ sudo hdparm -Ii /dev/sda > > /dev/sda: > HDIO_GET_IDENTITY failed: Invalid argument > > ATA device, with non-removable media > > Best regards, Hi, I suspect that it is just the missing of capability to issue the ATA commands pass through via SG_IO (see hdparm 9.65 source) because for me some HDDs (attached to motherboard sata ports) work and others (attached to LSI HBA CARDS) don't. This cannot be fixed without major code changes that I don't feel comfortable to do. Ciao, Tito From mjt at tls.msk.ru Wed Aug 12 13:51:30 2026 From: mjt at tls.msk.ru (Michael Tokarev) Date: Wed, 12 Aug 2026 16:51:30 +0300 Subject: [BUG] busybox tc doesn't compile with kernel 6.12.103 In-Reply-To: <20260811102026.01f333d9@devuan> References: <20260811102026.01f333d9@devuan> Message-ID: <4f8554f5-d288-4ea9-a668-fde9cac22217@tls.msk.ru> On 8/11/26 11:20, tito via busybox wrote: > Hi, > I've noticed that the tc applet doesn't compile with linux kernel 6.12.103 > and git rev-parse --short HEAD > networking/tc.c:236:27: error: ?TCA_CBQ_MAX? undeclared (first use in this function); did you mean ?TCA_CBS_MAX?? Can't you do at least minimal google searching before submitting the same bug report 100th time? It's been an issue known for several years, and everyone has local patch for it for a long time. https://bugs.busybox.net/show_bug.cgi?id=15931 -- unfortunately bugzilla does not work, but google finds a lot of occurences of this, including multiple posts here on busybox mailinglist. For this issue and for many other issues which are known for years and have to be fixed in distributions. Thanks, /mjt