aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-02-05 11:24:06 +0000
committerRon Yorston <rmy@pobox.com>2021-02-05 11:24:06 +0000
commit32e19e7ae8b0d76d69871ba234e8f0af31baff4e (patch)
tree6fdc833a444e0dd6fd359b21a8d463856917a387
parent4fb71406b884c6ac0a9a4d2acf7a32b544611f70 (diff)
parentcad3fc743aa7c7744e4fcf044371f0fda50fa51f (diff)
downloadbusybox-w32-32e19e7ae8b0d76d69871ba234e8f0af31baff4e.tar.gz
busybox-w32-32e19e7ae8b0d76d69871ba234e8f0af31baff4e.tar.bz2
busybox-w32-32e19e7ae8b0d76d69871ba234e8f0af31baff4e.zip
Merge branch 'busybox' into merge
-rw-r--r--applets/individual.c2
-rw-r--r--coreutils/cat.c4
-rw-r--r--coreutils/cut.c2
-rw-r--r--coreutils/expand.c2
-rw-r--r--coreutils/head.c2
-rw-r--r--coreutils/id.c2
-rw-r--r--coreutils/ls.c2
-rw-r--r--coreutils/nl.c2
-rw-r--r--coreutils/od_bloaty.c26
-rw-r--r--coreutils/paste.c4
-rw-r--r--coreutils/stat.c2
-rw-r--r--coreutils/stty.c2
-rw-r--r--coreutils/uudecode.c2
-rw-r--r--coreutils/yes.c2
-rw-r--r--editors/awk.c18
-rw-r--r--editors/ed.c2
-rw-r--r--editors/vi.c17
-rw-r--r--include/libbb.h1
-rw-r--r--libbb/appletlib.c96
-rw-r--r--libbb/bb_askpass.c2
-rw-r--r--libbb/compare_string_array.c14
-rw-r--r--libbb/dump.c2
-rw-r--r--libbb/fgets_str.c17
-rw-r--r--libbb/lineedit.c8
-rw-r--r--libbb/login.c6
-rw-r--r--libbb/print_numbered_lines.c5
-rw-r--r--libbb/update_passwd.c2
-rw-r--r--libbb/xfuncs_printf.c5
-rw-r--r--loginutils/cryptpw.c6
-rw-r--r--miscutils/bc.c2
-rw-r--r--miscutils/conspy.c4
-rw-r--r--miscutils/strings.c2
-rw-r--r--networking/brctl.c2
-rw-r--r--networking/httpd.c4
-rw-r--r--networking/libiproute/ipaddress.c14
-rw-r--r--networking/libiproute/iprule.c7
-rw-r--r--networking/traceroute.c2
-rw-r--r--networking/udhcp/dumpleases.c2
-rw-r--r--procps/powertop.c2
-rw-r--r--procps/top.c2
-rw-r--r--shell/hush.c2
-rw-r--r--sysklogd/logread.c4
-rwxr-xr-xtestsuite/awk.tests5
-rwxr-xr-xtestsuite/cat.tests24
-rwxr-xr-xtestsuite/nl.tests39
-rw-r--r--util-linux/fdisk_gpt.c4
-rw-r--r--util-linux/rev.c2
47 files changed, 202 insertions, 178 deletions
diff --git a/applets/individual.c b/applets/individual.c
index 4c468df06..e94f26c93 100644
--- a/applets/individual.c
+++ b/applets/individual.c
@@ -19,6 +19,6 @@ int main(int argc, char **argv)
19 19
20void bb_show_usage(void) 20void bb_show_usage(void)
21{ 21{
22 fputs(APPLET_full_usage "\n", stdout); 22 fputs_stdout(APPLET_full_usage "\n");
23 exit(EXIT_FAILURE); 23 exit(EXIT_FAILURE);
24} 24}
diff --git a/coreutils/cat.c b/coreutils/cat.c
index 65f0648f9..4b3414941 100644
--- a/coreutils/cat.c
+++ b/coreutils/cat.c
@@ -152,7 +152,7 @@ static int catv(unsigned opts, char **argv)
152 eol_seen = (c == eol_char); 152 eol_seen = (c == eol_char);
153#endif 153#endif
154 visible(c, buf, opts); 154 visible(c, buf, opts);
155 fputs(buf, stdout); 155 fputs_stdout(buf);
156 } 156 }
157 } 157 }
158 if (ENABLE_FEATURE_CLEAN_UP && fd) 158 if (ENABLE_FEATURE_CLEAN_UP && fd)
@@ -201,7 +201,7 @@ int cat_main(int argc UNUSED_PARAM, char **argv)
201 ns.start = 1; 201 ns.start = 1;
202 ns.inc = 1; 202 ns.inc = 1;
203 ns.sep = "\t"; 203 ns.sep = "\t";
204 ns.empty_str = "\n"; 204 ns.empty_str = NULL;
205 ns.all = !(opts & CAT_OPT_b); /* -n without -b */ 205 ns.all = !(opts & CAT_OPT_b); /* -n without -b */
206 ns.nonempty = (opts & CAT_OPT_b); /* -b (with or without -n) */ 206 ns.nonempty = (opts & CAT_OPT_b); /* -b (with or without -n) */
207 exitcode = EXIT_SUCCESS; 207 exitcode = EXIT_SUCCESS;
diff --git a/coreutils/cut.c b/coreutils/cut.c
index 1acbb513e..16418ff33 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -167,7 +167,7 @@ static void cut_file(FILE *file, char delim, const struct cut_list *cut_lists, u
167 * printed */ 167 * printed */
168 if (nfields_printed > 0) 168 if (nfields_printed > 0)
169 putchar(delim); 169 putchar(delim);
170 fputs(field, stdout); 170 fputs_stdout(field);
171 printed[ndelim] = 'X'; 171 printed[ndelim] = 'X';
172 nfields_printed++; /* shouldn't overflow.. */ 172 nfields_printed++; /* shouldn't overflow.. */
173 } 173 }
diff --git a/coreutils/expand.c b/coreutils/expand.c
index 5f5993921..c5e1de6f5 100644
--- a/coreutils/expand.c
+++ b/coreutils/expand.c
@@ -123,7 +123,7 @@ static void expand(FILE *file, unsigned tab_size, unsigned opt)
123 } 123 }
124 ptr++; 124 ptr++;
125 } 125 }
126 fputs(ptr_strbeg, stdout); 126 fputs_stdout(ptr_strbeg);
127 free(line); 127 free(line);
128 } 128 }
129} 129}
diff --git a/coreutils/head.c b/coreutils/head.c
index 1219dfe8b..b6efabbe0 100644
--- a/coreutils/head.c
+++ b/coreutils/head.c
@@ -117,7 +117,7 @@ print_except_N_last_lines(FILE *fp, unsigned count)
117 char *c; 117 char *c;
118 if (head == count) 118 if (head == count)
119 head = 0; 119 head = 0;
120 fputs(circle[head], stdout); 120 fputs_stdout(circle[head]);
121 c = xmalloc_fgets(fp); 121 c = xmalloc_fgets(fp);
122 if (!c) 122 if (!c)
123 goto ret; 123 goto ret;
diff --git a/coreutils/id.c b/coreutils/id.c
index 78d5f2a50..f453a87ae 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -258,7 +258,7 @@ int id_main(int argc UNUSED_PARAM, char **argv)
258 bb_error_msg_and_die("can't get process context%s", 258 bb_error_msg_and_die("can't get process context%s",
259 username ? " for a different user" : ""); 259 username ? " for a different user" : "");
260 } 260 }
261 fputs(scontext, stdout); 261 fputs_stdout(scontext);
262 } 262 }
263 /* freecon(NULL) seems to be harmless */ 263 /* freecon(NULL) seems to be harmless */
264 if (ENABLE_FEATURE_CLEAN_UP) 264 if (ENABLE_FEATURE_CLEAN_UP)
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 2f9338f19..e891a67ce 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -456,7 +456,7 @@ static unsigned print_name(const char *name)
456 name = printable_string2(&uni_stat, name); 456 name = printable_string2(&uni_stat, name);
457 457
458 if (!(option_mask32 & OPT_Q)) { 458 if (!(option_mask32 & OPT_Q)) {
459 fputs(name, stdout); 459 fputs_stdout(name);
460 return uni_stat.unicode_width; 460 return uni_stat.unicode_width;
461 } 461 }
462 462
diff --git a/coreutils/nl.c b/coreutils/nl.c
index 800b73c26..d06673881 100644
--- a/coreutils/nl.c
+++ b/coreutils/nl.c
@@ -68,7 +68,7 @@ int nl_main(int argc UNUSED_PARAM, char **argv)
68 &ns.width, &ns.sep, &ns.start, &ns.inc, &opt_b); 68 &ns.width, &ns.sep, &ns.start, &ns.inc, &opt_b);
69 ns.all = (opt_b[0] == 'a'); 69 ns.all = (opt_b[0] == 'a');
70 ns.nonempty = (opt_b[0] == 't'); 70 ns.nonempty = (opt_b[0] == 't');
71 ns.empty_str = xasprintf("%*s\n", ns.width + (int)strlen(ns.sep), ""); 71 ns.empty_str = xasprintf("%*s", ns.width + (int)strlen(ns.sep), "");
72 72
73 argv += optind; 73 argv += optind;
74 if (!*argv) 74 if (!*argv)
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index 76ee5137a..1830aca83 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -429,19 +429,19 @@ print_named_ascii(size_t n_bytes, const char *block,
429 429
430 masked_c &= 0x7f; 430 masked_c &= 0x7f;
431 if (masked_c == 0x7f) { 431 if (masked_c == 0x7f) {
432 fputs(" del", stdout); 432 fputs_stdout(" del");
433 continue; 433 continue;
434 } 434 }
435 if (masked_c > ' ') { 435 if (masked_c > ' ') {
436 buf[3] = masked_c; 436 buf[3] = masked_c;
437 fputs(buf, stdout); 437 fputs_stdout(buf);
438 continue; 438 continue;
439 } 439 }
440 /* Why? Because printf(" %3.3s") is much slower... */ 440 /* Why? Because printf(" %3.3s") is much slower... */
441 buf[6] = charname[masked_c][0]; 441 buf[6] = charname[masked_c][0];
442 buf[7] = charname[masked_c][1]; 442 buf[7] = charname[masked_c][1];
443 buf[8] = charname[masked_c][2]; 443 buf[8] = charname[masked_c][2];
444 fputs(buf+5, stdout); 444 fputs_stdout(buf+5);
445 } 445 }
446} 446}
447 447
@@ -458,7 +458,7 @@ print_ascii(size_t n_bytes, const char *block,
458 458
459 if (ISPRINT(c)) { 459 if (ISPRINT(c)) {
460 buf[3] = c; 460 buf[3] = c;
461 fputs(buf, stdout); 461 fputs_stdout(buf);
462 continue; 462 continue;
463 } 463 }
464 switch (c) { 464 switch (c) {
@@ -492,7 +492,7 @@ print_ascii(size_t n_bytes, const char *block,
492 buf[8] = (c & 7) + '0'; 492 buf[8] = (c & 7) + '0';
493 s = buf + 5; 493 s = buf + 5;
494 } 494 }
495 fputs(s, stdout); 495 fputs_stdout(s);
496 } 496 }
497} 497}
498 498
@@ -888,7 +888,7 @@ format_address_label(off_t address, char c)
888static void 888static void
889dump_hexl_mode_trailer(size_t n_bytes, const char *block) 889dump_hexl_mode_trailer(size_t n_bytes, const char *block)
890{ 890{
891 fputs(" >", stdout); 891 fputs_stdout(" >");
892 while (n_bytes--) { 892 while (n_bytes--) {
893 unsigned c = *(unsigned char *) block++; 893 unsigned c = *(unsigned char *) block++;
894 c = (ISPRINT(c) ? c : '.'); 894 c = (ISPRINT(c) ? c : '.');
@@ -1128,13 +1128,13 @@ dump_strings(off_t address, off_t end_offset)
1128 1128
1129 for (i = 0; (c = buf[i]); i++) { 1129 for (i = 0; (c = buf[i]); i++) {
1130 switch (c) { 1130 switch (c) {
1131 case '\007': fputs("\\a", stdout); break; 1131 case '\007': fputs_stdout("\\a"); break;
1132 case '\b': fputs("\\b", stdout); break; 1132 case '\b': fputs_stdout("\\b"); break;
1133 case '\f': fputs("\\f", stdout); break; 1133 case '\f': fputs_stdout("\\f"); break;
1134 case '\n': fputs("\\n", stdout); break; 1134 case '\n': fputs_stdout("\\n"); break;
1135 case '\r': fputs("\\r", stdout); break; 1135 case '\r': fputs_stdout("\\r"); break;
1136 case '\t': fputs("\\t", stdout); break; 1136 case '\t': fputs_stdout("\\t"); break;
1137 case '\v': fputs("\\v", stdout); break; 1137 case '\v': fputs_stdout("\\v"); break;
1138 default: putchar(c); 1138 default: putchar(c);
1139 } 1139 }
1140 } 1140 }
diff --git a/coreutils/paste.c b/coreutils/paste.c
index fd2aa5027..7def4de11 100644
--- a/coreutils/paste.c
+++ b/coreutils/paste.c
@@ -53,7 +53,7 @@ static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt)
53 --active_files; 53 --active_files;
54 continue; 54 continue;
55 } 55 }
56 fputs(line, stdout); 56 fputs_stdout(line);
57 free(line); 57 free(line);
58 delim = '\n'; 58 delim = '\n';
59 if (i != file_cnt - 1) { 59 if (i != file_cnt - 1) {
@@ -79,7 +79,7 @@ static void paste_files_separate(FILE** files, char* delims, int del_cnt)
79 line = NULL; 79 line = NULL;
80 while ((next_line = xmalloc_fgetline(files[i])) != NULL) { 80 while ((next_line = xmalloc_fgetline(files[i])) != NULL) {
81 if (line) { 81 if (line) {
82 fputs(line, stdout); 82 fputs_stdout(line);
83 free(line); 83 free(line);
84 delim = delims[del_idx++]; 84 delim = delims[del_idx++];
85 if (del_idx == del_cnt) 85 if (del_idx == del_cnt)
diff --git a/coreutils/stat.c b/coreutils/stat.c
index 1267df450..1e93dce80 100644
--- a/coreutils/stat.c
+++ b/coreutils/stat.c
@@ -445,7 +445,7 @@ static void print_it(const char *masterformat,
445 445
446 /* print preceding string */ 446 /* print preceding string */
447 *p = '\0'; 447 *p = '\0';
448 fputs(b, stdout); 448 fputs_stdout(b);
449 449
450 p += len; 450 p += len;
451 b = p + 1; 451 b = p + 1;
diff --git a/coreutils/stty.c b/coreutils/stty.c
index 19253964c..ba2b78317 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -855,7 +855,7 @@ static void wrapf(const char *message, ...)
855 } 855 }
856 } 856 }
857 } 857 }
858 fputs(buf, stdout); 858 fputs_stdout(buf);
859 G.current_col += buflen; 859 G.current_col += buflen;
860 if (buf[buflen-1] == '\n') 860 if (buf[buflen-1] == '\n')
861 G.current_col = 0; 861 G.current_col = 0;
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c
index 164b208ea..02b037276 100644
--- a/coreutils/uudecode.c
+++ b/coreutils/uudecode.c
@@ -319,7 +319,7 @@ int baseNUM_main(int argc UNUSED_PARAM, char **argv)
319 } 319 }
320 320
321 if (col == 0) { 321 if (col == 0) {
322 fputs(dst_buf, stdout); 322 fputs_stdout(dst_buf);
323 } else { 323 } else {
324 char *result = dst_buf; 324 char *result = dst_buf;
325 if (rem == 0) 325 if (rem == 0)
diff --git a/coreutils/yes.c b/coreutils/yes.c
index a51b1ad8e..38ffff46c 100644
--- a/coreutils/yes.c
+++ b/coreutils/yes.c
@@ -47,7 +47,7 @@ int yes_main(int argc UNUSED_PARAM, char **argv)
47#endif 47#endif
48 pp = argv; 48 pp = argv;
49 while (1) { 49 while (1) {
50 fputs(*pp, stdout); 50 fputs_stdout(*pp);
51 if (!*++pp) 51 if (!*++pp)
52 break; 52 break;
53 putchar(' '); 53 putchar(' ');
diff --git a/editors/awk.c b/editors/awk.c
index 4799091ec..41a57ea0c 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -2174,7 +2174,10 @@ static int fmt_num(char *b, int size, const char *format, double n, int int_as_i
2174} 2174}
2175 2175
2176/* formatted output into an allocated buffer, return ptr to buffer */ 2176/* formatted output into an allocated buffer, return ptr to buffer */
2177static char *awk_printf(node *n) 2177#if !ENABLE_FEATURE_AWK_GNU_EXTENSIONS
2178# define awk_printf(a, b) awk_printf(a)
2179#endif
2180static char *awk_printf(node *n, int *len)
2178{ 2181{
2179 char *b = NULL; 2182 char *b = NULL;
2180 char *fmt, *s, *f; 2183 char *fmt, *s, *f;
@@ -2228,6 +2231,10 @@ static char *awk_printf(node *n)
2228 nvfree(v); 2231 nvfree(v);
2229 b = xrealloc(b, i + 1); 2232 b = xrealloc(b, i + 1);
2230 b[i] = '\0'; 2233 b[i] = '\0';
2234#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
2235 if (len)
2236 *len = i;
2237#endif
2231 return b; 2238 return b;
2232} 2239}
2233 2240
@@ -2685,6 +2692,7 @@ static var *evaluate(node *op, var *res)
2685 case XC( OC_PRINT ): 2692 case XC( OC_PRINT ):
2686 case XC( OC_PRINTF ): { 2693 case XC( OC_PRINTF ): {
2687 FILE *F = stdout; 2694 FILE *F = stdout;
2695 IF_FEATURE_AWK_GNU_EXTENSIONS(int len;)
2688 2696
2689 if (op->r.n) { 2697 if (op->r.n) {
2690 rstream *rsm = newfile(R.s); 2698 rstream *rsm = newfile(R.s);
@@ -2722,8 +2730,12 @@ static var *evaluate(node *op, var *res)
2722 fputs(getvar_s(intvar[ORS]), F); 2730 fputs(getvar_s(intvar[ORS]), F);
2723 2731
2724 } else { /* OC_PRINTF */ 2732 } else { /* OC_PRINTF */
2725 char *s = awk_printf(op1); 2733 char *s = awk_printf(op1, &len);
2734#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
2735 fwrite(s, len, 1, F);
2736#else
2726 fputs(s, F); 2737 fputs(s, F);
2738#endif
2727 free(s); 2739 free(s);
2728 } 2740 }
2729 fflush(F); 2741 fflush(F);
@@ -2997,7 +3009,7 @@ static var *evaluate(node *op, var *res)
2997 break; 3009 break;
2998 3010
2999 case XC( OC_SPRINTF ): 3011 case XC( OC_SPRINTF ):
3000 setvar_p(res, awk_printf(op1)); 3012 setvar_p(res, awk_printf(op1, NULL));
3001 break; 3013 break;
3002 3014
3003 case XC( OC_UNARY ): { 3015 case XC( OC_UNARY ): {
diff --git a/editors/ed.c b/editors/ed.c
index d3ae8da92..c50faeefa 100644
--- a/editors/ed.c
+++ b/editors/ed.c
@@ -553,7 +553,7 @@ static int printLines(int num1, int num2, int expandFlag)
553 fputc_printable(ch | PRINTABLE_META, stdout); 553 fputc_printable(ch | PRINTABLE_META, stdout);
554 } 554 }
555 555
556 fputs("$\n", stdout); 556 fputs_stdout("$\n");
557 557
558 setCurNum(num1++); 558 setCurNum(num1++);
559 lp = lp->next; 559 lp = lp->next;
diff --git a/editors/vi.c b/editors/vi.c
index bfe05d613..8181a5384 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -524,7 +524,7 @@ static void show_help(void)
524 524
525static void write1(const char *out) 525static void write1(const char *out)
526{ 526{
527 fputs(out, stdout); 527 fputs_stdout(out);
528} 528}
529 529
530#if ENABLE_FEATURE_VI_WIN_RESIZE 530#if ENABLE_FEATURE_VI_WIN_RESIZE
@@ -3113,12 +3113,15 @@ static int find_range(char **start, char **stop, char c)
3113 do_cmd(c); // execute movement cmd 3113 do_cmd(c); // execute movement cmd
3114 dot_end(); // find NL 3114 dot_end(); // find NL
3115 q = dot; 3115 q = dot;
3116 } else { 3116 } else /* if (c == ' ' || c == 'l') */ {
3117 // nothing -- this causes any other values of c to 3117 // forward motion by character
3118 // represent the one-character range under the 3118 int tmpcnt = (cmdcnt ?: 1);
3119 // cursor. this is correct for ' ' and 'l', but 3119 do_cmd(c); // execute movement cmd
3120 // perhaps no others. 3120 // exclude last char unless range isn't what we expected
3121 // 3121 // this indicates we've hit EOL
3122 if (tmpcnt == dot - p)
3123 dot--;
3124 q = dot;
3122 } 3125 }
3123 if (q < p) { 3126 if (q < p) {
3124 t = q; 3127 t = q;
diff --git a/include/libbb.h b/include/libbb.h
index a7f32e21e..c4734e86d 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -916,6 +916,7 @@ char *xmalloc_substitute_string(const char *src, int count, const char *sub, con
916int bb_putchar(int ch) FAST_FUNC; 916int bb_putchar(int ch) FAST_FUNC;
917/* Note: does not use stdio, writes to fd 2 directly */ 917/* Note: does not use stdio, writes to fd 2 directly */
918int bb_putchar_stderr(char ch) FAST_FUNC; 918int bb_putchar_stderr(char ch) FAST_FUNC;
919int fputs_stdout(const char *s) FAST_FUNC;
919char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC; 920char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC;
920char *auto_string(char *str) FAST_FUNC; 921char *auto_string(char *str) FAST_FUNC;
921// gcc-4.1.1 still isn't good enough at optimizing it 922// gcc-4.1.1 still isn't good enough at optimizing it
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index ecee45ae2..320cb5b13 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -191,7 +191,7 @@ void FAST_FUNC bb_show_usage(void)
191 191
192int FAST_FUNC find_applet_by_name(const char *name) 192int FAST_FUNC find_applet_by_name(const char *name)
193{ 193{
194 unsigned i, max; 194 unsigned i;
195 int j; 195 int j;
196 const char *p; 196 const char *p;
197 197
@@ -215,105 +215,43 @@ int FAST_FUNC find_applet_by_name(const char *name)
215#endif 215#endif
216 216
217 p = applet_names; 217 p = applet_names;
218 i = 0;
219#if KNOWN_APPNAME_OFFSETS <= 0 218#if KNOWN_APPNAME_OFFSETS <= 0
220 max = NUM_APPLETS; 219 i = 0;
221#else 220#else
222 max = NUM_APPLETS * KNOWN_APPNAME_OFFSETS; 221 i = NUM_APPLETS * (KNOWN_APPNAME_OFFSETS - 1);
223 for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) { 222 for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) {
224 const char *pp = applet_names + applet_nameofs[j]; 223 const char *pp = applet_names + applet_nameofs[j];
225 if (strcmp(name, pp) >= 0) { 224 if (strcmp(name, pp) >= 0) {
226 //bb_error_msg("name:'%s' >= pp:'%s'", name, pp); 225 //bb_error_msg("name:'%s' >= pp:'%s'", name, pp);
227 p = pp; 226 p = pp;
228 i = max - NUM_APPLETS;
229 break; 227 break;
230 } 228 }
231 max -= NUM_APPLETS; 229 i -= NUM_APPLETS;
232 } 230 }
233 max /= (unsigned)KNOWN_APPNAME_OFFSETS;
234 i /= (unsigned)KNOWN_APPNAME_OFFSETS; 231 i /= (unsigned)KNOWN_APPNAME_OFFSETS;
235 //bb_error_msg("name:'%s' starting from:'%s' i:%u max:%u", name, p, i, max); 232 //bb_error_msg("name:'%s' starting from:'%s' i:%u", name, p, i);
236#endif 233#endif
237 234
238 /* Open-coded linear search without strcmp/strlen calls for speed */ 235 /* Open-coded linear search without strcmp/strlen calls for speed */
239 236 while (*p) {
240#if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/ 237 /* Do we see "name\0" at current position in applet_names? */
241 /* skip "[\0" name, it's surely not it */ 238 for (j = 0; *p == name[j]; ++j) {
242 if (ENABLE_TEST && LONE_CHAR(p, '[')) 239 if (*p++ == '\0') {
243 i++, p += 2;
244 /* All remaining applet names in p[] are at least 2 chars long */
245 /* name[] is also at least 2 chars long */
246
247 n32 = (name[0] << 0) | (name[1] << 8) | (name[2] << 16);
248 while (i < max) {
249 uint32_t p32;
250 char ch;
251
252 /* Quickly check match of the first 3 bytes */
253 move_from_unaligned32(p32, p);
254 p += 3;
255 if ((p32 & 0x00ffffff) != n32) {
256 /* Most likely case: 3 first bytes do not match */
257 i++;
258 if ((p32 & 0x00ff0000) == '\0')
259 continue; // p[2] was NUL
260 p++;
261 if ((p32 & 0xff000000) == '\0')
262 continue; // p[3] was NUL
263 /* p[0..3] aren't matching and none is NUL, check the rest */
264 while (*p++ != '\0')
265 continue;
266 continue;
267 }
268
269 /* Unlikely branch: first 3 bytes ([0..2]) match */
270 if ((p32 & 0x00ff0000) == '\0') {
271 /* name is 2-byte long, it is full match */
272 //bb_error_msg("found:'%s' i:%u", name, i);
273 return i;
274 }
275 /* Check remaining bytes [3..NUL] */
276 ch = (p32 >> 24);
277 j = 3;
278 while (ch == name[j]) {
279 if (ch == '\0') {
280 //bb_error_msg("found:'%s' i:%u", name, i);
281 return i;
282 }
283 ch = *++p;
284 j++;
285 }
286 /* Not a match. Skip it, including NUL */
287 while (ch != '\0')
288 ch = *++p;
289 p++;
290 i++;
291 }
292 return -1;
293#else
294 while (i < max) {
295 char ch;
296 j = 0;
297 /* Do we see "name\0" in applet_names[p] position? */
298 while ((ch = *p) == name[j]) {
299 if (ch == '\0') {
300 //bb_error_msg("found:'%s' i:%u", name, i); 240 //bb_error_msg("found:'%s' i:%u", name, i);
301 return i; /* yes */ 241 return i; /* yes */
302 } 242 }
303 p++;
304 j++;
305 } 243 }
306 /* No. 244 /* No. Have we gone too far, alphabetically? */
307 * p => 1st non-matching char in applet_names[], 245 if (*p > name[j]) {
308 * skip to and including NUL. 246 //bb_error_msg("break:'%s' i:%u", name, i);
309 */ 247 break;
310 while (ch != '\0') 248 }
311 ch = *++p; 249 /* No. Move to the start of the next applet name. */
312 p++; 250 while (*p++ != '\0')
251 continue;
313 i++; 252 i++;
314 } 253 }
315 return -1; 254 return -1;
316#endif
317} 255}
318 256
319 257
diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c
index 2dcead35a..66d6a479e 100644
--- a/libbb/bb_askpass.c
+++ b/libbb/bb_askpass.c
@@ -25,7 +25,7 @@ char* FAST_FUNC bb_ask_noecho(int fd, int timeout, const char *prompt)
25 /* Was buggy: was printing prompt *before* flushing input, 25 /* Was buggy: was printing prompt *before* flushing input,
26 * which was upsetting "expect" based scripts of some users. 26 * which was upsetting "expect" based scripts of some users.
27 */ 27 */
28 fputs(prompt, stdout); 28 fputs_stdout(prompt);
29 fflush_all(); 29 fflush_all();
30 30
31 tcgetattr(fd, &oldtio); 31 tcgetattr(fd, &oldtio);
diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c
index ede5a97e3..70a4c29cf 100644
--- a/libbb/compare_string_array.c
+++ b/libbb/compare_string_array.c
@@ -104,13 +104,19 @@ int FAST_FUNC index_in_str_array(const char *const string_array[], const char *k
104 104
105int FAST_FUNC index_in_strings(const char *strings, const char *key) 105int FAST_FUNC index_in_strings(const char *strings, const char *key)
106{ 106{
107 int idx = 0; 107 int j, idx = 0;
108 108
109 while (*strings) { 109 while (*strings) {
110 if (strcmp(strings, key) == 0) { 110 /* Do we see "key\0" at current position in strings? */
111 return idx; 111 for (j = 0; *strings == key[j]; ++j) {
112 if (*strings++ == '\0') {
113 //bb_error_msg("found:'%s' i:%u", key, idx);
114 return idx; /* yes */
115 }
112 } 116 }
113 strings += strlen(strings) + 1; /* skip NUL */ 117 /* No. Move to the start of the next string. */
118 while (*strings++ != '\0')
119 continue;
114 idx++; 120 idx++;
115 } 121 }
116 return -1; 122 return -1;
diff --git a/libbb/dump.c b/libbb/dump.c
index 1ba1132b3..fb7849e7d 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -560,7 +560,7 @@ static void display(priv_dumper_t* dumper)
560 ) { 560 ) {
561 if (dumper->pub.eofstring) { 561 if (dumper->pub.eofstring) {
562 /* xxd support: requested to not pad incomplete blocks */ 562 /* xxd support: requested to not pad incomplete blocks */
563 fputs(dumper->pub.eofstring, stdout); 563 fputs_stdout(dumper->pub.eofstring);
564 return; 564 return;
565 } 565 }
566 if (!(pr->flags & (F_TEXT | F_BPAD))) 566 if (!(pr->flags & (F_TEXT | F_BPAD)))
diff --git a/libbb/fgets_str.c b/libbb/fgets_str.c
index 1a7f2e9e0..c884ef8af 100644
--- a/libbb/fgets_str.c
+++ b/libbb/fgets_str.c
@@ -17,7 +17,7 @@ static char *xmalloc_fgets_internal(FILE *file, const char *terminating_string,
17 int linebufsz = 0; 17 int linebufsz = 0;
18 int idx = 0; 18 int idx = 0;
19 int ch; 19 int ch;
20 size_t maxsz = *maxsz_p; 20 size_t maxsz = maxsz_p ? *maxsz_p : INT_MAX - 4095;
21 21
22 while (1) { 22 while (1) {
23 ch = fgetc(file); 23 ch = fgetc(file);
@@ -53,7 +53,8 @@ static char *xmalloc_fgets_internal(FILE *file, const char *terminating_string,
53 /* Grow/shrink *first*, then store NUL */ 53 /* Grow/shrink *first*, then store NUL */
54 linebuf = xrealloc(linebuf, idx + 1); 54 linebuf = xrealloc(linebuf, idx + 1);
55 linebuf[idx] = '\0'; 55 linebuf[idx] = '\0';
56 *maxsz_p = idx; 56 if (maxsz_p)
57 *maxsz_p = idx;
57 return linebuf; 58 return linebuf;
58} 59}
59 60
@@ -63,23 +64,15 @@ static char *xmalloc_fgets_internal(FILE *file, const char *terminating_string,
63 * Return NULL if EOF is reached immediately. */ 64 * Return NULL if EOF is reached immediately. */
64char* FAST_FUNC xmalloc_fgets_str(FILE *file, const char *terminating_string) 65char* FAST_FUNC xmalloc_fgets_str(FILE *file, const char *terminating_string)
65{ 66{
66 size_t maxsz = INT_MAX - 4095; 67 return xmalloc_fgets_internal(file, terminating_string, 0, NULL);
67 return xmalloc_fgets_internal(file, terminating_string, 0, &maxsz);
68} 68}
69 69
70char* FAST_FUNC xmalloc_fgets_str_len(FILE *file, const char *terminating_string, size_t *maxsz_p) 70char* FAST_FUNC xmalloc_fgets_str_len(FILE *file, const char *terminating_string, size_t *maxsz_p)
71{ 71{
72 size_t maxsz;
73
74 if (!maxsz_p) {
75 maxsz = INT_MAX - 4095;
76 maxsz_p = &maxsz;
77 }
78 return xmalloc_fgets_internal(file, terminating_string, 0, maxsz_p); 72 return xmalloc_fgets_internal(file, terminating_string, 0, maxsz_p);
79} 73}
80 74
81char* FAST_FUNC xmalloc_fgetline_str(FILE *file, const char *terminating_string) 75char* FAST_FUNC xmalloc_fgetline_str(FILE *file, const char *terminating_string)
82{ 76{
83 size_t maxsz = INT_MAX - 4095; 77 return xmalloc_fgets_internal(file, terminating_string, 1, NULL);
84 return xmalloc_fgets_internal(file, terminating_string, 1, &maxsz);
85} 78}
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index f3cbc512c..27c1f3a74 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -312,7 +312,7 @@ static void BB_PUTCHAR(wchar_t c)
312 ssize_t len = wcrtomb(buf, c, &mbst); 312 ssize_t len = wcrtomb(buf, c, &mbst);
313 if (len > 0) { 313 if (len > 0) {
314 buf[len] = '\0'; 314 buf[len] = '\0';
315 fputs(buf, stdout); 315 fputs_stdout(buf);
316 } 316 }
317 } else { 317 } else {
318 /* In this case, c is always one byte */ 318 /* In this case, c is always one byte */
@@ -496,7 +496,7 @@ static void beep(void)
496 */ 496 */
497static void put_prompt_custom(bool is_full) 497static void put_prompt_custom(bool is_full)
498{ 498{
499 fputs((is_full ? cmdedit_prompt : prompt_last_line), stdout); 499 fputs_stdout((is_full ? cmdedit_prompt : prompt_last_line));
500 cursor = 0; 500 cursor = 0;
501 cmdedit_y = cmdedit_prmt_len / cmdedit_termw; /* new quasireal y */ 501 cmdedit_y = cmdedit_prmt_len / cmdedit_termw; /* new quasireal y */
502 cmdedit_x = cmdedit_prmt_len % cmdedit_termw; 502 cmdedit_x = cmdedit_prmt_len % cmdedit_termw;
@@ -1955,7 +1955,7 @@ static void ask_terminal(void)
1955 pfd.events = POLLIN; 1955 pfd.events = POLLIN;
1956 if (safe_poll(&pfd, 1, 0) == 0) { 1956 if (safe_poll(&pfd, 1, 0) == 0) {
1957 S.sent_ESC_br6n = 1; 1957 S.sent_ESC_br6n = 1;
1958 fputs(ESC"[6n", stdout); 1958 fputs_stdout(ESC"[6n");
1959 fflush_all(); /* make terminal see it ASAP! */ 1959 fflush_all(); /* make terminal see it ASAP! */
1960 } 1960 }
1961} 1961}
@@ -3085,7 +3085,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
3085#undef read_line_input 3085#undef read_line_input
3086int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize) 3086int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize)
3087{ 3087{
3088 fputs(prompt, stdout); 3088 fputs_stdout(prompt);
3089 fflush_all(); 3089 fflush_all();
3090 if (!fgets(command, maxsize, stdin)) 3090 if (!fgets(command, maxsize, stdin))
3091 return -1; 3091 return -1;
diff --git a/libbb/login.c b/libbb/login.c
index 7f593d80d..af860c277 100644
--- a/libbb/login.c
+++ b/libbb/login.c
@@ -120,7 +120,7 @@ void FAST_FUNC print_login_issue(const char *issue_file, const char *tty)
120 buf[0] = c; 120 buf[0] = c;
121 } 121 }
122 } 122 }
123 fputs(outbuf, stdout); 123 fputs_stdout(outbuf);
124 } 124 }
125 fclose(fp); 125 fclose(fp);
126 fflush_all(); 126 fflush_all();
@@ -130,8 +130,8 @@ void FAST_FUNC print_login_prompt(void)
130{ 130{
131 char *hostname = safe_gethostname(); 131 char *hostname = safe_gethostname();
132 132
133 fputs(hostname, stdout); 133 fputs_stdout(hostname);
134 fputs(LOGIN, stdout); 134 fputs_stdout(LOGIN);
135 fflush_all(); 135 fflush_all();
136 free(hostname); 136 free(hostname);
137} 137}
diff --git a/libbb/print_numbered_lines.c b/libbb/print_numbered_lines.c
index d6459d7c3..b64f85597 100644
--- a/libbb/print_numbered_lines.c
+++ b/libbb/print_numbered_lines.c
@@ -22,10 +22,11 @@ int FAST_FUNC print_numbered_lines(struct number_state *ns, const char *filename
22 if (ns->all 22 if (ns->all
23 || (ns->nonempty && line[0]) 23 || (ns->nonempty && line[0])
24 ) { 24 ) {
25 printf("%*u%s%s\n", ns->width, N, ns->sep, line); 25 printf("%*u%s", ns->width, N, ns->sep);
26 N += ns->inc; 26 N += ns->inc;
27 } else if (ns->empty_str) 27 } else if (ns->empty_str)
28 fputs(ns->empty_str, stdout); 28 fputs_stdout(ns->empty_str);
29 puts(line);
29 free(line); 30 free(line);
30 } 31 }
31 ns->start = N; 32 ns->start = N;
diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c
index 7b67f30cd..a228075cc 100644
--- a/libbb/update_passwd.c
+++ b/libbb/update_passwd.c
@@ -48,7 +48,7 @@ static void check_selinux_update_passwd(const char *username)
48 bb_simple_error_msg_and_die("SELinux: access denied"); 48 bb_simple_error_msg_and_die("SELinux: access denied");
49 } 49 }
50 if (ENABLE_FEATURE_CLEAN_UP) 50 if (ENABLE_FEATURE_CLEAN_UP)
51 freecon(context); 51 freecon(seuser);
52} 52}
53#else 53#else
54# define check_selinux_update_passwd(username) ((void)0) 54# define check_selinux_update_passwd(username) ((void)0)
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index 4bd19d471..d672e43e5 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -320,6 +320,11 @@ int FAST_FUNC bb_putchar(int ch)
320 return putchar(ch); 320 return putchar(ch);
321} 321}
322 322
323int FAST_FUNC fputs_stdout(const char *s)
324{
325 return fputs(s, stdout);
326}
327
323/* Die with an error message if we can't copy an entire FILE* to stdout, 328/* Die with an error message if we can't copy an entire FILE* to stdout,
324 * then close that file. */ 329 * then close that file. */
325void FAST_FUNC xprint_and_close_file(FILE *file) 330void FAST_FUNC xprint_and_close_file(FILE *file)
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c
index 645f1bb09..2109e2eb5 100644
--- a/loginutils/cryptpw.c
+++ b/loginutils/cryptpw.c
@@ -32,7 +32,7 @@
32//kbuild:lib-$(CONFIG_MKPASSWD) += cryptpw.o 32//kbuild:lib-$(CONFIG_MKPASSWD) += cryptpw.o
33 33
34//usage:#define cryptpw_trivial_usage 34//usage:#define cryptpw_trivial_usage
35//usage: "[-s] [-p N] [-m TYPE] [-S SALT] [PASSWORD] [SALT]" 35//usage: "[-P FD] [-m TYPE] [-S SALT] [PASSWORD] [SALT]"
36/* We do support -s, we just don't mention it */ 36/* We do support -s, we just don't mention it */
37//usage:#define cryptpw_full_usage "\n\n" 37//usage:#define cryptpw_full_usage "\n\n"
38//usage: "Print crypt(3) hashed PASSWORD\n" 38//usage: "Print crypt(3) hashed PASSWORD\n"
@@ -72,8 +72,8 @@ ENVIRONMENT
72 A list of options which will be evaluated before the ones 72 A list of options which will be evaluated before the ones
73 specified on the command line. 73 specified on the command line.
74BUGS 74BUGS
75 This programs suffers of a bad case of featuritis. 75 This program suffers of a bad case of featuritis.
76 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 76 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77 77
78Very true... 78Very true...
79 79
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 53eb5c799..02a61ac49 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -6448,7 +6448,7 @@ static BC_STATUS zdc_program_printStream(void)
6448 char *str; 6448 char *str;
6449 idx = (r->t == XC_RESULT_STR) ? r->d.id.idx : n->rdx; 6449 idx = (r->t == XC_RESULT_STR) ? r->d.id.idx : n->rdx;
6450 str = *xc_program_str(idx); 6450 str = *xc_program_str(idx);
6451 fputs(str, stdout); 6451 fputs_stdout(str);
6452 } 6452 }
6453 6453
6454 RETURN_STATUS(s); 6454 RETURN_STATUS(s);
diff --git a/miscutils/conspy.c b/miscutils/conspy.c
index fac11d339..21a498d0f 100644
--- a/miscutils/conspy.c
+++ b/miscutils/conspy.c
@@ -107,8 +107,8 @@ enum {
107 107
108static void putcsi(const char *s) 108static void putcsi(const char *s)
109{ 109{
110 fputs(ESC"[", stdout); 110 fputs_stdout(ESC"[");
111 fputs(s, stdout); 111 fputs_stdout(s);
112} 112}
113 113
114static void clrscr(void) 114static void clrscr(void)
diff --git a/miscutils/strings.c b/miscutils/strings.c
index 51412f401..e4a68227e 100644
--- a/miscutils/strings.c
+++ b/miscutils/strings.c
@@ -92,7 +92,7 @@ int strings_main(int argc UNUSED_PARAM, char **argv)
92 if (option_mask32 & (PRINT_OFFSET | PRINT_RADIX)) { 92 if (option_mask32 & (PRINT_OFFSET | PRINT_RADIX)) {
93 printf(radix_fmt, offset - n); 93 printf(radix_fmt, offset - n);
94 } 94 }
95 fputs(string, stdout); 95 fputs_stdout(string);
96 } 96 }
97 count++; 97 count++;
98 } 98 }
diff --git a/networking/brctl.c b/networking/brctl.c
index f057f9b60..e1f3e6445 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -156,7 +156,7 @@ static int show_bridge(const char *name, int need_hdr)
156 else 156 else
157 if (LONE_CHAR(filedata, '1')) 157 if (LONE_CHAR(filedata, '1'))
158 strcpy(filedata, "yes"); 158 strcpy(filedata, "yes");
159 fputs(filedata, stdout); 159 fputs_stdout(filedata);
160 160
161 /* sfx points past "BR/bridge/", turn it into "BR/brif": */ 161 /* sfx points past "BR/bridge/", turn it into "BR/brif": */
162 sfx[-4] = 'f'; sfx[-3] = '\0'; 162 sfx[-4] = 'f'; sfx[-3] = '\0';
diff --git a/networking/httpd.c b/networking/httpd.c
index 02f544593..08313bbc7 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -2923,12 +2923,12 @@ int httpd_main(int argc UNUSED_PARAM, char **argv)
2923 , &verbose 2923 , &verbose
2924 ); 2924 );
2925 if (opt & OPT_DECODE_URL) { 2925 if (opt & OPT_DECODE_URL) {
2926 fputs(percent_decode_in_place(url_for_decode, /*strict:*/ 0), stdout); 2926 fputs_stdout(percent_decode_in_place(url_for_decode, /*strict:*/ 0));
2927 return 0; 2927 return 0;
2928 } 2928 }
2929#if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR 2929#if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR
2930 if (opt & OPT_ENCODE_URL) { 2930 if (opt & OPT_ENCODE_URL) {
2931 fputs(encodeString(url_for_encode), stdout); 2931 fputs_stdout(encodeString(url_for_encode));
2932 return 0; 2932 return 0;
2933 } 2933 }
2934#endif 2934#endif
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index dfd84c000..17a838411 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -192,20 +192,20 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n)
192 printf("%c link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1)); 192 printf("%c link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1));
193 193
194 if (tb[IFLA_ADDRESS]) { 194 if (tb[IFLA_ADDRESS]) {
195 fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), 195 fputs_stdout(ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
196 RTA_PAYLOAD(tb[IFLA_ADDRESS]), 196 RTA_PAYLOAD(tb[IFLA_ADDRESS]),
197 ifi->ifi_type, 197 ifi->ifi_type,
198 b1, sizeof(b1)), stdout); 198 b1, sizeof(b1)));
199 } 199 }
200 if (tb[IFLA_BROADCAST]) { 200 if (tb[IFLA_BROADCAST]) {
201 if (ifi->ifi_flags & IFF_POINTOPOINT) 201 if (ifi->ifi_flags & IFF_POINTOPOINT)
202 printf(" peer "); 202 printf(" peer ");
203 else 203 else
204 printf(" brd "); 204 printf(" brd ");
205 fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), 205 fputs_stdout(ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
206 RTA_PAYLOAD(tb[IFLA_BROADCAST]), 206 RTA_PAYLOAD(tb[IFLA_BROADCAST]),
207 ifi->ifi_type, 207 ifi->ifi_type,
208 b1, sizeof(b1)), stdout); 208 b1, sizeof(b1)));
209 } 209 }
210 } 210 }
211 bb_putchar('\n'); 211 bb_putchar('\n');
@@ -307,9 +307,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
307 printf(" family %d ", ifa->ifa_family); 307 printf(" family %d ", ifa->ifa_family);
308 308
309 if (rta_tb[IFA_LOCAL]) { 309 if (rta_tb[IFA_LOCAL]) {
310 fputs(rt_addr_n2a(ifa->ifa_family, RTA_DATA(rta_tb[IFA_LOCAL])), 310 fputs_stdout(rt_addr_n2a(ifa->ifa_family, RTA_DATA(rta_tb[IFA_LOCAL])));
311 stdout
312 );
313 311
314 if (rta_tb[IFA_ADDRESS] == NULL 312 if (rta_tb[IFA_ADDRESS] == NULL
315 || memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0 313 || memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0
@@ -363,7 +361,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
363 if (ifa_flags) 361 if (ifa_flags)
364 printf("flags %02x ", ifa_flags); 362 printf("flags %02x ", ifa_flags);
365 if (rta_tb[IFA_LABEL]) 363 if (rta_tb[IFA_LABEL])
366 fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout); 364 fputs_stdout((char*)RTA_DATA(rta_tb[IFA_LABEL]));
367 if (rta_tb[IFA_CACHEINFO]) { 365 if (rta_tb[IFA_CACHEINFO]) {
368 struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]); 366 struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
369 char buf[128]; 367 char buf[128];
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index 50acfe4e7..a23a00d87 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -88,10 +88,9 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
88 r->rtm_src_len 88 r->rtm_src_len
89 ); 89 );
90 } else { 90 } else {
91 fputs(format_host(r->rtm_family, 91 fputs_stdout(format_host(r->rtm_family,
92 RTA_PAYLOAD(tb[RTA_SRC]), 92 RTA_PAYLOAD(tb[RTA_SRC]),
93 RTA_DATA(tb[RTA_SRC])), 93 RTA_DATA(tb[RTA_SRC]))
94 stdout
95 ); 94 );
96 } 95 }
97 } else if (r->rtm_src_len) { 96 } else if (r->rtm_src_len) {
@@ -178,7 +177,7 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
178 } else 177 } else
179 printf("masquerade"); 178 printf("masquerade");
180 } else if (r->rtm_type != RTN_UNICAST) 179 } else if (r->rtm_type != RTN_UNICAST)
181 fputs(rtnl_rtntype_n2a(r->rtm_type), stdout); 180 fputs_stdout(rtnl_rtntype_n2a(r->rtm_type));
182 181
183 bb_putchar('\n'); 182 bb_putchar('\n');
184 /*fflush_all();*/ 183 /*fflush_all();*/
diff --git a/networking/traceroute.c b/networking/traceroute.c
index 8f5cd0bf2..057f8591a 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -896,7 +896,7 @@ traceroute_init(int op, char **argv)
896 896
897 op |= getopt32(argv, "^" 897 op |= getopt32(argv, "^"
898 OPT_STRING 898 OPT_STRING
899 "\0" "-1:x-x" /* minimum 1 arg */ 899 "\0" "-1" /* minimum 1 arg */
900 , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str 900 , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
901 , &source, &waittime_str, &pausemsecs_str, &first_ttl_str 901 , &source, &waittime_str, &pausemsecs_str, &first_ttl_str
902 ); 902 );
diff --git a/networking/udhcp/dumpleases.c b/networking/udhcp/dumpleases.c
index 1e9405205..19606c58e 100644
--- a/networking/udhcp/dumpleases.c
+++ b/networking/udhcp/dumpleases.c
@@ -112,7 +112,7 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv)
112 printf("%02u:%02u:%02u\n", h, m, (unsigned)expires); 112 printf("%02u:%02u:%02u\n", h, m, (unsigned)expires);
113 } else { /* -a */ 113 } else { /* -a */
114 time_t t = expires_abs; 114 time_t t = expires_abs;
115 fputs(ctime(&t), stdout); 115 fputs_stdout(ctime(&t));
116 } 116 }
117 } 117 }
118 /* close(fd); */ 118 /* close(fd); */
diff --git a/procps/powertop.c b/procps/powertop.c
index d508b5f78..fc6018b7a 100644
--- a/procps/powertop.c
+++ b/procps/powertop.c
@@ -818,7 +818,7 @@ int powertop_main(int argc UNUSED_PARAM, char UNUSED_PARAM **argv)
818 818
819 for (i = 0; i < MAX_CSTATE_COUNT + 2; i++) 819 for (i = 0; i < MAX_CSTATE_COUNT + 2; i++)
820 if (cstate_lines[i][0]) 820 if (cstate_lines[i][0])
821 fputs(cstate_lines[i], stdout); 821 fputs_stdout(cstate_lines[i]);
822 822
823 i = process_timer_stats(); 823 i = process_timer_stats();
824#if ENABLE_FEATURE_POWERTOP_PROCIRQ 824#if ENABLE_FEATURE_POWERTOP_PROCIRQ
diff --git a/procps/top.c b/procps/top.c
index 8d39526ff..cadc4ecec 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -712,7 +712,7 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width)
712 ); 712 );
713 if ((int)(scr_width - col) > 1) 713 if ((int)(scr_width - col) > 1)
714 read_cmdline(line_buf + col, scr_width - col, s->pid, s->comm); 714 read_cmdline(line_buf + col, scr_width - col, s->pid, s->comm);
715 fputs(line_buf, stdout); 715 fputs_stdout(line_buf);
716 /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu, 716 /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu,
717 cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */ 717 cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */
718 s++; 718 s++;
diff --git a/shell/hush.c b/shell/hush.c
index 77f90f82f..5eb6fa396 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2692,7 +2692,7 @@ static int get_user_input(struct in_str *i)
2692 * Without check_and_run_traps, handler never runs. 2692 * Without check_and_run_traps, handler never runs.
2693 */ 2693 */
2694 check_and_run_traps(); 2694 check_and_run_traps();
2695 fputs(prompt_str, stdout); 2695 fputs_stdout(prompt_str);
2696 fflush_all(); 2696 fflush_all();
2697 } 2697 }
2698 r = hfgetc(i->file); 2698 r = hfgetc(i->file);
diff --git a/sysklogd/logread.c b/sysklogd/logread.c
index b52dc9cac..d5f8ca0a2 100644
--- a/sysklogd/logread.c
+++ b/sysklogd/logread.c
@@ -205,7 +205,7 @@ int logread_main(int argc UNUSED_PARAM, char **argv)
205 cur = shbuf_tail; 205 cur = shbuf_tail;
206#else 206#else
207 while (cur != shbuf_tail) { 207 while (cur != shbuf_tail) {
208 fputs(shbuf_data + cur, stdout); 208 fputs_stdout(shbuf_data + cur);
209 cur += strlen(shbuf_data + cur) + 1; 209 cur += strlen(shbuf_data + cur) + 1;
210 if (cur >= shbuf_size) 210 if (cur >= shbuf_size)
211 cur = 0; 211 cur = 0;
@@ -217,7 +217,7 @@ int logread_main(int argc UNUSED_PARAM, char **argv)
217 217
218#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING 218#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
219 for (i = 0; i < len_total; i += strlen(copy + i) + 1) { 219 for (i = 0; i < len_total; i += strlen(copy + i) + 1) {
220 fputs(copy + i, stdout); 220 fputs_stdout(copy + i);
221 } 221 }
222 free(copy); 222 free(copy);
223#endif 223#endif
diff --git a/testsuite/awk.tests b/testsuite/awk.tests
index 92c83d719..cf9b722dc 100755
--- a/testsuite/awk.tests
+++ b/testsuite/awk.tests
@@ -383,6 +383,11 @@ testing "awk errors on missing delete arg" \
383 "awk -e '{delete}' 2>&1" "awk: cmd. line:1: Too few arguments\n" "" "" 383 "awk -e '{delete}' 2>&1" "awk: cmd. line:1: Too few arguments\n" "" ""
384SKIP= 384SKIP=
385 385
386optional FEATURE_AWK_GNU_EXTENSIONS
387testing "awk printf('%c') can output NUL" \
388 "awk '{printf(\"hello%c null\n\", 0)}'" "hello\0 null\n" "" "\n"
389SKIP=
390
386# testing "description" "command" "result" "infile" "stdin" 391# testing "description" "command" "result" "infile" "stdin"
387testing 'awk negative field access' \ 392testing 'awk negative field access' \
388 'awk 2>&1 -- '\''{ $(-1) }'\' \ 393 'awk 2>&1 -- '\''{ $(-1) }'\' \
diff --git a/testsuite/cat.tests b/testsuite/cat.tests
index 10970dc90..cf924ab5b 100755
--- a/testsuite/cat.tests
+++ b/testsuite/cat.tests
@@ -22,4 +22,28 @@ testing 'cat -v' \
22 'foo\n' 22 'foo\n'
23SKIP= 23SKIP=
24 24
25optional FEATURE_CATN
26testing 'cat -n' \
27 'cat -n' \
28"\
29 1 line 1
30 2
31 3 line 3
32" \
33 '' \
34 'line 1\n\nline 3\n'
35SKIP=
36
37optional FEATURE_CATN
38testing 'cat -b' \
39 'cat -b' \
40"\
41 1 line 1
42
43 2 line 3
44" \
45 '' \
46 'line 1\n\nline 3\n'
47SKIP=
48
25exit $FAILCOUNT 49exit $FAILCOUNT
diff --git a/testsuite/nl.tests b/testsuite/nl.tests
new file mode 100755
index 000000000..95e7abb58
--- /dev/null
+++ b/testsuite/nl.tests
@@ -0,0 +1,39 @@
1#!/bin/sh
2# Copyright 2021 by Ron Yorston
3# Licensed under GPLv2, see file LICENSE in this source tree.
4
5. ./testing.sh
6
7# testing "test name" "commands" "expected result" "file input" "stdin"
8
9testing "nl numbers all lines" \
10 "nl -b a input" \
11"\
12 1 line 1
13 2
14 3 line 3
15" \
16 "line 1\n\nline 3\n" \
17 ""
18
19testing "nl numbers non-empty lines" \
20 "nl -b t input" \
21"\
22 1 line 1
23
24 2 line 3
25" \
26 "line 1\n\nline 3\n" \
27 ""
28
29testing "nl numbers no lines" \
30 "nl -b n input" \
31"\
32 line 1
33
34 line 3
35" \
36 "line 1\n\nline 3\n" \
37 ""
38
39exit $FAILCOUNT
diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c
index e884e3dc1..4c30f31f8 100644
--- a/util-linux/fdisk_gpt.c
+++ b/util-linux/fdisk_gpt.c
@@ -87,7 +87,7 @@ gpt_print_wide36(uint16_t *s)
87 } 87 }
88 wc[i] = 0; 88 wc[i] = 0;
89 if (wcstombs(buf, wc, sizeof(buf)) <= sizeof(buf)-1) 89 if (wcstombs(buf, wc, sizeof(buf)) <= sizeof(buf)-1)
90 fputs(printable_string(buf), stdout); 90 fputs_stdout(printable_string(buf));
91#else 91#else
92 char buf[37]; 92 char buf[37];
93 int i = 0; 93 int i = 0;
@@ -98,7 +98,7 @@ gpt_print_wide36(uint16_t *s)
98 i++; 98 i++;
99 } 99 }
100 buf[i] = '\0'; 100 buf[i] = '\0';
101 fputs(buf, stdout); 101 fputs_stdout(buf);
102#endif 102#endif
103} 103}
104 104
diff --git a/util-linux/rev.c b/util-linux/rev.c
index 31800fa51..cfcd12392 100644
--- a/util-linux/rev.c
+++ b/util-linux/rev.c
@@ -112,7 +112,7 @@ int rev_main(int argc UNUSED_PARAM, char **argv)
112#else 112#else
113 strrev(buf, strlen(buf)); 113 strrev(buf, strlen(buf));
114#endif 114#endif
115 fputs(buf, stdout); 115 fputs_stdout(buf);
116 } 116 }
117 fclose(fp); 117 fclose(fp);
118 } while (*argv); 118 } while (*argv);