aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-03-22 16:14:13 +0000
committerRon Yorston <rmy@pobox.com>2012-03-22 16:14:13 +0000
commit800c3f176fb21e30fbaa81ef68f50e601ea2f78b (patch)
tree84f4a2bf30d3208a020b25c82c11ac636c7072c6
parent9db164d6e39050d09f38288c6045cd2a2cbf6d63 (diff)
parentf99811908419608e3ab81393d0177cc456101e4b (diff)
downloadbusybox-w32-800c3f176fb21e30fbaa81ef68f50e601ea2f78b.tar.gz
busybox-w32-800c3f176fb21e30fbaa81ef68f50e601ea2f78b.tar.bz2
busybox-w32-800c3f176fb21e30fbaa81ef68f50e601ea2f78b.zip
Merge commit '1_19_4' into merge_1_19
-rw-r--r--Makefile2
-rw-r--r--applets/applet_tables.c9
-rw-r--r--archival/libarchive/decompress_uncompress.c13
-rw-r--r--coreutils/tail.c6
-rw-r--r--editors/patch.c8
-rw-r--r--editors/sed.c79
-rw-r--r--findutils/find.c5
-rw-r--r--findutils/grep.c22
-rw-r--r--include/platform.h4
-rw-r--r--libbb/getpty.c18
-rw-r--r--libbb/lineedit.c2
-rw-r--r--libbb/match_fstype.c4
-rw-r--r--libbb/procps.c34
-rw-r--r--libbb/udp_io.c2
-rw-r--r--loginutils/chpasswd.c17
-rw-r--r--loginutils/getty.c2
-rw-r--r--miscutils/crond.c3
-rw-r--r--miscutils/less.c7
-rw-r--r--modutils/modinfo.c1
-rw-r--r--networking/inetd.c14
-rw-r--r--networking/tftp.c3
-rw-r--r--networking/wget.c6
-rw-r--r--shell/cttyhack.c8
-rw-r--r--shell/hush.c18
-rw-r--r--sysklogd/syslogd.c12
-rwxr-xr-xtestsuite/sed.tests10
-rwxr-xr-xtestsuite/tail.tests8
-rw-r--r--util-linux/mdev.c2
-rw-r--r--util-linux/swaponoff.c3
29 files changed, 209 insertions, 113 deletions
diff --git a/Makefile b/Makefile
index 7d2db1871..a18cd356d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
1VERSION = 1 1VERSION = 1
2PATCHLEVEL = 19 2PATCHLEVEL = 19
3SUBLEVEL = 0 3SUBLEVEL = 4
4EXTRAVERSION = 4EXTRAVERSION =
5NAME = Unnamed 5NAME = Unnamed
6 6
diff --git a/applets/applet_tables.c b/applets/applet_tables.c
index 3859d7326..a47574737 100644
--- a/applets/applet_tables.c
+++ b/applets/applet_tables.c
@@ -80,8 +80,15 @@ int main(int argc, char **argv)
80 80
81 printf("#define NUM_APPLETS %u\n", NUM_APPLETS); 81 printf("#define NUM_APPLETS %u\n", NUM_APPLETS);
82 if (NUM_APPLETS == 1) { 82 if (NUM_APPLETS == 1) {
83 char *dash_to_underscore, *p;
83 printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); 84 printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name);
84 printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].name); 85 /* Example: "ether-wake" -> "ether_wake" */
86 p = dash_to_underscore = strdup(applets[0].name);
87 p--;
88 while (*++p)
89 if (*p == '-')
90 *p = '_';
91 printf("#define SINGLE_APPLET_MAIN %s_main\n", dash_to_underscore);
85 } 92 }
86 printf("\n"); 93 printf("\n");
87 94
diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c
index 44d894244..d1061a2bb 100644
--- a/archival/libarchive/decompress_uncompress.c
+++ b/archival/libarchive/decompress_uncompress.c
@@ -163,7 +163,8 @@ unpack_Z_stream(int fd_in, int fd_out)
163 163
164 if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { 164 if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
165 rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); 165 rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ);
166//error check?? 166 if (rsize < 0)
167 bb_error_msg_and_die(bb_msg_read_error);
167 insize += rsize; 168 insize += rsize;
168 } 169 }
169 170
@@ -195,6 +196,8 @@ unpack_Z_stream(int fd_in, int fd_out)
195 196
196 197
197 if (oldcode == -1) { 198 if (oldcode == -1) {
199 if (code >= 256)
200 bb_error_msg_and_die("corrupted data"); /* %ld", code); */
198 oldcode = code; 201 oldcode = code;
199 finchar = (int) oldcode; 202 finchar = (int) oldcode;
200 outbuf[outpos++] = (unsigned char) finchar; 203 outbuf[outpos++] = (unsigned char) finchar;
@@ -239,6 +242,8 @@ unpack_Z_stream(int fd_in, int fd_out)
239 242
240 /* Generate output characters in reverse order */ 243 /* Generate output characters in reverse order */
241 while ((long) code >= (long) 256) { 244 while ((long) code >= (long) 256) {
245 if (stackp <= &htabof(0))
246 bb_error_msg_and_die("corrupted data");
242 *--stackp = tab_suffixof(code); 247 *--stackp = tab_suffixof(code);
243 code = tab_prefixof(code); 248 code = tab_prefixof(code);
244 } 249 }
@@ -263,8 +268,7 @@ unpack_Z_stream(int fd_in, int fd_out)
263 } 268 }
264 269
265 if (outpos >= OBUFSIZ) { 270 if (outpos >= OBUFSIZ) {
266 full_write(fd_out, outbuf, outpos); 271 xwrite(fd_out, outbuf, outpos);
267//error check??
268 IF_DESKTOP(total_written += outpos;) 272 IF_DESKTOP(total_written += outpos;)
269 outpos = 0; 273 outpos = 0;
270 } 274 }
@@ -292,8 +296,7 @@ unpack_Z_stream(int fd_in, int fd_out)
292 } while (rsize > 0); 296 } while (rsize > 0);
293 297
294 if (outpos > 0) { 298 if (outpos > 0) {
295 full_write(fd_out, outbuf, outpos); 299 xwrite(fd_out, outbuf, outpos);
296//error check??
297 IF_DESKTOP(total_written += outpos;) 300 IF_DESKTOP(total_written += outpos;)
298 } 301 }
299 302
diff --git a/coreutils/tail.c b/coreutils/tail.c
index 454c25936..43cecbd97 100644
--- a/coreutils/tail.c
+++ b/coreutils/tail.c
@@ -203,7 +203,7 @@ int tail_main(int argc, char **argv)
203 int fd = fds[i]; 203 int fd = fds[i];
204 204
205 if (ENABLE_FEATURE_FANCY_TAIL && fd < 0) 205 if (ENABLE_FEATURE_FANCY_TAIL && fd < 0)
206 continue; /* may happen with -E */ 206 continue; /* may happen with -F */
207 207
208 if (nfiles > header_threshhold) { 208 if (nfiles > header_threshhold) {
209 tail_xprint_header(fmt, argv[i]); 209 tail_xprint_header(fmt, argv[i]);
@@ -252,14 +252,14 @@ int tail_main(int argc, char **argv)
252 * Used only by +N code ("start from Nth", 1-based): */ 252 * Used only by +N code ("start from Nth", 1-based): */
253 seen = 1; 253 seen = 1;
254 newlines_seen = 0; 254 newlines_seen = 0;
255 while ((nread = tail_read(fd, buf, tailbufsize-taillen)) > 0) { 255 while ((nread = tail_read(fd, buf, tailbufsize - taillen)) > 0) {
256 if (G.from_top) { 256 if (G.from_top) {
257 int nwrite = nread; 257 int nwrite = nread;
258 if (seen < count) { 258 if (seen < count) {
259 /* We need to skip a few more bytes/lines */ 259 /* We need to skip a few more bytes/lines */
260 if (COUNT_BYTES) { 260 if (COUNT_BYTES) {
261 nwrite -= (count - seen); 261 nwrite -= (count - seen);
262 seen = count; 262 seen += nread;
263 } else { 263 } else {
264 char *s = buf; 264 char *s = buf;
265 do { 265 do {
diff --git a/editors/patch.c b/editors/patch.c
index ec5b8e7ad..1f2a49b66 100644
--- a/editors/patch.c
+++ b/editors/patch.c
@@ -70,8 +70,7 @@ struct double_list {
70 70
71// Free all the elements of a linked list 71// Free all the elements of a linked list
72// Call freeit() on each element before freeing it. 72// Call freeit() on each element before freeing it.
73static 73static void dlist_free(struct double_list *list, void (*freeit)(void *data))
74void dlist_free(struct double_list *list, void (*freeit)(void *data))
75{ 74{
76 while (list) { 75 while (list) {
77 void *pop = list; 76 void *pop = list;
@@ -83,8 +82,7 @@ void dlist_free(struct double_list *list, void (*freeit)(void *data))
83} 82}
84 83
85// Add an entry before "list" element in (circular) doubly linked list 84// Add an entry before "list" element in (circular) doubly linked list
86static 85static struct double_list *dlist_add(struct double_list **list, char *data)
87struct double_list *dlist_add(struct double_list **list, char *data)
88{ 86{
89 struct double_list *llist; 87 struct double_list *llist;
90 struct double_list *line = xmalloc(sizeof(*line)); 88 struct double_list *line = xmalloc(sizeof(*line));
@@ -232,7 +230,7 @@ static int apply_one_hunk(void)
232 else matcheof = 0; 230 else matcheof = 0;
233 if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); 231 if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data);
234 } 232 }
235 matcheof = matcheof < TT.context; 233 matcheof = !matcheof || matcheof < TT.context;
236 234
237 if (PATCH_DEBUG) fdprintf(2,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N'); 235 if (PATCH_DEBUG) fdprintf(2,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N');
238 236
diff --git a/editors/sed.c b/editors/sed.c
index 5c4e9cc3b..1552cf370 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -75,6 +75,13 @@
75#include "libbb.h" 75#include "libbb.h"
76#include "xregex.h" 76#include "xregex.h"
77 77
78#if 0
79# define dbg(...) bb_error_msg(__VA_ARGS__)
80#else
81# define dbg(...) ((void)0)
82#endif
83
84
78enum { 85enum {
79 OPT_in_place = 1 << 0, 86 OPT_in_place = 1 << 0,
80}; 87};
@@ -89,6 +96,7 @@ typedef struct sed_cmd_s {
89 regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */ 96 regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */
90 regex_t *sub_match; /* For 's/sub_match/string/' */ 97 regex_t *sub_match; /* For 's/sub_match/string/' */
91 int beg_line; /* 'sed 1p' 0 == apply commands to all lines */ 98 int beg_line; /* 'sed 1p' 0 == apply commands to all lines */
99 int beg_line_orig; /* copy of the above, needed for -i */
92 int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($) */ 100 int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($) */
93 101
94 FILE *sw_file; /* File (sw) command writes to, -1 for none. */ 102 FILE *sw_file; /* File (sw) command writes to, -1 for none. */
@@ -123,7 +131,7 @@ struct globals {
123 regex_t *previous_regex_ptr; 131 regex_t *previous_regex_ptr;
124 132
125 /* linked list of sed commands */ 133 /* linked list of sed commands */
126 sed_cmd_t sed_cmd_head, *sed_cmd_tail; 134 sed_cmd_t *sed_cmd_head, **sed_cmd_tail;
127 135
128 /* Linked list of append lines */ 136 /* Linked list of append lines */
129 llist_t *append_head; 137 llist_t *append_head;
@@ -148,7 +156,7 @@ struct BUG_G_too_big {
148#if ENABLE_FEATURE_CLEAN_UP 156#if ENABLE_FEATURE_CLEAN_UP
149static void sed_free_and_close_stuff(void) 157static void sed_free_and_close_stuff(void)
150{ 158{
151 sed_cmd_t *sed_cmd = G.sed_cmd_head.next; 159 sed_cmd_t *sed_cmd = G.sed_cmd_head;
152 160
153 llist_free(G.append_head, free); 161 llist_free(G.append_head, free);
154 162
@@ -599,6 +607,7 @@ static void add_cmd(const char *cmdstr)
599 607
600 /* first part (if present) is an address: either a '$', a number or a /regex/ */ 608 /* first part (if present) is an address: either a '$', a number or a /regex/ */
601 cmdstr += get_address(cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match); 609 cmdstr += get_address(cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match);
610 sed_cmd->beg_line_orig = sed_cmd->beg_line;
602 611
603 /* second part (if present) will begin with a comma */ 612 /* second part (if present) will begin with a comma */
604 if (*cmdstr == ',') { 613 if (*cmdstr == ',') {
@@ -630,8 +639,8 @@ static void add_cmd(const char *cmdstr)
630 cmdstr = parse_cmd_args(sed_cmd, cmdstr); 639 cmdstr = parse_cmd_args(sed_cmd, cmdstr);
631 640
632 /* Add the command to the command array */ 641 /* Add the command to the command array */
633 G.sed_cmd_tail->next = sed_cmd; 642 *G.sed_cmd_tail = sed_cmd;
634 G.sed_cmd_tail = G.sed_cmd_tail->next; 643 G.sed_cmd_tail = &sed_cmd->next;
635 } 644 }
636 645
637 /* If we glued multiple lines together, free the memory. */ 646 /* If we glued multiple lines together, free the memory. */
@@ -777,7 +786,7 @@ static sed_cmd_t *branch_to(char *label)
777{ 786{
778 sed_cmd_t *sed_cmd; 787 sed_cmd_t *sed_cmd;
779 788
780 for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { 789 for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) {
781 if (sed_cmd->cmd == ':' && sed_cmd->string && !strcmp(sed_cmd->string, label)) { 790 if (sed_cmd->cmd == ':' && sed_cmd->string && !strcmp(sed_cmd->string, label)) {
782 return sed_cmd; 791 return sed_cmd;
783 } 792 }
@@ -953,24 +962,24 @@ static void process_files(void)
953 962
954 /* For every line, go through all the commands */ 963 /* For every line, go through all the commands */
955 restart: 964 restart:
956 for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { 965 for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) {
957 int old_matched, matched; 966 int old_matched, matched;
958 967
959 old_matched = sed_cmd->in_match; 968 old_matched = sed_cmd->in_match;
960 969
961 /* Determine if this command matches this line: */ 970 /* Determine if this command matches this line: */
962 971
963 //bb_error_msg("match1:%d", sed_cmd->in_match); 972 dbg("match1:%d", sed_cmd->in_match);
964 //bb_error_msg("match2:%d", (!sed_cmd->beg_line && !sed_cmd->end_line 973 dbg("match2:%d", (!sed_cmd->beg_line && !sed_cmd->end_line
965 // && !sed_cmd->beg_match && !sed_cmd->end_match)); 974 && !sed_cmd->beg_match && !sed_cmd->end_match));
966 //bb_error_msg("match3:%d", (sed_cmd->beg_line > 0 975 dbg("match3:%d", (sed_cmd->beg_line > 0
967 // && (sed_cmd->end_line || sed_cmd->end_match 976 && (sed_cmd->end_line || sed_cmd->end_match
968 // ? (sed_cmd->beg_line <= linenum) 977 ? (sed_cmd->beg_line <= linenum)
969 // : (sed_cmd->beg_line == linenum) 978 : (sed_cmd->beg_line == linenum)
970 // ) 979 )
971 // ) 980 ));
972 //bb_error_msg("match4:%d", (beg_match(sed_cmd, pattern_space))); 981 dbg("match4:%d", (beg_match(sed_cmd, pattern_space)));
973 //bb_error_msg("match5:%d", (sed_cmd->beg_line == -1 && next_line == NULL)); 982 dbg("match5:%d", (sed_cmd->beg_line == -1 && next_line == NULL));
974 983
975 /* Are we continuing a previous multi-line match? */ 984 /* Are we continuing a previous multi-line match? */
976 sed_cmd->in_match = sed_cmd->in_match 985 sed_cmd->in_match = sed_cmd->in_match
@@ -981,7 +990,14 @@ static void process_files(void)
981 || (sed_cmd->beg_line > 0 990 || (sed_cmd->beg_line > 0
982 && (sed_cmd->end_line || sed_cmd->end_match 991 && (sed_cmd->end_line || sed_cmd->end_match
983 /* note: even if end is numeric and is < linenum too, 992 /* note: even if end is numeric and is < linenum too,
984 * GNU sed matches! We match too */ 993 * GNU sed matches! We match too, therefore we don't
994 * check here that linenum <= end.
995 * Example:
996 * printf '1\n2\n3\n4\n' | sed -n '1{N;N;d};1p;2,3p;3p;4p'
997 * first three input lines are deleted;
998 * 4th line is matched and printed
999 * by "2,3" (!) and by "4" ranges
1000 */
985 ? (sed_cmd->beg_line <= linenum) /* N,end */ 1001 ? (sed_cmd->beg_line <= linenum) /* N,end */
986 : (sed_cmd->beg_line == linenum) /* N */ 1002 : (sed_cmd->beg_line == linenum) /* N */
987 ) 1003 )
@@ -994,16 +1010,14 @@ static void process_files(void)
994 /* Snapshot the value */ 1010 /* Snapshot the value */
995 matched = sed_cmd->in_match; 1011 matched = sed_cmd->in_match;
996 1012
997 //bb_error_msg("cmd:'%c' matched:%d beg_line:%d end_line:%d linenum:%d", 1013 dbg("cmd:'%c' matched:%d beg_line:%d end_line:%d linenum:%d",
998 //sed_cmd->cmd, matched, sed_cmd->beg_line, sed_cmd->end_line, linenum); 1014 sed_cmd->cmd, matched, sed_cmd->beg_line, sed_cmd->end_line, linenum);
999 1015
1000 /* Is this line the end of the current match? */ 1016 /* Is this line the end of the current match? */
1001 1017
1002 if (matched) { 1018 if (matched) {
1003 /* once matched, "n,xxx" range is dead, disabling it */ 1019 /* once matched, "n,xxx" range is dead, disabling it */
1004 if (sed_cmd->beg_line > 0 1020 if (sed_cmd->beg_line > 0) {
1005 && !(option_mask32 & OPT_in_place) /* but not for -i */
1006 ) {
1007 sed_cmd->beg_line = -2; 1021 sed_cmd->beg_line = -2;
1008 } 1022 }
1009 sed_cmd->in_match = !( 1023 sed_cmd->in_match = !(
@@ -1017,7 +1031,8 @@ static void process_files(void)
1017 /* or does this line matches our last address regex */ 1031 /* or does this line matches our last address regex */
1018 || (sed_cmd->end_match && old_matched 1032 || (sed_cmd->end_match && old_matched
1019 && (regexec(sed_cmd->end_match, 1033 && (regexec(sed_cmd->end_match,
1020 pattern_space, 0, NULL, 0) == 0)) 1034 pattern_space, 0, NULL, 0) == 0)
1035 )
1021 ); 1036 );
1022 } 1037 }
1023 1038
@@ -1407,11 +1422,12 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
1407 add_input_file(stdin); 1422 add_input_file(stdin);
1408 } else { 1423 } else {
1409 int i; 1424 int i;
1410 FILE *file;
1411 1425
1412 for (i = 0; argv[i]; i++) { 1426 for (i = 0; argv[i]; i++) {
1413 struct stat statbuf; 1427 struct stat statbuf;
1414 int nonstdoutfd; 1428 int nonstdoutfd;
1429 FILE *file;
1430 sed_cmd_t *sed_cmd;
1415 1431
1416 if (LONE_DASH(argv[i]) && !(opt & OPT_in_place)) { 1432 if (LONE_DASH(argv[i]) && !(opt & OPT_in_place)) {
1417 add_input_file(stdin); 1433 add_input_file(stdin);
@@ -1423,11 +1439,13 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
1423 status = EXIT_FAILURE; 1439 status = EXIT_FAILURE;
1424 continue; 1440 continue;
1425 } 1441 }
1442 add_input_file(file);
1426 if (!(opt & OPT_in_place)) { 1443 if (!(opt & OPT_in_place)) {
1427 add_input_file(file);
1428 continue; 1444 continue;
1429 } 1445 }
1430 1446
1447 /* -i: process each FILE separately: */
1448
1431 G.outname = xasprintf("%sXXXXXX", argv[i]); 1449 G.outname = xasprintf("%sXXXXXX", argv[i]);
1432 nonstdoutfd = xmkstemp(G.outname); 1450 nonstdoutfd = xmkstemp(G.outname);
1433 G.nonstdout = xfdopen_for_write(nonstdoutfd); 1451 G.nonstdout = xfdopen_for_write(nonstdoutfd);
@@ -1438,15 +1456,20 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
1438 * but GNU sed 4.2.1 does not preserve them either */ 1456 * but GNU sed 4.2.1 does not preserve them either */
1439 fchmod(nonstdoutfd, statbuf.st_mode); 1457 fchmod(nonstdoutfd, statbuf.st_mode);
1440 fchown(nonstdoutfd, statbuf.st_uid, statbuf.st_gid); 1458 fchown(nonstdoutfd, statbuf.st_uid, statbuf.st_gid);
1441 add_input_file(file); 1459
1442 process_files(); 1460 process_files();
1443 fclose(G.nonstdout); 1461 fclose(G.nonstdout);
1444
1445 G.nonstdout = stdout; 1462 G.nonstdout = stdout;
1463
1446 /* unlink(argv[i]); */ 1464 /* unlink(argv[i]); */
1447 xrename(G.outname, argv[i]); 1465 xrename(G.outname, argv[i]);
1448 free(G.outname); 1466 free(G.outname);
1449 G.outname = NULL; 1467 G.outname = NULL;
1468
1469 /* Re-enable disabled range matches */
1470 for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) {
1471 sed_cmd->beg_line = sed_cmd->beg_line_orig;
1472 }
1450 } 1473 }
1451 /* Here, to handle "sed 'cmds' nonexistent_file" case we did: 1474 /* Here, to handle "sed 'cmds' nonexistent_file" case we did:
1452 * if (G.current_input_file >= G.input_file_count) 1475 * if (G.current_input_file >= G.input_file_count)
diff --git a/findutils/find.c b/findutils/find.c
index 05f88d2f0..fc0fc5c9f 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -932,7 +932,10 @@ static action*** parse_params(char **argv)
932 * expression is reached. 932 * expression is reached.
933 */ 933 */
934 /* Options */ 934 /* Options */
935 if (0) { } 935 if (parm == OPT_FOLLOW) {
936 dbg("follow enabled: %d", __LINE__);
937 G.recurse_flags |= ACTION_FOLLOWLINKS | ACTION_DANGLING_OK;
938 }
936#if ENABLE_FEATURE_FIND_XDEV 939#if ENABLE_FEATURE_FIND_XDEV
937 else if (parm == OPT_XDEV) { 940 else if (parm == OPT_XDEV) {
938 dbg("%d", __LINE__); 941 dbg("%d", __LINE__);
diff --git a/findutils/grep.c b/findutils/grep.c
index fa3b8a3a9..f3463f94e 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -570,20 +570,20 @@ static char *add_grep_list_data(char *pattern)
570 570
571static void load_regexes_from_file(llist_t *fopt) 571static void load_regexes_from_file(llist_t *fopt)
572{ 572{
573 char *line;
574 FILE *f;
575
576 while (fopt) { 573 while (fopt) {
574 char *line;
575 FILE *fp;
577 llist_t *cur = fopt; 576 llist_t *cur = fopt;
578 char *ffile = cur->data; 577 char *ffile = cur->data;
579 578
580 fopt = cur->link; 579 fopt = cur->link;
581 free(cur); 580 free(cur);
582 f = xfopen_stdin(ffile); 581 fp = xfopen_stdin(ffile);
583 while ((line = xmalloc_fgetline(f)) != NULL) { 582 while ((line = xmalloc_fgetline(fp)) != NULL) {
584 llist_add_to(&pattern_head, 583 llist_add_to(&pattern_head,
585 new_grep_list_data(line, ALLOCATED)); 584 new_grep_list_data(line, ALLOCATED));
586 } 585 }
586 fclose_if_not_stdin(fp);
587 } 587 }
588} 588}
589 589
@@ -667,15 +667,19 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
667#endif 667#endif
668 invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */ 668 invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */
669 669
670 if (pattern_head != NULL) { 670 { /* convert char **argv to grep_list_data_t */
671 /* convert char **argv to grep_list_data_t */
672 llist_t *cur; 671 llist_t *cur;
673
674 for (cur = pattern_head; cur; cur = cur->link) 672 for (cur = pattern_head; cur; cur = cur->link)
675 cur->data = new_grep_list_data(cur->data, 0); 673 cur->data = new_grep_list_data(cur->data, 0);
676 } 674 }
677 if (option_mask32 & OPT_f) 675 if (option_mask32 & OPT_f) {
678 load_regexes_from_file(fopt); 676 load_regexes_from_file(fopt);
677 if (!pattern_head) { /* -f EMPTY_FILE? */
678 /* GNU grep treats it as "nothing matches" */
679 llist_add_to(&pattern_head, new_grep_list_data((char*) "", 0));
680 invert_search ^= 1;
681 }
682 }
679 683
680 if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f') 684 if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f')
681 option_mask32 |= OPT_F; 685 option_mask32 |= OPT_F;
diff --git a/include/platform.h b/include/platform.h
index e22c42007..713e76d04 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -451,6 +451,8 @@ typedef unsigned smalluint;
451# undef HAVE_STRVERSCMP 451# undef HAVE_STRVERSCMP
452# undef HAVE_XTABS 452# undef HAVE_XTABS
453# undef HAVE_DPRINTF 453# undef HAVE_DPRINTF
454# undef HAVE_UNLOCKED_STDIO
455# undef HAVE_UNLOCKED_LINE_OPS
454#endif 456#endif
455 457
456#if defined(__FreeBSD__) 458#if defined(__FreeBSD__)
@@ -465,7 +467,7 @@ typedef unsigned smalluint;
465# undef HAVE_STPCPY 467# undef HAVE_STPCPY
466#endif 468#endif
467 469
468#if defined(ANDROID) 470#if defined(ANDROID) || defined(__ANDROID__)
469# undef HAVE_DPRINTF 471# undef HAVE_DPRINTF
470# undef HAVE_GETLINE 472# undef HAVE_GETLINE
471# undef HAVE_STPCPY 473# undef HAVE_STPCPY
diff --git a/libbb/getpty.c b/libbb/getpty.c
index 6a15cff2f..435e4d09f 100644
--- a/libbb/getpty.c
+++ b/libbb/getpty.c
@@ -19,20 +19,22 @@ int FAST_FUNC xgetpty(char *line)
19 if (p > 0) { 19 if (p > 0) {
20 grantpt(p); /* chmod+chown corresponding slave pty */ 20 grantpt(p); /* chmod+chown corresponding slave pty */
21 unlockpt(p); /* (what does this do?) */ 21 unlockpt(p); /* (what does this do?) */
22#ifndef HAVE_PTSNAME_R 22# ifndef HAVE_PTSNAME_R
23 const char *name; 23 {
24 name = ptsname(p); /* find out the name of slave pty */ 24 const char *name;
25 if (!name) { 25 name = ptsname(p); /* find out the name of slave pty */
26 bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); 26 if (!name) {
27 bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
28 }
29 safe_strncpy(line, name, GETPTY_BUFSIZE);
27 } 30 }
28 safe_strncpy(line, name, GETPTY_BUFSIZE); 31# else
29#else
30 /* find out the name of slave pty */ 32 /* find out the name of slave pty */
31 if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) { 33 if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) {
32 bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); 34 bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
33 } 35 }
34 line[GETPTY_BUFSIZE-1] = '\0'; 36 line[GETPTY_BUFSIZE-1] = '\0';
35#endif 37# endif
36 return p; 38 return p;
37 } 39 }
38#else 40#else
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 1b97e8609..46ae93f8a 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -1433,7 +1433,7 @@ static void save_history(char *str)
1433 1433
1434 /* write out temp file and replace hist_file atomically */ 1434 /* write out temp file and replace hist_file atomically */
1435 new_name = xasprintf("%s.%u.new", state->hist_file, (int) getpid()); 1435 new_name = xasprintf("%s.%u.new", state->hist_file, (int) getpid());
1436 fd = open(state->hist_file, O_WRONLY | O_CREAT | O_TRUNC, 0600); 1436 fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
1437 if (fd >= 0) { 1437 if (fd >= 0) {
1438 FILE *fp; 1438 FILE *fp;
1439 int i; 1439 int i;
diff --git a/libbb/match_fstype.c b/libbb/match_fstype.c
index 83d6e6770..32c3d7f18 100644
--- a/libbb/match_fstype.c
+++ b/libbb/match_fstype.c
@@ -12,6 +12,8 @@
12 12
13#include "libbb.h" 13#include "libbb.h"
14 14
15#ifdef HAVE_MNTENT_H
16
15int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) 17int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype)
16{ 18{
17 int match = 1; 19 int match = 1;
@@ -40,3 +42,5 @@ int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype)
40 42
41 return !match; 43 return !match;
42} 44}
45
46#endif /* HAVE_MNTENT_H */
diff --git a/libbb/procps.c b/libbb/procps.c
index b5582edfa..39ddd2c12 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -285,27 +285,25 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
285void BUG_comm_size(void); 285void BUG_comm_size(void);
286procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) 286procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
287{ 287{
288 struct dirent *entry;
289 char buf[PROCPS_BUFSIZE];
290 char filename[sizeof("/proc//cmdline") + sizeof(int)*3];
291 char *filename_tail;
292 long tasknice;
293 unsigned pid;
294 int n;
295 struct stat sb;
296
297 if (!sp) 288 if (!sp)
298 sp = alloc_procps_scan(); 289 sp = alloc_procps_scan();
299 290
300 for (;;) { 291 for (;;) {
292 struct dirent *entry;
293 char buf[PROCPS_BUFSIZE];
294 long tasknice;
295 unsigned pid;
296 int n;
297 char filename[sizeof("/proc/%u/task/%u/cmdline") + sizeof(int)*3 * 2];
298 char *filename_tail;
299
301#if ENABLE_FEATURE_SHOW_THREADS 300#if ENABLE_FEATURE_SHOW_THREADS
302 if ((flags & PSSCAN_TASKS) && sp->task_dir) { 301 if (sp->task_dir) {
303 entry = readdir(sp->task_dir); 302 entry = readdir(sp->task_dir);
304 if (entry) 303 if (entry)
305 goto got_entry; 304 goto got_entry;
306 closedir(sp->task_dir); 305 closedir(sp->task_dir);
307 sp->task_dir = NULL; 306 sp->task_dir = NULL;
308 sp->main_thread_pid = 0;
309 } 307 }
310#endif 308#endif
311 entry = readdir(sp->dir); 309 entry = readdir(sp->dir);
@@ -322,9 +320,9 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
322 /* We found another /proc/PID. Do not use it, 320 /* We found another /proc/PID. Do not use it,
323 * there will be /proc/PID/task/PID (same PID!), 321 * there will be /proc/PID/task/PID (same PID!),
324 * so just go ahead and dive into /proc/PID/task. */ 322 * so just go ahead and dive into /proc/PID/task. */
325 char task_dir[sizeof("/proc/%u/task") + sizeof(int)*3]; 323 sprintf(filename, "/proc/%u/task", pid);
326 sprintf(task_dir, "/proc/%u/task", pid); 324 /* Note: if opendir fails, we just go to next /proc/XXX */
327 sp->task_dir = xopendir(task_dir); 325 sp->task_dir = opendir(filename);
328 sp->main_thread_pid = pid; 326 sp->main_thread_pid = pid;
329 continue; 327 continue;
330 } 328 }
@@ -348,9 +346,15 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
348 } 346 }
349#endif 347#endif
350 348
351 filename_tail = filename + sprintf(filename, "/proc/%u/", pid); 349#if ENABLE_FEATURE_SHOW_THREADS
350 if (sp->task_dir)
351 filename_tail = filename + sprintf(filename, "/proc/%u/task/%u/", sp->main_thread_pid, pid);
352 else
353#endif
354 filename_tail = filename + sprintf(filename, "/proc/%u/", pid);
352 355
353 if (flags & PSSCAN_UIDGID) { 356 if (flags & PSSCAN_UIDGID) {
357 struct stat sb;
354 if (stat(filename, &sb)) 358 if (stat(filename, &sb))
355 continue; /* process probably exited */ 359 continue; /* process probably exited */
356 /* Effective UID/GID, not real */ 360 /* Effective UID/GID, not real */
diff --git a/libbb/udp_io.c b/libbb/udp_io.c
index b8fb6755d..7985a9723 100644
--- a/libbb/udp_io.c
+++ b/libbb/udp_io.c
@@ -13,7 +13,7 @@
13 * We don't check for errors here. Not supported == won't be used 13 * We don't check for errors here. Not supported == won't be used
14 */ 14 */
15void FAST_FUNC 15void FAST_FUNC
16socket_want_pktinfo(int fd) 16socket_want_pktinfo(int fd UNUSED_PARAM)
17{ 17{
18#ifdef IP_PKTINFO 18#ifdef IP_PKTINFO
19 setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); 19 setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int));
diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c
index 2262b792a..b7df57e5d 100644
--- a/loginutils/chpasswd.c
+++ b/loginutils/chpasswd.c
@@ -33,9 +33,8 @@ static const char chpasswd_longopts[] ALIGN1 =
33int chpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 33int chpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
34int chpasswd_main(int argc UNUSED_PARAM, char **argv) 34int chpasswd_main(int argc UNUSED_PARAM, char **argv)
35{ 35{
36 char *name, *pass; 36 char *name;
37 char salt[sizeof("$N$XXXXXXXX")]; 37 int opt;
38 int opt, rc;
39 38
40 if (getuid() != 0) 39 if (getuid() != 0)
41 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 40 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
@@ -45,6 +44,10 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv)
45 opt = getopt32(argv, "em"); 44 opt = getopt32(argv, "em");
46 45
47 while ((name = xmalloc_fgetline(stdin)) != NULL) { 46 while ((name = xmalloc_fgetline(stdin)) != NULL) {
47 char *free_me;
48 char *pass;
49 int rc;
50
48 pass = strchr(name, ':'); 51 pass = strchr(name, ':');
49 if (!pass) 52 if (!pass)
50 bb_error_msg_and_die("missing new password"); 53 bb_error_msg_and_die("missing new password");
@@ -52,7 +55,10 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv)
52 55
53 xuname2uid(name); /* dies if there is no such user */ 56 xuname2uid(name); /* dies if there is no such user */
54 57
58 free_me = NULL;
55 if (!(opt & OPT_ENC)) { 59 if (!(opt & OPT_ENC)) {
60 char salt[sizeof("$N$XXXXXXXX")];
61
56 crypt_make_salt(salt, 1); 62 crypt_make_salt(salt, 1);
57 if (opt & OPT_MD5) { 63 if (opt & OPT_MD5) {
58 salt[0] = '$'; 64 salt[0] = '$';
@@ -60,7 +66,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv)
60 salt[2] = '$'; 66 salt[2] = '$';
61 crypt_make_salt(salt + 3, 4); 67 crypt_make_salt(salt + 3, 4);
62 } 68 }
63 pass = pw_encrypt(pass, salt, 0); 69 free_me = pass = pw_encrypt(pass, salt, 0);
64 } 70 }
65 71
66 /* This is rather complex: if user is not found in /etc/shadow, 72 /* This is rather complex: if user is not found in /etc/shadow,
@@ -81,8 +87,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv)
81 bb_info_msg("Password for '%s' changed", name); 87 bb_info_msg("Password for '%s' changed", name);
82 logmode = LOGMODE_STDIO; 88 logmode = LOGMODE_STDIO;
83 free(name); 89 free(name);
84 if (!(opt & OPT_ENC)) 90 free(free_me);
85 free(pass);
86 } 91 }
87 return EXIT_SUCCESS; 92 return EXIT_SUCCESS;
88} 93}
diff --git a/loginutils/getty.c b/loginutils/getty.c
index 62456651b..4c8dd91a2 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -271,7 +271,9 @@ static void termios_init(int speed)
271#ifdef CMSPAR 271#ifdef CMSPAR
272 | CMSPAR /* mark or space parity */ 272 | CMSPAR /* mark or space parity */
273#endif 273#endif
274#ifdef CBAUD
274 | CBAUD /* (output) baud rate */ 275 | CBAUD /* (output) baud rate */
276#endif
275#ifdef CBAUDEX 277#ifdef CBAUDEX
276 | CBAUDEX /* (output) baud rate */ 278 | CBAUDEX /* (output) baud rate */
277#endif 279#endif
diff --git a/miscutils/crond.c b/miscutils/crond.c
index 014016fb6..a0b73c774 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -861,7 +861,8 @@ int crond_main(int argc UNUSED_PARAM, char **argv)
861 861
862 /* "-b after -f is ignored", and so on for every pair a-b */ 862 /* "-b after -f is ignored", and so on for every pair a-b */
863 opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l") 863 opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l")
864 ":l+:d+"; /* -l and -d have numeric param */ 864 /* -l and -d have numeric param */
865 ":l+" IF_FEATURE_CROND_D(":d+");
865 opts = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"), 866 opts = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"),
866 &G.log_level, &G.log_filename, &G.crontab_dir_name 867 &G.log_level, &G.log_filename, &G.crontab_dir_name
867 IF_FEATURE_CROND_D(,&G.log_level)); 868 IF_FEATURE_CROND_D(,&G.log_level));
diff --git a/miscutils/less.c b/miscutils/less.c
index 9543fb9f9..045fd2db3 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -721,8 +721,8 @@ static void print_found(const char *line)
721 while (match_status == 0) { 721 while (match_status == 0) {
722 char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL, 722 char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL,
723 growline ? growline : "", 723 growline ? growline : "",
724 match_structs.rm_so, str, 724 (int)match_structs.rm_so, str,
725 match_structs.rm_eo - match_structs.rm_so, 725 (int)(match_structs.rm_eo - match_structs.rm_so),
726 str + match_structs.rm_so); 726 str + match_structs.rm_so);
727 free(growline); 727 free(growline);
728 growline = new; 728 growline = new;
@@ -990,7 +990,8 @@ static int64_t less_getch(int pos)
990 */ 990 */
991 if (key >= 0 && key < ' ' && key != 0x0d && key != 8) 991 if (key >= 0 && key < ' ' && key != 0x0d && key != 8)
992 goto again; 992 goto again;
993 return key; 993
994 return key64;
994} 995}
995 996
996static char* less_gets(int sz) 997static char* less_gets(int sz)
diff --git a/modutils/modinfo.c b/modutils/modinfo.c
index 410b6fbe4..c0910ffed 100644
--- a/modutils/modinfo.c
+++ b/modutils/modinfo.c
@@ -13,6 +13,7 @@
13//config:config MODINFO 13//config:config MODINFO
14//config: bool "modinfo" 14//config: bool "modinfo"
15//config: default y 15//config: default y
16//config: select PLATFORM_LINUX
16//config: help 17//config: help
17//config: Show information about a Linux Kernel module 18//config: Show information about a Linux Kernel module
18 19
diff --git a/networking/inetd.c b/networking/inetd.c
index 873fd9528..05ad8c792 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -1278,6 +1278,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
1278 sep->se_count = 0; 1278 sep->se_count = 0;
1279 rearm_alarm(); /* will revive it in RETRYTIME sec */ 1279 rearm_alarm(); /* will revive it in RETRYTIME sec */
1280 restore_sigmask(&omask); 1280 restore_sigmask(&omask);
1281 maybe_close(new_udp_fd);
1281 maybe_close(accepted_fd); 1282 maybe_close(accepted_fd);
1282 continue; /* -> check next fd in fd set */ 1283 continue; /* -> check next fd in fd set */
1283 } 1284 }
@@ -1298,17 +1299,18 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
1298 bb_perror_msg("vfork"+1); 1299 bb_perror_msg("vfork"+1);
1299 sleep(1); 1300 sleep(1);
1300 restore_sigmask(&omask); 1301 restore_sigmask(&omask);
1302 maybe_close(new_udp_fd);
1301 maybe_close(accepted_fd); 1303 maybe_close(accepted_fd);
1302 continue; /* -> check next fd in fd set */ 1304 continue; /* -> check next fd in fd set */
1303 } 1305 }
1304 if (pid == 0) 1306 if (pid == 0)
1305 pid--; /* -1: "we did fork and we are child" */ 1307 pid--; /* -1: "we did fork and we are child" */
1306 } 1308 }
1307 /* if pid == 0 here, we never forked */ 1309 /* if pid == 0 here, we didn't fork */
1308 1310
1309 if (pid > 0) { /* parent */ 1311 if (pid > 0) { /* parent */
1310 if (sep->se_wait) { 1312 if (sep->se_wait) {
1311 /* tcp wait: we passed listening socket to child, 1313 /* wait: we passed socket to child,
1312 * will wait for child to terminate */ 1314 * will wait for child to terminate */
1313 sep->se_wait = pid; 1315 sep->se_wait = pid;
1314 remove_fd_from_set(sep->se_fd); 1316 remove_fd_from_set(sep->se_fd);
@@ -1345,9 +1347,13 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
1345 setsid(); 1347 setsid();
1346 /* "nowait" udp */ 1348 /* "nowait" udp */
1347 if (new_udp_fd >= 0) { 1349 if (new_udp_fd >= 0) {
1348 len_and_sockaddr *lsa = xzalloc_lsa(sep->se_family); 1350 len_and_sockaddr *lsa;
1351 int r;
1352
1353 close(new_udp_fd);
1354 lsa = xzalloc_lsa(sep->se_family);
1349 /* peek at the packet and remember peer addr */ 1355 /* peek at the packet and remember peer addr */
1350 int r = recvfrom(ctrl, NULL, 0, MSG_PEEK|MSG_DONTWAIT, 1356 r = recvfrom(ctrl, NULL, 0, MSG_PEEK|MSG_DONTWAIT,
1351 &lsa->u.sa, &lsa->len); 1357 &lsa->u.sa, &lsa->len);
1352 if (r < 0) 1358 if (r < 0)
1353 goto do_exit1; 1359 goto do_exit1;
diff --git a/networking/tftp.c b/networking/tftp.c
index 17485a527..043b879af 100644
--- a/networking/tftp.c
+++ b/networking/tftp.c
@@ -813,7 +813,8 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv)
813 goto err; 813 goto err;
814 } 814 }
815 mode = local_file + strlen(local_file) + 1; 815 mode = local_file + strlen(local_file) + 1;
816 if (mode >= block_buf + result || strcmp(mode, "octet") != 0) { 816 /* RFC 1350 says mode string is case independent */
817 if (mode >= block_buf + result || strcasecmp(mode, "octet") != 0) {
817 goto err; 818 goto err;
818 } 819 }
819# if ENABLE_FEATURE_TFTP_BLOCKSIZE 820# if ENABLE_FEATURE_TFTP_BLOCKSIZE
diff --git a/networking/wget.c b/networking/wget.c
index eca673a86..24b0d93c8 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -552,6 +552,7 @@ static void download_one_url(const char *url)
552 FILE *dfp; /* socket to ftp server (data) */ 552 FILE *dfp; /* socket to ftp server (data) */
553 char *proxy = NULL; 553 char *proxy = NULL;
554 char *fname_out_alloc; 554 char *fname_out_alloc;
555 char *redirected_path = NULL;
555 struct host_info server; 556 struct host_info server;
556 struct host_info target; 557 struct host_info target;
557 558
@@ -794,8 +795,8 @@ However, in real world it was observed that some web servers
794 bb_error_msg_and_die("too many redirections"); 795 bb_error_msg_and_die("too many redirections");
795 fclose(sfp); 796 fclose(sfp);
796 if (str[0] == '/') { 797 if (str[0] == '/') {
797 free(target.allocated); 798 free(redirected_path);
798 target.path = target.allocated = xstrdup(str+1); 799 target.path = redirected_path = xstrdup(str+1);
799 /* lsa stays the same: it's on the same server */ 800 /* lsa stays the same: it's on the same server */
800 } else { 801 } else {
801 parse_url(str, &target); 802 parse_url(str, &target);
@@ -850,6 +851,7 @@ However, in real world it was observed that some web servers
850 free(server.allocated); 851 free(server.allocated);
851 free(target.allocated); 852 free(target.allocated);
852 free(fname_out_alloc); 853 free(fname_out_alloc);
854 free(redirected_path);
853} 855}
854 856
855int wget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 857int wget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
diff --git a/shell/cttyhack.c b/shell/cttyhack.c
index 4261289b4..37ea13723 100644
--- a/shell/cttyhack.c
+++ b/shell/cttyhack.c
@@ -122,10 +122,12 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv)
122 do { 122 do {
123#ifdef __linux__ 123#ifdef __linux__
124 int s = open_read_close("/sys/class/tty/console/active", 124 int s = open_read_close("/sys/class/tty/console/active",
125 console + 5, sizeof(console) - 5 - 1); 125 console + 5, sizeof(console) - 5);
126 if (s > 0) { 126 if (s > 0) {
127 /* found active console via sysfs (Linux 2.6.38+) */ 127 /* found active console via sysfs (Linux 2.6.38+)
128 console[5 + s] = '\0'; 128 * sysfs string looks like "ttyS0\n" so zap the newline:
129 */
130 console[4 + s] = '\0';
129 break; 131 break;
130 } 132 }
131 133
diff --git a/shell/hush.c b/shell/hush.c
index e4138adf7..de0af9cec 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -7817,20 +7817,24 @@ int hush_main(int argc, char **argv)
7817 7817
7818#if ENABLE_FEATURE_EDITING 7818#if ENABLE_FEATURE_EDITING
7819 G.line_input_state = new_line_input_t(FOR_SHELL); 7819 G.line_input_state = new_line_input_t(FOR_SHELL);
7820# if defined MAX_HISTORY && MAX_HISTORY > 0 && ENABLE_HUSH_SAVEHISTORY 7820# if MAX_HISTORY > 0 && ENABLE_HUSH_SAVEHISTORY
7821 { 7821 {
7822 const char *hp = get_local_var_value("HISTFILE"); 7822 const char *hp = get_local_var_value("HISTFILE");
7823 if (!hp) { 7823 if (!hp) {
7824 hp = get_local_var_value("HOME"); 7824 hp = get_local_var_value("HOME");
7825 if (hp) { 7825 if (hp)
7826 G.line_input_state->hist_file = concat_path_file(hp, ".hush_history"); 7826 hp = concat_path_file(hp, ".hush_history");
7827 //set_local_var(xasprintf("HISTFILE=%s", ...)); 7827 } else {
7828 } 7828 hp = xstrdup(hp);
7829 } 7829 }
7830# if ENABLE_FEATURE_SH_HISTFILESIZE 7830 if (hp) {
7831 G.line_input_state->hist_file = hp;
7832 //set_local_var(xasprintf("HISTFILE=%s", ...));
7833 }
7834# if ENABLE_FEATURE_SH_HISTFILESIZE
7831 hp = get_local_var_value("HISTFILESIZE"); 7835 hp = get_local_var_value("HISTFILESIZE");
7832 G.line_input_state->max_history = size_from_HISTFILESIZE(hp); 7836 G.line_input_state->max_history = size_from_HISTFILESIZE(hp);
7833# endif 7837# endif
7834 } 7838 }
7835# endif 7839# endif
7836#endif 7840#endif
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 2f0ca6ac5..fc380d9f9 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -278,7 +278,7 @@ static void parse_syslogdcfg(const char *file)
278 parser_t *parser; 278 parser_t *parser;
279 279
280 parser = config_open2(file ? file : "/etc/syslog.conf", 280 parser = config_open2(file ? file : "/etc/syslog.conf",
281 file ? xfopen_for_read : fopen_or_warn_stdin); 281 file ? xfopen_for_read : fopen_for_read);
282 if (!parser) 282 if (!parser)
283 /* didn't find default /etc/syslog.conf */ 283 /* didn't find default /etc/syslog.conf */
284 /* proceed as if we built busybox without config support */ 284 /* proceed as if we built busybox without config support */
@@ -594,6 +594,14 @@ static void log_locally(time_t now, char *msg, logFile_t *log_file)
594 } 594 }
595 /* newFile == "f.0" now */ 595 /* newFile == "f.0" now */
596 rename(log_file->path, newFile); 596 rename(log_file->path, newFile);
597 /* Incredibly, if F and F.0 are hardlinks, POSIX
598 * _demands_ that rename returns 0 but does not
599 * remove F!!!
600 * (hardlinked F/F.0 pair was observed after
601 * power failure during rename()).
602 * Ensure old file is gone:
603 */
604 unlink(log_file->path);
597#ifdef SYSLOGD_WRLOCK 605#ifdef SYSLOGD_WRLOCK
598 fl.l_type = F_UNLCK; 606 fl.l_type = F_UNLCK;
599 fcntl(log_file->fd, F_SETLKW, &fl); 607 fcntl(log_file->fd, F_SETLKW, &fl);
@@ -678,7 +686,7 @@ static void timestamp_and_log(int pri, char *msg, int len)
678 if (LOG_PRI(pri) < G.logLevel) { 686 if (LOG_PRI(pri) < G.logLevel) {
679#if ENABLE_FEATURE_IPC_SYSLOG 687#if ENABLE_FEATURE_IPC_SYSLOG
680 if ((option_mask32 & OPT_circularlog) && G.shbuf) { 688 if ((option_mask32 & OPT_circularlog) && G.shbuf) {
681 log_to_shmem(msg); 689 log_to_shmem(G.printbuf);
682 return; 690 return;
683 } 691 }
684#endif 692#endif
diff --git a/testsuite/sed.tests b/testsuite/sed.tests
index e9d0ed601..ba163e9e9 100755
--- a/testsuite/sed.tests
+++ b/testsuite/sed.tests
@@ -6,7 +6,7 @@
6 6
7. ./testing.sh 7. ./testing.sh
8 8
9# testing "description" "arguments" "result" "infile" "stdin" 9# testing "description" "commands" "result" "infile" "stdin"
10 10
11# Corner cases 11# Corner cases
12testing "sed no files (stdin)" 'sed ""' "hello\n" "" "hello\n" 12testing "sed no files (stdin)" 'sed ""' "hello\n" "" "hello\n"
@@ -225,7 +225,7 @@ testing "sed s/xxx/[/" "sed -e 's/xxx/[/'" "[\n" "" "xxx\n"
225#testing "sed -g (exhaustive)" "sed -e 's/[[:space:]]*/,/g'" ",1,2,3,4,5," \ 225#testing "sed -g (exhaustive)" "sed -e 's/[[:space:]]*/,/g'" ",1,2,3,4,5," \
226# "" "12345" 226# "" "12345"
227 227
228# testing "description" "arguments" "result" "infile" "stdin" 228# testing "description" "commands" "result" "infile" "stdin"
229 229
230testing "sed n command must reset 'substituted' bit" \ 230testing "sed n command must reset 'substituted' bit" \
231 "sed 's/1/x/;T;n;: next;s/3/y/;t quit;n;b next;: quit;q'" \ 231 "sed 's/1/x/;T;n;: next;s/3/y/;t quit;n;b next;: quit;q'" \
@@ -291,6 +291,10 @@ testing "sed understands \r" \
291 "sed 's/r/\r/'" \ 291 "sed 's/r/\r/'" \
292 "\rrr\n" "" "rrr\n" 292 "\rrr\n" "" "rrr\n"
293 293
294# testing "description" "arguments" "result" "infile" "stdin" 294testing "sed -i finishes ranges correctly" \
295 "sed '1,2d' -i input; echo \$?; cat input" \
296 "0\n3\n4\n" "1\n2\n3\n4\n" ""
297
298# testing "description" "commands" "result" "infile" "stdin"
295 299
296exit $FAILCOUNT 300exit $FAILCOUNT
diff --git a/testsuite/tail.tests b/testsuite/tail.tests
index 7140da262..305a83b15 100755
--- a/testsuite/tail.tests
+++ b/testsuite/tail.tests
@@ -14,4 +14,12 @@ testing "tail: +N with N > file length" \
14 "0\n" \ 14 "0\n" \
15 "" "qw" 15 "" "qw"
16 16
17testing "tail: -c +N with largish N" \
18 "
19 dd if=/dev/zero bs=16k count=1 2>/dev/null | tail -c +8200 | wc -c;
20 dd if=/dev/zero bs=16k count=1 2>/dev/null | tail -c +8208 | wc -c;
21 " \
22 "8185\n8177\n" \
23 "" ""
24
17exit $FAILCOUNT 25exit $FAILCOUNT
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 7cabb1df6..e0a527e73 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -610,7 +610,7 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
610 int seqlen; 610 int seqlen;
611 char seqbuf[sizeof(int)*3 + 2]; 611 char seqbuf[sizeof(int)*3 + 2];
612 612
613 seqlen = open_read_close("mdev.seq", seqbuf, sizeof(seqbuf-1)); 613 seqlen = open_read_close("mdev.seq", seqbuf, sizeof(seqbuf) - 1);
614 if (seqlen < 0) { 614 if (seqlen < 0) {
615 seq = NULL; 615 seq = NULL;
616 break; 616 break;
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c
index 43ddb4031..e53e24c71 100644
--- a/util-linux/swaponoff.c
+++ b/util-linux/swaponoff.c
@@ -114,7 +114,8 @@ int swap_on_off_main(int argc UNUSED_PARAM, char **argv)
114#if !ENABLE_FEATURE_SWAPON_PRI 114#if !ENABLE_FEATURE_SWAPON_PRI
115 ret = getopt32(argv, "a"); 115 ret = getopt32(argv, "a");
116#else 116#else
117 opt_complementary = "p+"; 117 if (applet_name[5] == 'n')
118 opt_complementary = "p+";
118 ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags); 119 ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags);
119 120
120 if (ret & 2) { // -p 121 if (ret & 2) { // -p