aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-03-17 09:07:36 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-03-17 09:07:36 +0000
commit62a90cdd7435f09f4bb8673e8b7b213067f9d5cc (patch)
treeac7f86c4de0ce0c095b59820c7ba238369c65f71
parentd02db892440499a072ea8c83c2370e9d9c103098 (diff)
downloadbusybox-w32-62a90cdd7435f09f4bb8673e8b7b213067f9d5cc.tar.gz
busybox-w32-62a90cdd7435f09f4bb8673e8b7b213067f9d5cc.tar.bz2
busybox-w32-62a90cdd7435f09f4bb8673e8b7b213067f9d5cc.zip
*: shrink by using [f]open_or_warn_stdin where appropriate
function old new delta lsattr_main 62 143 +81 open_or_warn_stdin - 36 +36 fclose_if_not_stdin 20 47 +27 xfopen_stdin - 20 +20 tac_main 336 356 +20 cksum_main 249 259 +10 bb_argv_dash - 8 +8 su_main 448 455 +7 cmp_main 630 633 +3 passwd_main 1072 1074 +2 uudecode_main 317 315 -2 text_yank 110 108 -2 handle_incoming_and_exit 2653 2651 -2 flags 5 1 -4 write_leases 235 230 -5 fopen_or_warn_stdin 48 42 -6 fold_main 648 642 -6 static.argv_dash 8 - -8 sum_main 142 128 -14 tail_main 1237 1221 -16 sed_main 711 695 -16 cmp_xfopen_input 17 - -17 bb_cat 113 96 -17 catv_main 328 306 -22 strings_main 457 434 -23 hash_file 298 274 -24 sum_file 353 325 -28 sort_main 904 859 -45 expand_main 736 686 -50 cut_main 1116 1065 -51 md5_sha1_sum_main 549 493 -56 lsattr_args 90 - -90 read_stduu 408 255 -153 ------------------------------------------------------------------------------ (add/remove: 3/3 grow/shrink: 7/20 up/down: 214/-657) Total: -443 bytes text data bss dec hex filename 797417 658 7428 805503 c4a7f busybox_old 796973 658 7428 805059 c48c3 busybox_unstripped
-rw-r--r--coreutils/cat.c8
-rw-r--r--coreutils/catv.c10
-rw-r--r--coreutils/cksum.c38
-rw-r--r--coreutils/cut.c17
-rw-r--r--coreutils/expand.c23
-rw-r--r--coreutils/fold.c29
-rw-r--r--coreutils/head.c10
-rw-r--r--coreutils/md5_sha1_sum.c37
-rw-r--r--coreutils/sort.c16
-rw-r--r--coreutils/sum.c27
-rw-r--r--coreutils/tac.c24
-rw-r--r--coreutils/tail.c22
-rw-r--r--coreutils/uudecode.c70
-rw-r--r--coreutils/yes.c9
-rw-r--r--e2fsprogs/lsattr.c6
-rw-r--r--editors/cmp.c14
-rw-r--r--editors/sed.c11
-rw-r--r--include/libbb.h3
-rw-r--r--libbb/fclose_nonstdin.c10
-rw-r--r--libbb/getopt32.c2
-rw-r--r--libbb/wfopen_input.c25
-rw-r--r--loginutils/su.c10
-rw-r--r--miscutils/strings.c6
-rw-r--r--networking/udhcp/files.c2
-rw-r--r--shell/lash_unused.c2
-rw-r--r--util-linux/hexdump.c2
26 files changed, 214 insertions, 219 deletions
diff --git a/coreutils/cat.c b/coreutils/cat.c
index 181d96a2c..989147b39 100644
--- a/coreutils/cat.c
+++ b/coreutils/cat.c
@@ -17,18 +17,14 @@
17 17
18int bb_cat(char **argv) 18int bb_cat(char **argv)
19{ 19{
20 static const char *const argv_dash[] = { "-", NULL };
21
22 int fd; 20 int fd;
23 int retval = EXIT_SUCCESS; 21 int retval = EXIT_SUCCESS;
24 22
25 if (!*argv) 23 if (!*argv)
26 argv = (char**) &argv_dash; 24 argv = (char**) &bb_argv_dash;
27 25
28 do { 26 do {
29 fd = STDIN_FILENO; 27 fd = open_or_warn_stdin(*argv);
30 if (!LONE_DASH(*argv))
31 fd = open_or_warn(*argv, O_RDONLY);
32 if (fd >= 0) { 28 if (fd >= 0) {
33 /* This is not a xfunc - never exits */ 29 /* This is not a xfunc - never exits */
34 off_t r = bb_copyfd_eof(fd, STDOUT_FILENO); 30 off_t r = bb_copyfd_eof(fd, STDOUT_FILENO);
diff --git a/coreutils/catv.c b/coreutils/catv.c
index a5ee534e2..b87740ec9 100644
--- a/coreutils/catv.c
+++ b/coreutils/catv.c
@@ -27,18 +27,14 @@ int catv_main(int argc ATTRIBUTE_UNUSED, char **argv)
27 argv += optind; 27 argv += optind;
28 28
29 /* Read from stdin if there's nothing else to do. */ 29 /* Read from stdin if there's nothing else to do. */
30 fd = 0; 30 if (!argv[0])
31 if (!argv[0]) { 31 *--argv = (char*)"-";
32 argv--;
33 goto jump_in;
34 }
35 do { 32 do {
36 fd = open_or_warn(*argv, O_RDONLY); 33 fd = open_or_warn_stdin(*argv);
37 if (fd < 0) { 34 if (fd < 0) {
38 retval = EXIT_FAILURE; 35 retval = EXIT_FAILURE;
39 continue; 36 continue;
40 } 37 }
41 jump_in:
42 for (;;) { 38 for (;;) {
43 int i, res; 39 int i, res;
44 40
diff --git a/coreutils/cksum.c b/coreutils/cksum.c
index dd274afc2..6512ccc17 100644
--- a/coreutils/cksum.c
+++ b/coreutils/cksum.c
@@ -9,46 +9,48 @@
9#include "libbb.h" 9#include "libbb.h"
10 10
11int cksum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 11int cksum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
12int cksum_main(int argc, char **argv) 12int cksum_main(int argc ATTRIBUTE_UNUSED, char **argv)
13{ 13{
14 uint32_t *crc32_table = crc32_filltable(NULL, 1); 14 uint32_t *crc32_table = crc32_filltable(NULL, 1);
15
16 FILE *fp;
17 uint32_t crc; 15 uint32_t crc;
18 long length, filesize; 16 long length, filesize;
19 int bytes_read; 17 int bytes_read;
20 char *cp; 18 uint8_t *cp;
21 19
22 int inp_stdin = (argc == optind) ? 1 : 0; 20#if ENABLE_DESKTOP
21 getopt32(argv, ""); /* coreutils 6.9 compat */
22 argv += optind;
23#else
24 argv++;
25#endif
23 26
24 do { 27 do {
25 fp = fopen_or_warn_stdin((inp_stdin) ? bb_msg_standard_input : *++argv); 28 int fd = open_or_warn_stdin(*argv ? *argv : bb_msg_standard_input);
26 29
30 if (fd < 0)
31 continue;
27 crc = 0; 32 crc = 0;
28 length = 0; 33 length = 0;
29 34
30#define read_buf bb_common_bufsiz1 35#define read_buf bb_common_bufsiz1
31 while ((bytes_read = fread(read_buf, 1, BUFSIZ, fp)) > 0) { 36 while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) {
32 cp = read_buf; 37 cp = read_buf;
33 length += bytes_read; 38 length += bytes_read;
34 while (bytes_read--) 39 do {
35 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL]; 40 crc = (crc << 8) ^ crc32_table[(crc >> 24) ^ *cp++];
41 } while (--bytes_read);
36 } 42 }
43 close(fd);
37 44
38 filesize = length; 45 filesize = length;
39 46
40 for (; length; length >>= 8) 47 for (; length; length >>= 8)
41 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL]; 48 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xff];
42 crc ^= 0xffffffffL; 49 crc ^= 0xffffffffL;
43 50
44 if (inp_stdin) { 51 printf((*argv ? "%" PRIu32 " %li %s\n" : "%" PRIu32 " %li\n"),
45 printf("%" PRIu32 " %li\n", crc, filesize); 52 crc, filesize, *argv);
46 break; 53 } while (*argv && *++argv);
47 }
48
49 printf("%" PRIu32 " %li %s\n", crc, filesize, *argv);
50 fclose(fp);
51 } while (*(argv + 1));
52 54
53 fflush_stdout_and_exit(EXIT_SUCCESS); 55 fflush_stdout_and_exit(EXIT_SUCCESS);
54} 56}
diff --git a/coreutils/cut.c b/coreutils/cut.c
index ed6f8f608..e617ef28f 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -205,7 +205,7 @@ int cut_main(int argc ATTRIBUTE_UNUSED, char **argv)
205 char *ntok; 205 char *ntok;
206 int s = 0, e = 0; 206 int s = 0, e = 0;
207 207
208 /* take apart the lists, one by one (they are separated with commas */ 208 /* take apart the lists, one by one (they are separated with commas) */
209 while ((ltok = strsep(&sopt, ",")) != NULL) { 209 while ((ltok = strsep(&sopt, ",")) != NULL) {
210 210
211 /* it's actually legal to pass an empty list */ 211 /* it's actually legal to pass an empty list */
@@ -258,25 +258,18 @@ int cut_main(int argc ATTRIBUTE_UNUSED, char **argv)
258 258
259 { 259 {
260 int retval = EXIT_SUCCESS; 260 int retval = EXIT_SUCCESS;
261 FILE *file = stdin;
262 261
263 if (!*argv) { 262 if (!*argv)
264 argv--; 263 *--argv = (char *)"-";
265 goto jump_in;
266 }
267 264
268 do { 265 do {
269 file = stdin; 266 FILE *file = fopen_or_warn_stdin(*argv);
270 if (NOT_LONE_DASH(*argv))
271 file = fopen_or_warn(*argv, "r");
272 if (!file) { 267 if (!file) {
273 retval = EXIT_FAILURE; 268 retval = EXIT_FAILURE;
274 continue; 269 continue;
275 } 270 }
276 jump_in:
277 cut_file(file, delim); 271 cut_file(file, delim);
278 if (NOT_LONE_DASH(*argv)) 272 fclose_if_not_stdin(file);
279 fclose(file);
280 } while (*++argv); 273 } while (*++argv);
281 274
282 if (ENABLE_FEATURE_CLEAN_UP) 275 if (ENABLE_FEATURE_CLEAN_UP)
diff --git a/coreutils/expand.c b/coreutils/expand.c
index c0133956f..a7ac8ea84 100644
--- a/coreutils/expand.c
+++ b/coreutils/expand.c
@@ -154,7 +154,7 @@ int expand_main(int argc ATTRIBUTE_UNUSED, char **argv)
154 if (ENABLE_EXPAND && (!ENABLE_UNEXPAND || applet_name[0] == 'e')) { 154 if (ENABLE_EXPAND && (!ENABLE_UNEXPAND || applet_name[0] == 'e')) {
155 USE_FEATURE_EXPAND_LONG_OPTIONS(applet_long_options = expand_longopts); 155 USE_FEATURE_EXPAND_LONG_OPTIONS(applet_long_options = expand_longopts);
156 opt = getopt32(argv, "it:", &opt_t); 156 opt = getopt32(argv, "it:", &opt_t);
157 } else if (ENABLE_UNEXPAND) { 157 } else {
158 USE_FEATURE_UNEXPAND_LONG_OPTIONS(applet_long_options = unexpand_longopts); 158 USE_FEATURE_UNEXPAND_LONG_OPTIONS(applet_long_options = unexpand_longopts);
159 /* -t NUM sets also -a */ 159 /* -t NUM sets also -a */
160 opt_complementary = "ta"; 160 opt_complementary = "ta";
@@ -166,32 +166,23 @@ int expand_main(int argc ATTRIBUTE_UNUSED, char **argv)
166 166
167 argv += optind; 167 argv += optind;
168 168
169 /* If no args are given, read from stdin */
170 if (!*argv) { 169 if (!*argv) {
171 *--argv = (char*)bb_msg_standard_input; 170 *--argv = (char*)bb_msg_standard_input;
172 goto use_stdin;
173 } 171 }
174
175 do { 172 do {
176 if (NOT_LONE_CHAR(*argv, '-')) { 173 file = fopen_or_warn_stdin(*argv);
177 file = fopen_or_warn(*argv, "r"); 174 if (!file) {
178 if (!file) { 175 exit_status = EXIT_FAILURE;
179 exit_status = EXIT_FAILURE; 176 continue;
180 continue;
181 }
182 } else {
183 use_stdin:
184 file = stdin;
185 } 177 }
186 178
187 if (ENABLE_EXPAND && (!ENABLE_UNEXPAND || applet_name[0] == 'e')) 179 if (ENABLE_EXPAND && (!ENABLE_UNEXPAND || applet_name[0] == 'e'))
188 USE_EXPAND(expand(file, tab_size, opt)); 180 USE_EXPAND(expand(file, tab_size, opt));
189 else if (ENABLE_UNEXPAND) 181 else
190 USE_UNEXPAND(unexpand(file, tab_size, opt)); 182 USE_UNEXPAND(unexpand(file, tab_size, opt));
191 183
192 /* Check and close the file */ 184 /* Check and close the file */
193 /* We do want all of them to execute, thus | instead of || */ 185 if (fclose_if_not_stdin(file)) {
194 if (ferror(file) | fclose_if_not_stdin(file)) {
195 bb_simple_perror_msg(*argv); 186 bb_simple_perror_msg(*argv);
196 exit_status = EXIT_FAILURE; 187 exit_status = EXIT_FAILURE;
197 } 188 }
diff --git a/coreutils/fold.c b/coreutils/fold.c
index ed484edf0..e2a30d5d4 100644
--- a/coreutils/fold.c
+++ b/coreutils/fold.c
@@ -12,18 +12,17 @@
12 12
13#include "libbb.h" 13#include "libbb.h"
14 14
15static unsigned long flags; 15/* Must match getopt32 call */
16#define FLAG_COUNT_BYTES 1 16#define FLAG_COUNT_BYTES 1
17#define FLAG_BREAK_SPACES 2 17#define FLAG_BREAK_SPACES 2
18#define FLAG_WIDTH 4 18#define FLAG_WIDTH 4
19 19
20/* Assuming the current column is COLUMN, return the column that 20/* Assuming the current column is COLUMN, return the column that
21 printing C will move the cursor to. 21 printing C will move the cursor to.
22 The first column is 0. */ 22 The first column is 0. */
23
24static int adjust_column(int column, char c) 23static int adjust_column(int column, char c)
25{ 24{
26 if (!(flags & FLAG_COUNT_BYTES)) { 25 if (!(option_mask32 & FLAG_COUNT_BYTES)) {
27 if (c == '\b') { 26 if (c == '\b') {
28 if (column > 0) 27 if (column > 0)
29 column--; 28 column--;
@@ -54,29 +53,27 @@ int fold_main(int argc, char **argv)
54 char const *a = argv[i]; 53 char const *a = argv[i];
55 54
56 if (*a++ == '-') { 55 if (*a++ == '-') {
57 if (*a == '-' && !a[1]) 56 if (*a == '-' && !a[1]) /* "--" */
58 break; 57 break;
59 if (isdigit(*a)) { 58 if (isdigit(*a))
60 argv[i] = xasprintf("-w%s", a); 59 argv[i] = xasprintf("-w%s", a);
61 }
62 } 60 }
63 } 61 }
64 } 62 }
65 63
66 flags = getopt32(argv, "bsw:", &w_opt); 64 getopt32(argv, "bsw:", &w_opt);
67 if (flags & FLAG_WIDTH) 65 if (option_mask32 & FLAG_WIDTH)
68 width = xatoul_range(w_opt, 1, 10000); 66 width = xatoul_range(w_opt, 1, 10000);
69 67
70 argv += optind; 68 argv += optind;
71 if (!*argv) { 69 if (!*argv)
72 *--argv = (char*)"-"; 70 *--argv = (char*)"-";
73 }
74 71
75 do { 72 do {
76 FILE *istream = fopen_or_warn_stdin(*argv); 73 FILE *istream = fopen_or_warn_stdin(*argv);
77 int c; 74 int c;
78 int column = 0; /* Screen column where next char will go. */ 75 int column = 0; /* Screen column where next char will go. */
79 int offset_out = 0; /* Index in `line_out' for next char. */ 76 int offset_out = 0; /* Index in 'line_out' for next char. */
80 77
81 if (istream == NULL) { 78 if (istream == NULL) {
82 errs |= EXIT_FAILURE; 79 errs |= EXIT_FAILURE;
@@ -102,7 +99,7 @@ int fold_main(int argc, char **argv)
102 /* This character would make the line too long. 99 /* This character would make the line too long.
103 Print the line plus a newline, and make this character 100 Print the line plus a newline, and make this character
104 start the next line. */ 101 start the next line. */
105 if (flags & FLAG_BREAK_SPACES) { 102 if (option_mask32 & FLAG_BREAK_SPACES) {
106 /* Look for the last blank. */ 103 /* Look for the last blank. */
107 int logical_end; 104 int logical_end;
108 105
@@ -144,7 +141,7 @@ int fold_main(int argc, char **argv)
144 fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); 141 fwrite(line_out, sizeof(char), (size_t) offset_out, stdout);
145 } 142 }
146 143
147 if (ferror(istream) || fclose_if_not_stdin(istream)) { 144 if (fclose_if_not_stdin(istream)) {
148 bb_simple_perror_msg(*argv); /* Avoid multibyte problems. */ 145 bb_simple_perror_msg(*argv); /* Avoid multibyte problems. */
149 errs |= EXIT_FAILURE; 146 errs |= EXIT_FAILURE;
150 } 147 }
diff --git a/coreutils/head.c b/coreutils/head.c
index 629307719..570f140b1 100644
--- a/coreutils/head.c
+++ b/coreutils/head.c
@@ -91,19 +91,19 @@ int head_main(int argc, char **argv)
91 } 91 }
92 } 92 }
93 93
94 argc -= optind;
94 argv += optind; 95 argv += optind;
95 if (!*argv) { 96 if (!*argv)
96 *--argv = (char*)"-"; 97 *--argv = (char*)"-";
97 }
98 98
99 fmt = header_fmt_str + 1; 99 fmt = header_fmt_str + 1;
100#if ENABLE_FEATURE_FANCY_HEAD 100#if ENABLE_FEATURE_FANCY_HEAD
101 if (argc - optind <= header_threshhold) { 101 if (argc <= header_threshhold) {
102 header_threshhold = 0; 102 header_threshhold = 0;
103 } 103 }
104#else 104#else
105 if (argc <= optind + 1) { 105 if (argc <= 1) {
106 fmt += 11; 106 fmt += 11; /* "" */
107 } 107 }
108 /* Now define some things here to avoid #ifdefs in the code below. 108 /* Now define some things here to avoid #ifdefs in the code below.
109 * These should optimize out of the if conditions below. */ 109 * These should optimize out of the if conditions below. */
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index e94f2ceb1..080eac5f4 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -36,12 +36,9 @@ static uint8_t *hash_file(const char *filename, hash_algo_t hash_algo)
36 void (*update)(const void*, size_t, void*); 36 void (*update)(const void*, size_t, void*);
37 void (*final)(void*, void*); 37 void (*final)(void*, void*);
38 38
39 src_fd = STDIN_FILENO; 39 src_fd = open_or_warn_stdin(filename);
40 if (NOT_LONE_DASH(filename)) { 40 if (src_fd < 0) {
41 src_fd = open_or_warn(filename, O_RDONLY); 41 return NULL;
42 if (src_fd < 0) {
43 return NULL;
44 }
45 } 42 }
46 43
47 /* figure specific hash algorithims */ 44 /* figure specific hash algorithims */
@@ -78,7 +75,7 @@ static uint8_t *hash_file(const char *filename, hash_algo_t hash_algo)
78} 75}
79 76
80int md5_sha1_sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 77int md5_sha1_sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
81int md5_sha1_sum_main(int argc, char **argv) 78int md5_sha1_sum_main(int argc ATTRIBUTE_UNUSED, char **argv)
82{ 79{
83 int return_value = EXIT_SUCCESS; 80 int return_value = EXIT_SUCCESS;
84 uint8_t *hash_value; 81 uint8_t *hash_value;
@@ -90,6 +87,10 @@ int md5_sha1_sum_main(int argc, char **argv)
90 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) 87 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK)
91 flags = getopt32(argv, "scw"); 88 flags = getopt32(argv, "scw");
92 else optind = 1; 89 else optind = 1;
90 argv += optind;
91 //argc -= optind;
92 if (!*argv)
93 *--argv = (char*)"-";
93 94
94 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) { 95 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) {
95 if (flags & FLAG_SILENT) { 96 if (flags & FLAG_SILENT) {
@@ -101,26 +102,18 @@ int md5_sha1_sum_main(int argc, char **argv)
101 } 102 }
102 } 103 }
103 104
104 if (argc == optind) {
105 argv[argc++] = (char*)"-";
106 }
107
108 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) { 105 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
109 FILE *pre_computed_stream; 106 FILE *pre_computed_stream;
110 int count_total = 0; 107 int count_total = 0;
111 int count_failed = 0; 108 int count_failed = 0;
112 char *file_ptr = argv[optind];
113 char *line; 109 char *line;
114 110
115 if (optind + 1 != argc) { 111 if (argv[1]) {
116 bb_error_msg_and_die 112 bb_error_msg_and_die
117 ("only one argument may be specified when using -c"); 113 ("only one argument may be specified when using -c");
118 } 114 }
119 115
120 pre_computed_stream = stdin; 116 pre_computed_stream = xfopen_stdin(argv[0]);
121 if (NOT_LONE_DASH(file_ptr)) {
122 pre_computed_stream = xfopen(file_ptr, "r");
123 }
124 117
125 while ((line = xmalloc_getline(pre_computed_stream)) != NULL) { 118 while ((line = xmalloc_getline(pre_computed_stream)) != NULL) {
126 char *filename_ptr; 119 char *filename_ptr;
@@ -168,17 +161,15 @@ int md5_sha1_sum_main(int argc, char **argv)
168 } 161 }
169 */ 162 */
170 } else { 163 } else {
171 while (optind < argc) { 164 do {
172 char *file_ptr = argv[optind++]; 165 hash_value = hash_file(*argv, hash_algo);
173
174 hash_value = hash_file(file_ptr, hash_algo);
175 if (hash_value == NULL) { 166 if (hash_value == NULL) {
176 return_value = EXIT_FAILURE; 167 return_value = EXIT_FAILURE;
177 } else { 168 } else {
178 printf("%s %s\n", hash_value, file_ptr); 169 printf("%s %s\n", hash_value, *argv);
179 free(hash_value); 170 free(hash_value);
180 } 171 }
181 } 172 } while (*++argv);
182 } 173 }
183 return return_value; 174 return return_value;
184} 175}
diff --git a/coreutils/sort.c b/coreutils/sort.c
index 510f7a235..15566ce2b 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -351,10 +351,13 @@ int sort_main(int argc ATTRIBUTE_UNUSED, char **argv)
351 if (option_mask32 & FLAG_b) option_mask32 |= FLAG_bb; 351 if (option_mask32 & FLAG_b) option_mask32 |= FLAG_bb;
352 352
353 /* Open input files and read data */ 353 /* Open input files and read data */
354 for (i = argv[optind] ? optind : optind-1; argv[i]; i++) { 354 argv += optind;
355 fp = stdin; 355 if (!*argv)
356 if (i >= optind && NOT_LONE_DASH(argv[i])) 356 *--argv = (char*)"-";
357 fp = xfopen(argv[i], "r"); 357 do {
358 /* coreutils 6.9 compat: abort on first open error,
359 * do not continue to next file: */
360 fp = xfopen_stdin(*argv);
358 for (;;) { 361 for (;;) {
359 line = GET_LINE(fp); 362 line = GET_LINE(fp);
360 if (!line) break; 363 if (!line) break;
@@ -362,8 +365,9 @@ int sort_main(int argc ATTRIBUTE_UNUSED, char **argv)
362 lines = xrealloc(lines, sizeof(char *) * (linecount + 64)); 365 lines = xrealloc(lines, sizeof(char *) * (linecount + 64));
363 lines[linecount++] = line; 366 lines[linecount++] = line;
364 } 367 }
365 fclose(fp); 368 fclose_if_not_stdin(fp);
366 } 369 } while (*++argv);
370
367#if ENABLE_FEATURE_SORT_BIG 371#if ENABLE_FEATURE_SORT_BIG
368 /* if no key, perform alphabetic sort */ 372 /* if no key, perform alphabetic sort */
369 if (!key_list) 373 if (!key_list)
diff --git a/coreutils/sum.c b/coreutils/sum.c
index 65478b0a1..e6cfbfd80 100644
--- a/coreutils/sum.c
+++ b/coreutils/sum.c
@@ -21,20 +21,17 @@ enum { SUM_BSD, PRINT_NAME, SUM_SYSV };
21 The checksum varies depending on sizeof (int). */ 21 The checksum varies depending on sizeof (int). */
22/* SYSV: calculate and print the checksum and the size in 512-byte blocks */ 22/* SYSV: calculate and print the checksum and the size in 512-byte blocks */
23/* Return 1 if successful. */ 23/* Return 1 if successful. */
24static unsigned sum_file(const char *file, const unsigned type) 24static unsigned sum_file(const char *file, unsigned type)
25{ 25{
26#define buf bb_common_bufsiz1 26#define buf bb_common_bufsiz1
27 unsigned long long total_bytes = 0; 27 unsigned long long total_bytes = 0;
28 int fd = 0, r; 28 int fd, r;
29
30 /* The sum of all the input bytes, modulo (UINT_MAX + 1). */ 29 /* The sum of all the input bytes, modulo (UINT_MAX + 1). */
31 unsigned s = 0; 30 unsigned s = 0;
32 31
33 if (NOT_LONE_DASH(file)) { 32 fd = open_or_warn_stdin(file);
34 fd = open(file, O_RDONLY); 33 if (fd == -1)
35 if (fd == -1) 34 return 0;
36 goto ret_bad;
37 }
38 35
39 while (1) { 36 while (1) {
40 size_t bytes_read = safe_read(fd, buf, BUFSIZ); 37 size_t bytes_read = safe_read(fd, buf, BUFSIZ);
@@ -44,7 +41,6 @@ static unsigned sum_file(const char *file, const unsigned type)
44 if (!bytes_read && !r) 41 if (!bytes_read && !r)
45 /* no error */ 42 /* no error */
46 break; 43 break;
47 ret_bad:
48 bb_perror_msg(file); 44 bb_perror_msg(file);
49 return 0; 45 return 0;
50 } 46 }
@@ -75,26 +71,29 @@ static unsigned sum_file(const char *file, const unsigned type)
75} 71}
76 72
77int sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 73int sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
78int sum_main(int argc, char **argv) 74int sum_main(int argc ATTRIBUTE_UNUSED, char **argv)
79{ 75{
80 unsigned n; 76 unsigned n;
81 unsigned type = SUM_BSD; 77 unsigned type = SUM_BSD;
82 78
83 n = getopt32(argv, "sr"); 79 n = getopt32(argv, "sr");
80 argv += optind;
84 if (n & 1) type = SUM_SYSV; 81 if (n & 1) type = SUM_SYSV;
85 /* give the bsd priority over sysv func */ 82 /* give the bsd priority over sysv func */
86 if (n & 2) type = SUM_BSD; 83 if (n & 2) type = SUM_BSD;
87 84
88 if (argc == optind) { 85 if (!argv[0]) {
89 /* Do not print the name */ 86 /* Do not print the name */
90 n = sum_file("-", type); 87 n = sum_file("-", type);
91 } else { 88 } else {
92 /* Need to print the name if either 89 /* Need to print the name if either
93 - more than one file given 90 - more than one file given
94 - doing sysv */ 91 - doing sysv */
95 type += argc - 1 > optind || type == SUM_SYSV; 92 type += (argv[1] || type == SUM_SYSV);
96 for (n = 1; optind < argc; optind++) 93 n = 1;
97 n &= sum_file(argv[optind], type); 94 do {
95 n &= sum_file(*argv, type);
96 } while (*++argv);
98 } 97 }
99 return !n; 98 return !n;
100} 99}
diff --git a/coreutils/tac.c b/coreutils/tac.c
index ddadcc7bc..af70f3092 100644
--- a/coreutils/tac.c
+++ b/coreutils/tac.c
@@ -22,7 +22,7 @@
22 22
23struct lstring { 23struct lstring {
24 int size; 24 int size;
25 char buf[]; 25 char buf[1];
26}; 26};
27 27
28int tac_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 28int tac_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -34,7 +34,21 @@ int tac_main(int argc ATTRIBUTE_UNUSED, char **argv)
34 llist_t *list = NULL; 34 llist_t *list = NULL;
35 int retval = EXIT_SUCCESS; 35 int retval = EXIT_SUCCESS;
36 36
37#if ENABLE_DESKTOP
38/* tac from coreutils 6.9 supports:
39 -b, --before
40 attach the separator before instead of after
41 -r, --regex
42 interpret the separator as a regular expression
43 -s, --separator=STRING
44 use STRING as the separator instead of newline
45We support none, but at least we will complain or handle "--":
46*/
47 getopt32(argv, "");
48 argv += optind;
49#else
37 argv++; 50 argv++;
51#endif
38 if (!*argv) 52 if (!*argv)
39 *--argv = (char *)"-"; 53 *--argv = (char *)"-";
40 /* We will read from last file to first */ 54 /* We will read from last file to first */
@@ -48,6 +62,7 @@ int tac_main(int argc ATTRIBUTE_UNUSED, char **argv)
48 name--; 62 name--;
49 f = fopen_or_warn_stdin(*name); 63 f = fopen_or_warn_stdin(*name);
50 if (f == NULL) { 64 if (f == NULL) {
65 /* error message is printed by fopen_or_warn_stdin */
51 retval = EXIT_FAILURE; 66 retval = EXIT_FAILURE;
52 continue; 67 continue;
53 } 68 }
@@ -61,7 +76,7 @@ int tac_main(int argc ATTRIBUTE_UNUSED, char **argv)
61 line = xrealloc(line, i + 0x7f + sizeof(int) + 1); 76 line = xrealloc(line, i + 0x7f + sizeof(int) + 1);
62 line->buf[i++] = ch; 77 line->buf[i++] = ch;
63 } 78 }
64 if ((ch == '\n' || ch == EOF) && i) { 79 if (ch == '\n' || (ch == EOF && i != 0)) {
65 line = xrealloc(line, i + sizeof(int)); 80 line = xrealloc(line, i + sizeof(int));
66 line->size = i; 81 line->size = i;
67 llist_add_to(&list, line); 82 llist_add_to(&list, line);
@@ -69,9 +84,8 @@ int tac_main(int argc ATTRIBUTE_UNUSED, char **argv)
69 i = 0; 84 i = 0;
70 } 85 }
71 } while (ch != EOF); 86 } while (ch != EOF);
72 /* fgetc sets errno to ENOENT on EOF, but */ 87 /* fgetc sets errno to ENOENT on EOF, we don't want
73 /* fopen_or_warn_stdin would catch this error */ 88 * to warn on this non-error! */
74 /* so we can filter it out here. */
75 if (errno && errno != ENOENT) { 89 if (errno && errno != ENOENT) {
76 bb_simple_perror_msg(*name); 90 bb_simple_perror_msg(*name);
77 retval = EXIT_FAILURE; 91 retval = EXIT_FAILURE;
diff --git a/coreutils/tail.c b/coreutils/tail.c
index 340697f88..52aa8f69e 100644
--- a/coreutils/tail.c
+++ b/coreutils/tail.c
@@ -101,16 +101,12 @@ int tail_main(int argc, char **argv)
101 101
102#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL 102#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL
103 /* Allow legacy syntax of an initial numeric option without -n. */ 103 /* Allow legacy syntax of an initial numeric option without -n. */
104 if (argc >= 2 && (argv[1][0] == '+' || argv[1][0] == '-') 104 if (argv[1] && (argv[1][0] == '+' || argv[1][0] == '-')
105 && isdigit(argv[1][1]) 105 && isdigit(argv[1][1])
106 ) { 106 ) {
107 /* replacing arg[0] with "-n" can segfault, so... */ 107 count = eat_num(&argv[1][1]);
108 argv[1] = xasprintf("-n%s", argv[1]); 108 argv++;
109#if 0 /* If we ever decide to make tail NOFORK */ 109 argc--;
110 char *s = alloca(strlen(argv[1]) + 3);
111 sprintf(s, "-n%s", argv[1]);
112 argv[1] = s;
113#endif
114 } 110 }
115#endif 111#endif
116 112
@@ -133,8 +129,7 @@ int tail_main(int argc, char **argv)
133 129
134 /* open all the files */ 130 /* open all the files */
135 fds = xmalloc(sizeof(int) * (argc + 1)); 131 fds = xmalloc(sizeof(int) * (argc + 1));
136 nfiles = i = 0; 132 if (!argv[0]) {
137 if (argc == 0) {
138 struct stat statbuf; 133 struct stat statbuf;
139 134
140 if (!fstat(STDIN_FILENO, &statbuf) && S_ISFIFO(statbuf.st_mode)) { 135 if (!fstat(STDIN_FILENO, &statbuf) && S_ISFIFO(statbuf.st_mode)) {
@@ -142,13 +137,14 @@ int tail_main(int argc, char **argv)
142 } 137 }
143 *argv = (char *) bb_msg_standard_input; 138 *argv = (char *) bb_msg_standard_input;
144 } 139 }
140 nfiles = i = 0;
145 do { 141 do {
146 FILE* fil = fopen_or_warn_stdin(argv[i]); 142 int fd = open_or_warn_stdin(argv[i]);
147 if (!fil) { 143 if (fd < 0) {
148 G.status = EXIT_FAILURE; 144 G.status = EXIT_FAILURE;
149 continue; 145 continue;
150 } 146 }
151 fds[nfiles] = fileno(fil); 147 fds[nfiles] = fd;
152 argv[nfiles++] = argv[i]; 148 argv[nfiles++] = argv[i];
153 } while (++i < argc); 149 } while (++i < argc);
154 150
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c
index 34a22398c..4c619dec5 100644
--- a/coreutils/uudecode.c
+++ b/coreutils/uudecode.c
@@ -19,48 +19,57 @@ static void read_stduu(FILE *src_stream, FILE *dst_stream)
19 char *line; 19 char *line;
20 20
21 while ((line = xmalloc_getline(src_stream)) != NULL) { 21 while ((line = xmalloc_getline(src_stream)) != NULL) {
22 int length; 22 int encoded_len, str_len;
23 char *line_ptr = line; 23 char *line_ptr, *dst;
24 24
25 if (strcmp(line, "end") == 0) { 25 if (strcmp(line, "end") == 0) {
26 return; 26 return; /* the only non-error exit */
27 } 27 }
28 length = ((*line_ptr - 0x20) & 0x3f)* 4 / 3;
29 28
30 if (length <= 0) { 29 line_ptr = line;
30 while (*line_ptr) {
31 *line_ptr = (*line_ptr - 0x20) & 0x3f;
32 line_ptr++;
33 }
34 str_len = line_ptr - line;
35
36 encoded_len = line[0] * 4 / 3;
37 /* Check that line is not too short. (we tolerate
38 * overly _long_ line to accomodate possible extra '`').
39 * Empty line case is also caught here. */
40 if (str_len <= encoded_len) {
41 break; /* go to bb_error_msg_and_die("short file"); */
42 }
43 if (encoded_len <= 0) {
31 /* Ignore the "`\n" line, why is it even in the encode file ? */ 44 /* Ignore the "`\n" line, why is it even in the encode file ? */
45 free(line);
32 continue; 46 continue;
33 } 47 }
34 if (length > 60) { 48 if (encoded_len > 60) {
35 bb_error_msg_and_die("line too long"); 49 bb_error_msg_and_die("line too long");
36 } 50 }
37 51
38 line_ptr++; 52 dst = line;
39 /* Tolerate an overly long line to accomodate a possible exta '`' */ 53 line_ptr = line + 1;
40 if (strlen(line_ptr) < (size_t)length) { 54 do {
41 bb_error_msg_and_die("short file");
42 }
43
44 while (length > 0) {
45 /* Merge four 6 bit chars to three 8 bit chars */ 55 /* Merge four 6 bit chars to three 8 bit chars */
46 fputc(((line_ptr[0] - 0x20) & 077) << 2 | ((line_ptr[1] - 0x20) & 077) >> 4, dst_stream); 56 *dst++ = line_ptr[0] << 2 | line_ptr[1] >> 4;
47 line_ptr++; 57 encoded_len--;
48 length--; 58 if (encoded_len == 0) {
49 if (length == 0) {
50 break; 59 break;
51 } 60 }
52 61
53 fputc(((line_ptr[0] - 0x20) & 077) << 4 | ((line_ptr[1] - 0x20) & 077) >> 2, dst_stream); 62 *dst++ = line_ptr[1] << 4 | line_ptr[2] >> 2;
54 line_ptr++; 63 encoded_len--;
55 length--; 64 if (encoded_len == 0) {
56 if (length == 0) {
57 break; 65 break;
58 } 66 }
59 67
60 fputc(((line_ptr[0] - 0x20) & 077) << 6 | ((line_ptr[1] - 0x20) & 077), dst_stream); 68 *dst++ = line_ptr[2] << 6 | line_ptr[3];
61 line_ptr += 2; 69 line_ptr += 4;
62 length -= 2; 70 encoded_len -= 2;
63 } 71 } while (encoded_len > 0);
72 fwrite(line, 1, dst - line, dst_stream);
64 free(line); 73 free(line);
65 } 74 }
66 bb_error_msg_and_die("short file"); 75 bb_error_msg_and_die("short file");
@@ -129,7 +138,7 @@ static void read_base64(FILE *src_stream, FILE *dst_stream)
129int uudecode_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 138int uudecode_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
130int uudecode_main(int argc ATTRIBUTE_UNUSED, char **argv) 139int uudecode_main(int argc ATTRIBUTE_UNUSED, char **argv)
131{ 140{
132 FILE *src_stream = stdin; 141 FILE *src_stream;
133 char *outname = NULL; 142 char *outname = NULL;
134 char *line; 143 char *line;
135 144
@@ -137,8 +146,9 @@ int uudecode_main(int argc ATTRIBUTE_UNUSED, char **argv)
137 getopt32(argv, "o:", &outname); 146 getopt32(argv, "o:", &outname);
138 argv += optind; 147 argv += optind;
139 148
140 if (argv[0]) 149 if (!*argv)
141 src_stream = xfopen(argv[0], "r"); 150 *--argv = (char*)"-";
151 src_stream = xfopen_stdin(*argv);
142 152
143 /* Search for the start of the encoding */ 153 /* Search for the start of the encoding */
144 while ((line = xmalloc_getline(src_stream)) != NULL) { 154 while ((line = xmalloc_getline(src_stream)) != NULL) {
@@ -159,7 +169,7 @@ int uudecode_main(int argc ATTRIBUTE_UNUSED, char **argv)
159 } 169 }
160 170
161 /* begin line found. decode and exit */ 171 /* begin line found. decode and exit */
162 mode = strtoul(line_ptr, NULL, 8); 172 mode = bb_strtou(line_ptr, NULL, 8);
163 if (outname == NULL) { 173 if (outname == NULL) {
164 outname = strchr(line_ptr, ' '); 174 outname = strchr(line_ptr, ' ');
165 if ((outname == NULL) || (*outname == '\0')) { 175 if ((outname == NULL) || (*outname == '\0')) {
@@ -170,7 +180,7 @@ int uudecode_main(int argc ATTRIBUTE_UNUSED, char **argv)
170 dst_stream = stdout; 180 dst_stream = stdout;
171 if (NOT_LONE_DASH(outname)) { 181 if (NOT_LONE_DASH(outname)) {
172 dst_stream = xfopen(outname, "w"); 182 dst_stream = xfopen(outname, "w");
173 chmod(outname, mode & (S_IRWXU | S_IRWXG | S_IRWXO)); 183 fchmod(fileno(dst_stream), mode & (S_IRWXU | S_IRWXG | S_IRWXO));
174 } 184 }
175 free(line); 185 free(line);
176 decode_fn_ptr(src_stream, dst_stream); 186 decode_fn_ptr(src_stream, dst_stream);
diff --git a/coreutils/yes.c b/coreutils/yes.c
index 269d2a0c2..9d3f67550 100644
--- a/coreutils/yes.c
+++ b/coreutils/yes.c
@@ -21,22 +21,21 @@
21int yes_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 21int yes_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
22int yes_main(int argc, char **argv) 22int yes_main(int argc, char **argv)
23{ 23{
24 char **first_arg; 24 char **pp;
25 25
26 argv[0] = (char*)"y"; 26 argv[0] = (char*)"y";
27 if (argc != 1) { 27 if (argc != 1) {
28 ++argv; 28 ++argv;
29 } 29 }
30 30
31 first_arg = argv;
32 do { 31 do {
32 pp = argv;
33 while (1) { 33 while (1) {
34 fputs(*argv, stdout); 34 fputs(*pp, stdout);
35 if (!*++argv) 35 if (!*++pp)
36 break; 36 break;
37 putchar(' '); 37 putchar(' ');
38 } 38 }
39 argv = first_arg;
40 } while (putchar('\n') != EOF); 39 } while (putchar('\n') != EOF);
41 40
42 bb_perror_nomsg_and_die(); 41 bb_perror_nomsg_and_die();
diff --git a/e2fsprogs/lsattr.c b/e2fsprogs/lsattr.c
index c58948698..13eeb35f5 100644
--- a/e2fsprogs/lsattr.c
+++ b/e2fsprogs/lsattr.c
@@ -102,10 +102,8 @@ int lsattr_main(int argc ATTRIBUTE_UNUSED, char **argv)
102 argv += optind; 102 argv += optind;
103 103
104 if (!*argv) 104 if (!*argv)
105 lsattr_args("."); 105 *--argv = (char*)".";
106 else { 106 do lsattr_args(*argv++); while (*argv);
107 do lsattr_args(*argv++); while (*argv);
108 }
109 107
110 return EXIT_SUCCESS; 108 return EXIT_SUCCESS;
111} 109}
diff --git a/editors/cmp.c b/editors/cmp.c
index 9189b3150..b211adf9f 100644
--- a/editors/cmp.c
+++ b/editors/cmp.c
@@ -23,16 +23,6 @@
23 23
24#include "libbb.h" 24#include "libbb.h"
25 25
26static FILE *cmp_xfopen_input(const char *filename)
27{
28 FILE *fp;
29
30 fp = fopen_or_warn_stdin(filename);
31 if (fp)
32 return fp;
33 xfunc_die(); /* We already output an error message. */
34}
35
36static const char fmt_eof[] ALIGN1 = "cmp: EOF on %s\n"; 26static const char fmt_eof[] ALIGN1 = "cmp: EOF on %s\n";
37static const char fmt_differ[] ALIGN1 = "%s %s differ: char %"OFF_FMT"d, line %d\n"; 27static const char fmt_differ[] ALIGN1 = "%s %s differ: char %"OFF_FMT"d, line %d\n";
38// This fmt_l_opt uses gnu-isms. SUSv3 would be "%.0s%.0s%"OFF_FMT"d %o %o\n" 28// This fmt_l_opt uses gnu-isms. SUSv3 would be "%.0s%.0s%"OFF_FMT"d %o %o\n"
@@ -65,7 +55,7 @@ int cmp_main(int argc ATTRIBUTE_UNUSED, char **argv)
65 argv += optind; 55 argv += optind;
66 56
67 filename1 = *argv; 57 filename1 = *argv;
68 fp1 = cmp_xfopen_input(filename1); 58 fp1 = xfopen_stdin(filename1);
69 59
70 if (*++argv) { 60 if (*++argv) {
71 filename2 = *argv; 61 filename2 = *argv;
@@ -79,7 +69,7 @@ int cmp_main(int argc ATTRIBUTE_UNUSED, char **argv)
79#endif 69#endif
80 } 70 }
81 71
82 fp2 = cmp_xfopen_input(filename2); 72 fp2 = xfopen_stdin(filename2);
83 if (fp1 == fp2) { /* Paranoia check... stdin == stdin? */ 73 if (fp1 == fp2) { /* Paranoia check... stdin == stdin? */
84 /* Note that we don't bother reading stdin. Neither does gnu wc. 74 /* Note that we don't bother reading stdin. Neither does gnu wc.
85 * But perhaps we should, so that other apps down the chain don't 75 * But perhaps we should, so that other apps down the chain don't
diff --git a/editors/sed.c b/editors/sed.c
index a0994aec0..32911f8f9 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -1231,7 +1231,7 @@ static void add_cmd_block(char *cmdstr)
1231} 1231}
1232 1232
1233int sed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1233int sed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1234int sed_main(int argc, char **argv) 1234int sed_main(int argc ATTRIBUTE_UNUSED, char **argv)
1235{ 1235{
1236 enum { 1236 enum {
1237 OPT_in_place = 1 << 0, 1237 OPT_in_place = 1 << 0,
@@ -1246,7 +1246,7 @@ int sed_main(int argc, char **argv)
1246 if (ENABLE_FEATURE_CLEAN_UP) atexit(sed_free_and_close_stuff); 1246 if (ENABLE_FEATURE_CLEAN_UP) atexit(sed_free_and_close_stuff);
1247 1247
1248 /* Lie to autoconf when it starts asking stupid questions. */ 1248 /* Lie to autoconf when it starts asking stupid questions. */
1249 if (argc == 2 && !strcmp(argv[1], "--version")) { 1249 if (argv[1] && !strcmp(argv[1], "--version")) {
1250 puts("This is not GNU sed version 4.0"); 1250 puts("This is not GNU sed version 4.0");
1251 return 0; 1251 return 0;
1252 } 1252 }
@@ -1257,7 +1257,7 @@ int sed_main(int argc, char **argv)
1257 "nn"; /* count -n */ 1257 "nn"; /* count -n */
1258 opt = getopt32(argv, "irne:f:", &opt_e, &opt_f, 1258 opt = getopt32(argv, "irne:f:", &opt_e, &opt_f,
1259 &G.be_quiet); /* counter for -n */ 1259 &G.be_quiet); /* counter for -n */
1260 argc -= optind; 1260 //argc -= optind;
1261 argv += optind; 1261 argv += optind;
1262 if (opt & OPT_in_place) { // -i 1262 if (opt & OPT_in_place) { // -i
1263 atexit(cleanup_outname); 1263 atexit(cleanup_outname);
@@ -1283,10 +1283,9 @@ int sed_main(int argc, char **argv)
1283 } 1283 }
1284 /* if we didn't get a pattern from -e or -f, use argv[0] */ 1284 /* if we didn't get a pattern from -e or -f, use argv[0] */
1285 if (!(opt & 0x18)) { 1285 if (!(opt & 0x18)) {
1286 if (!argc) 1286 if (!*argv)
1287 bb_show_usage(); 1287 bb_show_usage();
1288 add_cmd_block(*argv++); 1288 add_cmd_block(*argv++);
1289 argc--;
1290 } 1289 }
1291 /* Flush any unfinished commands. */ 1290 /* Flush any unfinished commands. */
1292 add_cmd(""); 1291 add_cmd("");
@@ -1306,7 +1305,7 @@ int sed_main(int argc, char **argv)
1306 int i; 1305 int i;
1307 FILE *file; 1306 FILE *file;
1308 1307
1309 for (i = 0; i < argc; i++) { 1308 for (i = 0; argv[i]; i++) {
1310 struct stat statbuf; 1309 struct stat statbuf;
1311 int nonstdoutfd; 1310 int nonstdoutfd;
1312 1311
diff --git a/include/libbb.h b/include/libbb.h
index c6c2be244..99d681dbe 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -333,6 +333,7 @@ int xopen(const char *pathname, int flags);
333int xopen3(const char *pathname, int flags, int mode); 333int xopen3(const char *pathname, int flags, int mode);
334int open_or_warn(const char *pathname, int flags); 334int open_or_warn(const char *pathname, int flags);
335int open3_or_warn(const char *pathname, int flags, int mode); 335int open3_or_warn(const char *pathname, int flags, int mode);
336int open_or_warn_stdin(const char *pathname);
336void xrename(const char *oldpath, const char *newpath); 337void xrename(const char *oldpath, const char *newpath);
337int rename_or_warn(const char *oldpath, const char *newpath); 338int rename_or_warn(const char *oldpath, const char *newpath);
338off_t xlseek(int fd, off_t offset, int whence); 339off_t xlseek(int fd, off_t offset, int whence);
@@ -559,6 +560,7 @@ extern FILE *xfopen(const char *filename, const char *mode);
559/* Prints warning to stderr and returns NULL on failure: */ 560/* Prints warning to stderr and returns NULL on failure: */
560extern FILE *fopen_or_warn(const char *filename, const char *mode); 561extern FILE *fopen_or_warn(const char *filename, const char *mode);
561/* "Opens" stdin if filename is special, else just opens file: */ 562/* "Opens" stdin if filename is special, else just opens file: */
563extern FILE *xfopen_stdin(const char *filename);
562extern FILE *fopen_or_warn_stdin(const char *filename); 564extern FILE *fopen_or_warn_stdin(const char *filename);
563 565
564int bb_pstrcmp(const void *a, const void *b); 566int bb_pstrcmp(const void *a, const void *b);
@@ -741,6 +743,7 @@ void bb_sanitize_stdio(void);
741int sanitize_env_if_suid(void); 743int sanitize_env_if_suid(void);
742 744
743 745
746extern const char *const bb_argv_dash[]; /* "-", NULL */
744extern const char *opt_complementary; 747extern const char *opt_complementary;
745#if ENABLE_GETOPT_LONG 748#if ENABLE_GETOPT_LONG
746#define No_argument "\0" 749#define No_argument "\0"
diff --git a/libbb/fclose_nonstdin.c b/libbb/fclose_nonstdin.c
index 88e8474f2..768ee946d 100644
--- a/libbb/fclose_nonstdin.c
+++ b/libbb/fclose_nonstdin.c
@@ -16,8 +16,10 @@
16 16
17int fclose_if_not_stdin(FILE *f) 17int fclose_if_not_stdin(FILE *f)
18{ 18{
19 if (f != stdin) { 19 /* Some more paranoid applets want ferror() check too */
20 return fclose(f); 20 int r = ferror(f); /* NB: does NOT set errno! */
21 } 21 if (r) errno = EIO; /* so we'll help it */
22 return 0; 22 if (f != stdin)
23 return (r | fclose(f)); /* fclose does set errno on error */
24 return r;
23} 25}
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index f48ccaa6a..9e53dfd08 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -281,6 +281,8 @@ Special characters:
281 281
282/* Code here assumes that 'unsigned' is at least 32 bits wide */ 282/* Code here assumes that 'unsigned' is at least 32 bits wide */
283 283
284const char *const bb_argv_dash[] = { "-", NULL };
285
284const char *opt_complementary; 286const char *opt_complementary;
285 287
286enum { 288enum {
diff --git a/libbb/wfopen_input.c b/libbb/wfopen_input.c
index 1b4928e1f..a7c1c32f5 100644
--- a/libbb/wfopen_input.c
+++ b/libbb/wfopen_input.c
@@ -10,8 +10,6 @@
10/* A number of applets need to open a file for reading, where the filename 10/* A number of applets need to open a file for reading, where the filename
11 * is a command line arg. Since often that arg is '-' (meaning stdin), 11 * is a command line arg. Since often that arg is '-' (meaning stdin),
12 * we avoid testing everywhere by consolidating things in this routine. 12 * we avoid testing everywhere by consolidating things in this routine.
13 *
14 * Note: we also consider "" to mean stdin (for 'cmp' at least).
15 */ 13 */
16 14
17#include "libbb.h" 15#include "libbb.h"
@@ -21,11 +19,30 @@ FILE *fopen_or_warn_stdin(const char *filename)
21 FILE *fp = stdin; 19 FILE *fp = stdin;
22 20
23 if (filename != bb_msg_standard_input 21 if (filename != bb_msg_standard_input
24 && filename[0]
25 && NOT_LONE_DASH(filename) 22 && NOT_LONE_DASH(filename)
26 ) { 23 ) {
27 fp = fopen_or_warn(filename, "r"); 24 fp = fopen_or_warn(filename, "r");
28 } 25 }
29
30 return fp; 26 return fp;
31} 27}
28
29FILE *xfopen_stdin(const char *filename)
30{
31 FILE *fp = fopen_or_warn_stdin(filename);
32 if (fp)
33 return fp;
34 xfunc_die(); /* We already output an error message. */
35}
36
37int open_or_warn_stdin(const char *filename)
38{
39 int fd = STDIN_FILENO;
40
41 if (filename != bb_msg_standard_input
42 && NOT_LONE_DASH(filename)
43 ) {
44 fd = open_or_warn(filename, O_RDONLY);
45 }
46
47 return fd;
48}
diff --git a/loginutils/su.c b/loginutils/su.c
index afb9843f8..1a35f0e4f 100644
--- a/loginutils/su.c
+++ b/loginutils/su.c
@@ -12,7 +12,7 @@
12#define SU_OPT_l (4) 12#define SU_OPT_l (4)
13 13
14int su_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 14int su_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
15int su_main(int argc, char **argv) 15int su_main(int argc ATTRIBUTE_UNUSED, char **argv)
16{ 16{
17 unsigned flags; 17 unsigned flags;
18 char *opt_shell = NULL; 18 char *opt_shell = NULL;
@@ -24,19 +24,17 @@ int su_main(int argc, char **argv)
24 char *old_user; 24 char *old_user;
25 25
26 flags = getopt32(argv, "mplc:s:", &opt_command, &opt_shell); 26 flags = getopt32(argv, "mplc:s:", &opt_command, &opt_shell);
27 argc -= optind; 27 //argc -= optind;
28 argv += optind; 28 argv += optind;
29 29
30 if (argc && LONE_DASH(argv[0])) { 30 if (argv[0] && LONE_DASH(argv[0])) {
31 flags |= SU_OPT_l; 31 flags |= SU_OPT_l;
32 argc--;
33 argv++; 32 argv++;
34 } 33 }
35 34
36 /* get user if specified */ 35 /* get user if specified */
37 if (argc) { 36 if (argv[0]) {
38 opt_username = argv[0]; 37 opt_username = argv[0];
39 //argc--; - not used below anyway
40 argv++; 38 argv++;
41 } 39 }
42 40
diff --git a/miscutils/strings.c b/miscutils/strings.c
index 57a2c0a17..5efbabf6f 100644
--- a/miscutils/strings.c
+++ b/miscutils/strings.c
@@ -23,7 +23,7 @@ int strings_main(int argc ATTRIBUTE_UNUSED, char **argv)
23 unsigned opt; 23 unsigned opt;
24 unsigned count; 24 unsigned count;
25 off_t offset; 25 off_t offset;
26 FILE *file = stdin; 26 FILE *file;
27 char *string; 27 char *string;
28 const char *fmt = "%s: "; 28 const char *fmt = "%s: ";
29 const char *n_arg = "4"; 29 const char *n_arg = "4";
@@ -40,16 +40,14 @@ int strings_main(int argc ATTRIBUTE_UNUSED, char **argv)
40 if (!*argv) { 40 if (!*argv) {
41 fmt = "{%s}: "; 41 fmt = "{%s}: ";
42 *--argv = (char *)bb_msg_standard_input; 42 *--argv = (char *)bb_msg_standard_input;
43 goto PIPE;
44 } 43 }
45 44
46 do { 45 do {
47 file = fopen_or_warn(*argv, "r"); 46 file = fopen_or_warn_stdin(*argv);
48 if (!file) { 47 if (!file) {
49 status = EXIT_FAILURE; 48 status = EXIT_FAILURE;
50 continue; 49 continue;
51 } 50 }
52 PIPE:
53 offset = 0; 51 offset = 0;
54 count = 0; 52 count = 0;
55 do { 53 do {
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index 5bf1a491c..ca0c6cb20 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -377,7 +377,7 @@ void write_leases(void)
377 time_t curr = time(0); 377 time_t curr = time(0);
378 unsigned long tmp_time; 378 unsigned long tmp_time;
379 379
380 fp = open3_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC, 0666); 380 fp = open_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC);
381 if (fp < 0) { 381 if (fp < 0) {
382 return; 382 return;
383 } 383 }
diff --git a/shell/lash_unused.c b/shell/lash_unused.c
index 10a9120e2..d57f584b2 100644
--- a/shell/lash_unused.c
+++ b/shell/lash_unused.c
@@ -566,7 +566,7 @@ static int setup_redirects(struct child_prog *prog, int squirrel[])
566 break; 566 break;
567 } 567 }
568 568
569 openfd = open3_or_warn(redir->filename, mode, 0666); 569 openfd = open_or_warn(redir->filename, mode);
570 if (openfd < 0) { 570 if (openfd < 0) {
571 /* this could get lost if stderr has been redirected, but 571 /* this could get lost if stderr has been redirected, but
572 bash and ash both lose it as well (though zsh doesn't!) */ 572 bash and ash both lose it as well (though zsh doesn't!) */
diff --git a/util-linux/hexdump.c b/util-linux/hexdump.c
index 670867054..cdb17ca3b 100644
--- a/util-linux/hexdump.c
+++ b/util-linux/hexdump.c
@@ -73,7 +73,7 @@ int hexdump_main(int argc, char **argv)
73 } 73 }
74 74
75 /* We cannot use getopt32: in hexdump options are cumulative. 75 /* We cannot use getopt32: in hexdump options are cumulative.
76 * E.g. hexdump -C -C file should dump each line twice */ 76 * E.g. "hexdump -C -C file" should dump each line twice */
77 while ((ch = getopt(argc, argv, hexdump_opts)) > 0) { 77 while ((ch = getopt(argc, argv, hexdump_opts)) > 0) {
78 p = strchr(hexdump_opts, ch); 78 p = strchr(hexdump_opts, ch);
79 if (!p) 79 if (!p)