From cc272b06eefb87030bb85b686abdbc22b5ed1c34 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 28 Aug 2011 13:00:29 +0200 Subject: Apply post-1.19.0 patches, bump version to 1.19.1 Signed-off-by: Denys Vlasenko --- Makefile | 2 +- archival/libarchive/decompress_uncompress.c | 13 +++-- editors/sed.c | 79 +++++++++++++++++++---------- findutils/find.c | 5 +- findutils/grep.c | 22 ++++---- include/platform.h | 2 + libbb/getpty.c | 18 ++++--- libbb/match_fstype.c | 4 ++ libbb/procps.c | 34 +++++++------ libbb/udp_io.c | 2 +- miscutils/less.c | 7 +-- shell/cttyhack.c | 8 +-- testsuite/sed.tests | 10 ++-- util-linux/swaponoff.c | 3 +- 14 files changed, 131 insertions(+), 78 deletions(-) diff --git a/Makefile b/Makefile index 7a1abda1b..138d1d425 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 19 -SUBLEVEL = 0 +SUBLEVEL = 1 EXTRAVERSION = NAME = Unnamed 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) if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); -//error check?? + if (rsize < 0) + bb_error_msg_and_die(bb_msg_read_error); insize += rsize; } @@ -195,6 +196,8 @@ unpack_Z_stream(int fd_in, int fd_out) if (oldcode == -1) { + if (code >= 256) + bb_error_msg_and_die("corrupted data"); /* %ld", code); */ oldcode = code; finchar = (int) oldcode; outbuf[outpos++] = (unsigned char) finchar; @@ -239,6 +242,8 @@ unpack_Z_stream(int fd_in, int fd_out) /* Generate output characters in reverse order */ while ((long) code >= (long) 256) { + if (stackp <= &htabof(0)) + bb_error_msg_and_die("corrupted data"); *--stackp = tab_suffixof(code); code = tab_prefixof(code); } @@ -263,8 +268,7 @@ unpack_Z_stream(int fd_in, int fd_out) } if (outpos >= OBUFSIZ) { - full_write(fd_out, outbuf, outpos); -//error check?? + xwrite(fd_out, outbuf, outpos); IF_DESKTOP(total_written += outpos;) outpos = 0; } @@ -292,8 +296,7 @@ unpack_Z_stream(int fd_in, int fd_out) } while (rsize > 0); if (outpos > 0) { - full_write(fd_out, outbuf, outpos); -//error check?? + xwrite(fd_out, outbuf, outpos); IF_DESKTOP(total_written += outpos;) } 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 @@ #include "libbb.h" #include "xregex.h" +#if 0 +# define dbg(...) bb_error_msg(__VA_ARGS__) +#else +# define dbg(...) ((void)0) +#endif + + enum { OPT_in_place = 1 << 0, }; @@ -89,6 +96,7 @@ typedef struct sed_cmd_s { regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */ regex_t *sub_match; /* For 's/sub_match/string/' */ int beg_line; /* 'sed 1p' 0 == apply commands to all lines */ + int beg_line_orig; /* copy of the above, needed for -i */ int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($) */ FILE *sw_file; /* File (sw) command writes to, -1 for none. */ @@ -123,7 +131,7 @@ struct globals { regex_t *previous_regex_ptr; /* linked list of sed commands */ - sed_cmd_t sed_cmd_head, *sed_cmd_tail; + sed_cmd_t *sed_cmd_head, **sed_cmd_tail; /* Linked list of append lines */ llist_t *append_head; @@ -148,7 +156,7 @@ struct BUG_G_too_big { #if ENABLE_FEATURE_CLEAN_UP static void sed_free_and_close_stuff(void) { - sed_cmd_t *sed_cmd = G.sed_cmd_head.next; + sed_cmd_t *sed_cmd = G.sed_cmd_head; llist_free(G.append_head, free); @@ -599,6 +607,7 @@ static void add_cmd(const char *cmdstr) /* first part (if present) is an address: either a '$', a number or a /regex/ */ cmdstr += get_address(cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match); + sed_cmd->beg_line_orig = sed_cmd->beg_line; /* second part (if present) will begin with a comma */ if (*cmdstr == ',') { @@ -630,8 +639,8 @@ static void add_cmd(const char *cmdstr) cmdstr = parse_cmd_args(sed_cmd, cmdstr); /* Add the command to the command array */ - G.sed_cmd_tail->next = sed_cmd; - G.sed_cmd_tail = G.sed_cmd_tail->next; + *G.sed_cmd_tail = sed_cmd; + G.sed_cmd_tail = &sed_cmd->next; } /* If we glued multiple lines together, free the memory. */ @@ -777,7 +786,7 @@ static sed_cmd_t *branch_to(char *label) { sed_cmd_t *sed_cmd; - for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { + for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) { if (sed_cmd->cmd == ':' && sed_cmd->string && !strcmp(sed_cmd->string, label)) { return sed_cmd; } @@ -953,24 +962,24 @@ static void process_files(void) /* For every line, go through all the commands */ restart: - for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { + for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) { int old_matched, matched; old_matched = sed_cmd->in_match; /* Determine if this command matches this line: */ - //bb_error_msg("match1:%d", sed_cmd->in_match); - //bb_error_msg("match2:%d", (!sed_cmd->beg_line && !sed_cmd->end_line - // && !sed_cmd->beg_match && !sed_cmd->end_match)); - //bb_error_msg("match3:%d", (sed_cmd->beg_line > 0 - // && (sed_cmd->end_line || sed_cmd->end_match - // ? (sed_cmd->beg_line <= linenum) - // : (sed_cmd->beg_line == linenum) - // ) - // ) - //bb_error_msg("match4:%d", (beg_match(sed_cmd, pattern_space))); - //bb_error_msg("match5:%d", (sed_cmd->beg_line == -1 && next_line == NULL)); + dbg("match1:%d", sed_cmd->in_match); + dbg("match2:%d", (!sed_cmd->beg_line && !sed_cmd->end_line + && !sed_cmd->beg_match && !sed_cmd->end_match)); + dbg("match3:%d", (sed_cmd->beg_line > 0 + && (sed_cmd->end_line || sed_cmd->end_match + ? (sed_cmd->beg_line <= linenum) + : (sed_cmd->beg_line == linenum) + ) + )); + dbg("match4:%d", (beg_match(sed_cmd, pattern_space))); + dbg("match5:%d", (sed_cmd->beg_line == -1 && next_line == NULL)); /* Are we continuing a previous multi-line match? */ sed_cmd->in_match = sed_cmd->in_match @@ -981,7 +990,14 @@ static void process_files(void) || (sed_cmd->beg_line > 0 && (sed_cmd->end_line || sed_cmd->end_match /* note: even if end is numeric and is < linenum too, - * GNU sed matches! We match too */ + * GNU sed matches! We match too, therefore we don't + * check here that linenum <= end. + * Example: + * printf '1\n2\n3\n4\n' | sed -n '1{N;N;d};1p;2,3p;3p;4p' + * first three input lines are deleted; + * 4th line is matched and printed + * by "2,3" (!) and by "4" ranges + */ ? (sed_cmd->beg_line <= linenum) /* N,end */ : (sed_cmd->beg_line == linenum) /* N */ ) @@ -994,16 +1010,14 @@ static void process_files(void) /* Snapshot the value */ matched = sed_cmd->in_match; - //bb_error_msg("cmd:'%c' matched:%d beg_line:%d end_line:%d linenum:%d", - //sed_cmd->cmd, matched, sed_cmd->beg_line, sed_cmd->end_line, linenum); + dbg("cmd:'%c' matched:%d beg_line:%d end_line:%d linenum:%d", + sed_cmd->cmd, matched, sed_cmd->beg_line, sed_cmd->end_line, linenum); /* Is this line the end of the current match? */ if (matched) { /* once matched, "n,xxx" range is dead, disabling it */ - if (sed_cmd->beg_line > 0 - && !(option_mask32 & OPT_in_place) /* but not for -i */ - ) { + if (sed_cmd->beg_line > 0) { sed_cmd->beg_line = -2; } sed_cmd->in_match = !( @@ -1017,7 +1031,8 @@ static void process_files(void) /* or does this line matches our last address regex */ || (sed_cmd->end_match && old_matched && (regexec(sed_cmd->end_match, - pattern_space, 0, NULL, 0) == 0)) + pattern_space, 0, NULL, 0) == 0) + ) ); } @@ -1407,11 +1422,12 @@ int sed_main(int argc UNUSED_PARAM, char **argv) add_input_file(stdin); } else { int i; - FILE *file; for (i = 0; argv[i]; i++) { struct stat statbuf; int nonstdoutfd; + FILE *file; + sed_cmd_t *sed_cmd; if (LONE_DASH(argv[i]) && !(opt & OPT_in_place)) { add_input_file(stdin); @@ -1423,11 +1439,13 @@ int sed_main(int argc UNUSED_PARAM, char **argv) status = EXIT_FAILURE; continue; } + add_input_file(file); if (!(opt & OPT_in_place)) { - add_input_file(file); continue; } + /* -i: process each FILE separately: */ + G.outname = xasprintf("%sXXXXXX", argv[i]); nonstdoutfd = xmkstemp(G.outname); G.nonstdout = xfdopen_for_write(nonstdoutfd); @@ -1438,15 +1456,20 @@ int sed_main(int argc UNUSED_PARAM, char **argv) * but GNU sed 4.2.1 does not preserve them either */ fchmod(nonstdoutfd, statbuf.st_mode); fchown(nonstdoutfd, statbuf.st_uid, statbuf.st_gid); - add_input_file(file); + process_files(); fclose(G.nonstdout); - G.nonstdout = stdout; + /* unlink(argv[i]); */ xrename(G.outname, argv[i]); free(G.outname); G.outname = NULL; + + /* Re-enable disabled range matches */ + for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) { + sed_cmd->beg_line = sed_cmd->beg_line_orig; + } } /* Here, to handle "sed 'cmds' nonexistent_file" case we did: * 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) * expression is reached. */ /* Options */ - if (0) { } + if (parm == OPT_FOLLOW) { + dbg("follow enabled: %d", __LINE__); + G.recurse_flags |= ACTION_FOLLOWLINKS | ACTION_DANGLING_OK; + } #if ENABLE_FEATURE_FIND_XDEV else if (parm == OPT_XDEV) { dbg("%d", __LINE__); diff --git a/findutils/grep.c b/findutils/grep.c index 3acfa9197..5f4224203 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -562,20 +562,20 @@ static char *add_grep_list_data(char *pattern) static void load_regexes_from_file(llist_t *fopt) { - char *line; - FILE *f; - while (fopt) { + char *line; + FILE *fp; llist_t *cur = fopt; char *ffile = cur->data; fopt = cur->link; free(cur); - f = xfopen_stdin(ffile); - while ((line = xmalloc_fgetline(f)) != NULL) { + fp = xfopen_stdin(ffile); + while ((line = xmalloc_fgetline(fp)) != NULL) { llist_add_to(&pattern_head, new_grep_list_data(line, ALLOCATED)); } + fclose_if_not_stdin(fp); } } @@ -659,15 +659,19 @@ int grep_main(int argc UNUSED_PARAM, char **argv) #endif invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */ - if (pattern_head != NULL) { - /* convert char **argv to grep_list_data_t */ + { /* convert char **argv to grep_list_data_t */ llist_t *cur; - for (cur = pattern_head; cur; cur = cur->link) cur->data = new_grep_list_data(cur->data, 0); } - if (option_mask32 & OPT_f) + if (option_mask32 & OPT_f) { load_regexes_from_file(fopt); + if (!pattern_head) { /* -f EMPTY_FILE? */ + /* GNU grep treats it as "nothing matches" */ + llist_add_to(&pattern_head, new_grep_list_data((char*) "", 0)); + invert_search ^= 1; + } + } if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f') option_mask32 |= OPT_F; diff --git a/include/platform.h b/include/platform.h index e22dbdb4a..826a4c497 100644 --- a/include/platform.h +++ b/include/platform.h @@ -417,6 +417,8 @@ typedef unsigned smalluint; # undef HAVE_STRVERSCMP # undef HAVE_XTABS # undef HAVE_DPRINTF +# undef HAVE_UNLOCKED_STDIO +# undef HAVE_UNLOCKED_LINE_OPS #endif #if defined(__FreeBSD__) 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) if (p > 0) { grantpt(p); /* chmod+chown corresponding slave pty */ unlockpt(p); /* (what does this do?) */ -#ifndef HAVE_PTSNAME_R - const char *name; - name = ptsname(p); /* find out the name of slave pty */ - if (!name) { - bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); +# ifndef HAVE_PTSNAME_R + { + const char *name; + name = ptsname(p); /* find out the name of slave pty */ + if (!name) { + bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); + } + safe_strncpy(line, name, GETPTY_BUFSIZE); } - safe_strncpy(line, name, GETPTY_BUFSIZE); -#else +# else /* find out the name of slave pty */ if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) { bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); } line[GETPTY_BUFSIZE-1] = '\0'; -#endif +# endif return p; } #else diff --git a/libbb/match_fstype.c b/libbb/match_fstype.c index 83d6e6770..c792d13b3 100644 --- a/libbb/match_fstype.c +++ b/libbb/match_fstype.c @@ -10,6 +10,8 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +#ifdef HAVE_MNTENT_H + #include "libbb.h" int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) @@ -40,3 +42,5 @@ int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) return !match; } + +#endif /* HAVE_MNTENT_H */ diff --git a/libbb/procps.c b/libbb/procps.c index 1dea61518..e15ddd1e5 100644 --- a/libbb/procps.c +++ b/libbb/procps.c @@ -284,27 +284,25 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, void BUG_comm_size(void); procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) { - struct dirent *entry; - char buf[PROCPS_BUFSIZE]; - char filename[sizeof("/proc//cmdline") + sizeof(int)*3]; - char *filename_tail; - long tasknice; - unsigned pid; - int n; - struct stat sb; - if (!sp) sp = alloc_procps_scan(); for (;;) { + struct dirent *entry; + char buf[PROCPS_BUFSIZE]; + long tasknice; + unsigned pid; + int n; + char filename[sizeof("/proc/%u/task/%u/cmdline") + sizeof(int)*3 * 2]; + char *filename_tail; + #if ENABLE_FEATURE_SHOW_THREADS - if ((flags & PSSCAN_TASKS) && sp->task_dir) { + if (sp->task_dir) { entry = readdir(sp->task_dir); if (entry) goto got_entry; closedir(sp->task_dir); sp->task_dir = NULL; - sp->main_thread_pid = 0; } #endif entry = readdir(sp->dir); @@ -321,9 +319,9 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) /* We found another /proc/PID. Do not use it, * there will be /proc/PID/task/PID (same PID!), * so just go ahead and dive into /proc/PID/task. */ - char task_dir[sizeof("/proc/%u/task") + sizeof(int)*3]; - sprintf(task_dir, "/proc/%u/task", pid); - sp->task_dir = xopendir(task_dir); + sprintf(filename, "/proc/%u/task", pid); + /* Note: if opendir fails, we just go to next /proc/XXX */ + sp->task_dir = opendir(filename); sp->main_thread_pid = pid; continue; } @@ -347,9 +345,15 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) } #endif - filename_tail = filename + sprintf(filename, "/proc/%u/", pid); +#if ENABLE_FEATURE_SHOW_THREADS + if (sp->task_dir) + filename_tail = filename + sprintf(filename, "/proc/%u/task/%u/", sp->main_thread_pid, pid); + else +#endif + filename_tail = filename + sprintf(filename, "/proc/%u/", pid); if (flags & PSSCAN_UIDGID) { + struct stat sb; if (stat(filename, &sb)) continue; /* process probably exited */ /* 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 @@ * We don't check for errors here. Not supported == won't be used */ void FAST_FUNC -socket_want_pktinfo(int fd) +socket_want_pktinfo(int fd UNUSED_PARAM) { #ifdef IP_PKTINFO setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); 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) while (match_status == 0) { char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL, growline ? growline : "", - match_structs.rm_so, str, - match_structs.rm_eo - match_structs.rm_so, + (int)match_structs.rm_so, str, + (int)(match_structs.rm_eo - match_structs.rm_so), str + match_structs.rm_so); free(growline); growline = new; @@ -990,7 +990,8 @@ static int64_t less_getch(int pos) */ if (key >= 0 && key < ' ' && key != 0x0d && key != 8) goto again; - return key; + + return key64; } static char* less_gets(int sz) 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) do { #ifdef __linux__ int s = open_read_close("/sys/class/tty/console/active", - console + 5, sizeof(console) - 5 - 1); + console + 5, sizeof(console) - 5); if (s > 0) { - /* found active console via sysfs (Linux 2.6.38+) */ - console[5 + s] = '\0'; + /* found active console via sysfs (Linux 2.6.38+) + * sysfs string looks like "ttyS0\n" so zap the newline: + */ + console[4 + s] = '\0'; break; } 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 @@ . ./testing.sh -# testing "description" "arguments" "result" "infile" "stdin" +# testing "description" "commands" "result" "infile" "stdin" # Corner cases testing "sed no files (stdin)" 'sed ""' "hello\n" "" "hello\n" @@ -225,7 +225,7 @@ testing "sed s/xxx/[/" "sed -e 's/xxx/[/'" "[\n" "" "xxx\n" #testing "sed -g (exhaustive)" "sed -e 's/[[:space:]]*/,/g'" ",1,2,3,4,5," \ # "" "12345" -# testing "description" "arguments" "result" "infile" "stdin" +# testing "description" "commands" "result" "infile" "stdin" testing "sed n command must reset 'substituted' bit" \ "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" \ "sed 's/r/\r/'" \ "\rrr\n" "" "rrr\n" -# testing "description" "arguments" "result" "infile" "stdin" +testing "sed -i finishes ranges correctly" \ + "sed '1,2d' -i input; echo \$?; cat input" \ + "0\n3\n4\n" "1\n2\n3\n4\n" "" + +# testing "description" "commands" "result" "infile" "stdin" exit $FAILCOUNT 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) #if !ENABLE_FEATURE_SWAPON_PRI ret = getopt32(argv, "a"); #else - opt_complementary = "p+"; + if (applet_name[5] == 'n') + opt_complementary = "p+"; ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags); if (ret & 2) { // -p -- cgit v1.2.3