aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2025-11-13 07:50:50 +0000
committerDenys Vlasenko <vda.linux@googlemail.com>2026-03-05 21:46:04 +0100
commitea01f254b4e0dc2f59db4cba9dd4fa98e9f5b2e5 (patch)
treecce0009e2d1ade4f28a32c9e23709dc20ede2d80 /coreutils
parentb59b00323181d5d450a92959b9bbfe3585c6786b (diff)
downloadbusybox-w32-ea01f254b4e0dc2f59db4cba9dd4fa98e9f5b2e5.tar.gz
busybox-w32-ea01f254b4e0dc2f59db4cba9dd4fa98e9f5b2e5.tar.bz2
busybox-w32-ea01f254b4e0dc2f59db4cba9dd4fa98e9f5b2e5.zip
paste: fix output when file lengths differ
If the files being pasted had different numbers of lines the output was incorrect. Rewrite the loop over all lines to allow for this. Add tests for such conditions. function old new delta paste_main 458 526 +68 Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/paste.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/coreutils/paste.c b/coreutils/paste.c
index 3e5f20158..363340e3d 100644
--- a/coreutils/paste.c
+++ b/coreutils/paste.c
@@ -34,27 +34,38 @@
34 34
35static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt) 35static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt)
36{ 36{
37 char *line; 37 char **line = xmalloc(file_cnt * sizeof(char *));
38 char delim; 38 char delim;
39 int active_files = file_cnt; 39 int active_files = file_cnt;
40 int i; 40 int i;
41 41
42 while (active_files > 0) { 42 while (active_files > 0) {
43 int del_idx = 0; 43 int del_idx = 0;
44 int got_line = FALSE;
44 45
45 for (i = 0; i < file_cnt; ++i) { 46 for (i = 0; i < file_cnt; ++i) {
46 if (files[i] == NULL) 47 if (files[i]) {
47 continue; 48 line[i] = xmalloc_fgetline(files[i]);
48 49 if (!line[i]) {
49 line = xmalloc_fgetline(files[i]); 50 fclose_if_not_stdin(files[i]);
50 if (!line) { 51 files[i] = NULL;
51 fclose_if_not_stdin(files[i]); 52 --active_files;
52 files[i] = NULL; 53 } else {
53 --active_files; 54 got_line = TRUE;
54 continue; 55 }
56 } else {
57 line[i] = NULL;
58 }
59 }
60
61 if (!got_line)
62 break;
63
64 for (i = 0; i < file_cnt; ++i) {
65 if (line[i]) {
66 fputs_stdout(line[i]);
67 free(line[i]);
55 } 68 }
56 fputs_stdout(line);
57 free(line);
58 delim = '\n'; 69 delim = '\n';
59 if (i != file_cnt - 1) { 70 if (i != file_cnt - 1) {
60 delim = delims[del_idx++]; 71 delim = delims[del_idx++];
@@ -65,6 +76,7 @@ static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt)
65 fputc(delim, stdout); 76 fputc(delim, stdout);
66 } 77 }
67 } 78 }
79 free(line);
68} 80}
69 81
70static void paste_files_separate(FILE** files, char* delims, int del_cnt) 82static void paste_files_separate(FILE** files, char* delims, int del_cnt)