diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | console-tools/showkey.c | 4 | ||||
-rw-r--r-- | editors/awk.c | 21 | ||||
-rw-r--r-- | editors/vi.c | 48 | ||||
-rw-r--r-- | findutils/grep.c | 36 | ||||
-rw-r--r-- | libbb/lineedit.c | 73 | ||||
-rw-r--r-- | miscutils/crontab.c | 19 | ||||
-rw-r--r-- | modutils/insmod.c | 120 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 5 | ||||
-rw-r--r-- | procps/top.c | 17 |
10 files changed, 215 insertions, 130 deletions
@@ -1,6 +1,6 @@ | |||
1 | VERSION = 1 | 1 | VERSION = 1 |
2 | PATCHLEVEL = 12 | 2 | PATCHLEVEL = 12 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 1 |
4 | EXTRAVERSION = | 4 | EXTRAVERSION = |
5 | NAME = Unnamed | 5 | NAME = Unnamed |
6 | 6 | ||
diff --git a/console-tools/showkey.c b/console-tools/showkey.c index e4603e2d3..95db6e16e 100644 --- a/console-tools/showkey.c +++ b/console-tools/showkey.c | |||
@@ -50,7 +50,7 @@ static void signal_handler(int signo) | |||
50 | { | 50 | { |
51 | // restore keyboard and console settings | 51 | // restore keyboard and console settings |
52 | xset1(STDIN_FILENO, &tio0, "stdin"); | 52 | xset1(STDIN_FILENO, &tio0, "stdin"); |
53 | xioctl(STDIN_FILENO, KDSKBMODE, (void *)kbmode); | 53 | xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode); |
54 | // alarmed? -> exit 0 | 54 | // alarmed? -> exit 0 |
55 | exit(SIGALRM == signo); | 55 | exit(SIGALRM == signo); |
56 | } | 56 | } |
@@ -95,7 +95,7 @@ int showkey_main(int argc UNUSED_PARAM, char **argv) | |||
95 | // we should exit on any signal | 95 | // we should exit on any signal |
96 | bb_signals(BB_FATAL_SIGS, signal_handler); | 96 | bb_signals(BB_FATAL_SIGS, signal_handler); |
97 | // set raw keyboard mode | 97 | // set raw keyboard mode |
98 | xioctl(STDIN_FILENO, KDSKBMODE, (void *)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW)); | 98 | xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW)); |
99 | 99 | ||
100 | // read and show scancodes | 100 | // read and show scancodes |
101 | while (1) { | 101 | while (1) { |
diff --git a/editors/awk.c b/editors/awk.c index 571d68193..72eca245f 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -973,7 +973,12 @@ static uint32_t next_token(uint32_t expected) | |||
973 | 973 | ||
974 | } else if (*p == '.' || isdigit(*p)) { | 974 | } else if (*p == '.' || isdigit(*p)) { |
975 | /* it's a number */ | 975 | /* it's a number */ |
976 | t_double = strtod(p, &p); | 976 | #if ENABLE_DESKTOP |
977 | if (p[0] == '0' && (p[1] | 0x20) == 'x') | ||
978 | t_double = strtoll(p, &p, 0); | ||
979 | else | ||
980 | #endif | ||
981 | t_double = strtod(p, &p); | ||
977 | if (*p == '.') | 982 | if (*p == '.') |
978 | syntax_error(EMSG_UNEXP_TOKEN); | 983 | syntax_error(EMSG_UNEXP_TOKEN); |
979 | tc = TC_NUMBER; | 984 | tc = TC_NUMBER; |
@@ -2034,28 +2039,30 @@ static var *exec_builtin(node *op, var *res) | |||
2034 | setvar_p(res, s); | 2039 | setvar_p(res, s); |
2035 | break; | 2040 | break; |
2036 | 2041 | ||
2042 | /* Bitwise ops must assume that operands are unsigned. GNU Awk 3.1.5: | ||
2043 | * awk '{ print or(-1,1) }' gives "4.29497e+09", not "-2.xxxe+09" */ | ||
2037 | case B_an: | 2044 | case B_an: |
2038 | setvar_i(res, (long)getvar_i(av[0]) & (long)getvar_i(av[1])); | 2045 | setvar_i(res, (unsigned long)getvar_i(av[0]) & (unsigned long)getvar_i(av[1])); |
2039 | break; | 2046 | break; |
2040 | 2047 | ||
2041 | case B_co: | 2048 | case B_co: |
2042 | setvar_i(res, ~(long)getvar_i(av[0])); | 2049 | setvar_i(res, ~(unsigned long)getvar_i(av[0])); |
2043 | break; | 2050 | break; |
2044 | 2051 | ||
2045 | case B_ls: | 2052 | case B_ls: |
2046 | setvar_i(res, (long)getvar_i(av[0]) << (long)getvar_i(av[1])); | 2053 | setvar_i(res, (unsigned long)getvar_i(av[0]) << (unsigned long)getvar_i(av[1])); |
2047 | break; | 2054 | break; |
2048 | 2055 | ||
2049 | case B_or: | 2056 | case B_or: |
2050 | setvar_i(res, (long)getvar_i(av[0]) | (long)getvar_i(av[1])); | 2057 | setvar_i(res, (unsigned long)getvar_i(av[0]) | (unsigned long)getvar_i(av[1])); |
2051 | break; | 2058 | break; |
2052 | 2059 | ||
2053 | case B_rs: | 2060 | case B_rs: |
2054 | setvar_i(res, (long)((unsigned long)getvar_i(av[0]) >> (unsigned long)getvar_i(av[1]))); | 2061 | setvar_i(res, (unsigned long)getvar_i(av[0]) >> (unsigned long)getvar_i(av[1])); |
2055 | break; | 2062 | break; |
2056 | 2063 | ||
2057 | case B_xo: | 2064 | case B_xo: |
2058 | setvar_i(res, (long)getvar_i(av[0]) ^ (long)getvar_i(av[1])); | 2065 | setvar_i(res, (unsigned long)getvar_i(av[0]) ^ (unsigned long)getvar_i(av[1])); |
2059 | break; | 2066 | break; |
2060 | 2067 | ||
2061 | case B_lo: | 2068 | case B_lo: |
diff --git a/editors/vi.c b/editors/vi.c index 27f2a3abd..02bdbb37b 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -147,10 +147,10 @@ struct globals { | |||
147 | #endif | 147 | #endif |
148 | 148 | ||
149 | smallint editing; // >0 while we are editing a file | 149 | smallint editing; // >0 while we are editing a file |
150 | // [code audit says "can be 0 or 1 only"] | 150 | // [code audit says "can be 0, 1 or 2 only"] |
151 | smallint cmd_mode; // 0=command 1=insert 2=replace | 151 | smallint cmd_mode; // 0=command 1=insert 2=replace |
152 | int file_modified; // buffer contents changed (counter, not flag!) | 152 | int file_modified; // buffer contents changed (counter, not flag!) |
153 | int last_file_modified; // = -1; | 153 | int last_file_modified; // = -1; |
154 | int fn_start; // index of first cmd line file name | 154 | int fn_start; // index of first cmd line file name |
155 | int save_argc; // how many file names on cmd line | 155 | int save_argc; // how many file names on cmd line |
156 | int cmdcnt; // repetition count | 156 | int cmdcnt; // repetition count |
@@ -623,7 +623,7 @@ static void edit_file(char *fn) | |||
623 | // These are commands that change text[]. | 623 | // These are commands that change text[]. |
624 | // Remember the input for the "." command | 624 | // Remember the input for the "." command |
625 | if (!adding2q && ioq_start == NULL | 625 | if (!adding2q && ioq_start == NULL |
626 | && strchr(modifying_cmds, c) | 626 | && c != '\0' && strchr(modifying_cmds, c) |
627 | ) { | 627 | ) { |
628 | start_new_cmd_q(c); | 628 | start_new_cmd_q(c); |
629 | } | 629 | } |
@@ -645,8 +645,8 @@ static void edit_file(char *fn) | |||
645 | } | 645 | } |
646 | //------------------------------------------------------------------- | 646 | //------------------------------------------------------------------- |
647 | 647 | ||
648 | place_cursor(rows, 0, FALSE); // go to bottom of screen | 648 | place_cursor(rows - 1, 0, FALSE); // go to bottom of screen |
649 | clear_to_eol(); // Erase to end of line | 649 | clear_to_eol(); // erase to end of line |
650 | cookmode(); | 650 | cookmode(); |
651 | #undef cur_line | 651 | #undef cur_line |
652 | } | 652 | } |
@@ -2009,9 +2009,9 @@ static void start_new_cmd_q(char c) | |||
2009 | { | 2009 | { |
2010 | // get buffer for new cmd | 2010 | // get buffer for new cmd |
2011 | // if there is a current cmd count put it in the buffer first | 2011 | // if there is a current cmd count put it in the buffer first |
2012 | if (cmdcnt > 0) | 2012 | if (cmdcnt > 0) { |
2013 | lmc_len = sprintf(last_modifying_cmd, "%d%c", cmdcnt, c); | 2013 | lmc_len = sprintf(last_modifying_cmd, "%d%c", cmdcnt, c); |
2014 | else { // just save char c onto queue | 2014 | } else { // just save char c onto queue |
2015 | last_modifying_cmd[0] = c; | 2015 | last_modifying_cmd[0] = c; |
2016 | lmc_len = 1; | 2016 | lmc_len = 1; |
2017 | } | 2017 | } |
@@ -2157,21 +2157,21 @@ static void winch_sig(int sig UNUSED_PARAM) | |||
2157 | //----- Come here when we get a continue signal ------------------- | 2157 | //----- Come here when we get a continue signal ------------------- |
2158 | static void cont_sig(int sig UNUSED_PARAM) | 2158 | static void cont_sig(int sig UNUSED_PARAM) |
2159 | { | 2159 | { |
2160 | rawmode(); // terminal to "raw" | 2160 | rawmode(); // terminal to "raw" |
2161 | last_status_cksum = 0; // force status update | 2161 | last_status_cksum = 0; // force status update |
2162 | redraw(TRUE); // re-draw the screen | 2162 | redraw(TRUE); // re-draw the screen |
2163 | 2163 | ||
2164 | signal(SIGTSTP, suspend_sig); | 2164 | signal(SIGTSTP, suspend_sig); |
2165 | signal(SIGCONT, SIG_DFL); | 2165 | signal(SIGCONT, SIG_DFL); |
2166 | kill(my_pid, SIGCONT); | 2166 | kill(my_pid, SIGCONT); // huh? why? we are already "continued"... |
2167 | } | 2167 | } |
2168 | 2168 | ||
2169 | //----- Come here when we get a Suspend signal ------------------- | 2169 | //----- Come here when we get a Suspend signal ------------------- |
2170 | static void suspend_sig(int sig UNUSED_PARAM) | 2170 | static void suspend_sig(int sig UNUSED_PARAM) |
2171 | { | 2171 | { |
2172 | place_cursor(rows - 1, 0, FALSE); // go to bottom of screen | 2172 | place_cursor(rows - 1, 0, FALSE); // go to bottom of screen |
2173 | clear_to_eol(); // Erase to end of line | 2173 | clear_to_eol(); // erase to end of line |
2174 | cookmode(); // terminal to "cooked" | 2174 | cookmode(); // terminal to "cooked" |
2175 | 2175 | ||
2176 | signal(SIGCONT, cont_sig); | 2176 | signal(SIGCONT, cont_sig); |
2177 | signal(SIGTSTP, SIG_DFL); | 2177 | signal(SIGTSTP, SIG_DFL); |
@@ -2247,18 +2247,20 @@ static char readit(void) // read (maybe cursor) key from stdin | |||
2247 | 2247 | ||
2248 | fflush(stdout); | 2248 | fflush(stdout); |
2249 | n = chars_to_parse; | 2249 | n = chars_to_parse; |
2250 | // get input from User- are there already input chars in Q? | 2250 | // get input from User - are there already input chars in Q? |
2251 | if (n <= 0) { | 2251 | if (n <= 0) { |
2252 | // the Q is empty, wait for a typed char | 2252 | // the Q is empty, wait for a typed char |
2253 | again: | ||
2253 | n = safe_read(STDIN_FILENO, readbuffer, sizeof(readbuffer)); | 2254 | n = safe_read(STDIN_FILENO, readbuffer, sizeof(readbuffer)); |
2254 | if (n < 0) { | 2255 | if (n <= 0) { |
2255 | if (errno == EBADF || errno == EFAULT || errno == EINVAL | 2256 | place_cursor(rows - 1, 0, FALSE); // go to bottom of screen |
2256 | || errno == EIO) | 2257 | clear_to_eol(); // erase to end of line |
2257 | editing = 0; // want to exit | 2258 | cookmode(); // terminal to "cooked" |
2258 | errno = 0; | 2259 | bb_error_msg_and_die("can't read user input"); |
2259 | } | 2260 | } |
2260 | if (n <= 0) | 2261 | /* elsewhere we can get very confused by NULs */ |
2261 | return 0; // error | 2262 | if (readbuffer[0] == '\0') |
2263 | goto again; | ||
2262 | if (readbuffer[0] == 27) { | 2264 | if (readbuffer[0] == 27) { |
2263 | // This is an ESC char. Is this Esc sequence? | 2265 | // This is an ESC char. Is this Esc sequence? |
2264 | // Could be bare Esc key. See if there are any | 2266 | // Could be bare Esc key. See if there are any |
diff --git a/findutils/grep.c b/findutils/grep.c index f2ed01e74..9d38ef912 100644 --- a/findutils/grep.c +++ b/findutils/grep.c | |||
@@ -87,7 +87,11 @@ enum { | |||
87 | 87 | ||
88 | struct globals { | 88 | struct globals { |
89 | int max_matches; | 89 | int max_matches; |
90 | #if !ENABLE_EXTRA_COMPAT | ||
90 | int reflags; | 91 | int reflags; |
92 | #else | ||
93 | RE_TRANSLATE_TYPE case_fold; /* RE_TRANSLATE_TYPE is [[un]signed] char* */ | ||
94 | #endif | ||
91 | smalluint invert_search; | 95 | smalluint invert_search; |
92 | smalluint print_filename; | 96 | smalluint print_filename; |
93 | smalluint open_errors; | 97 | smalluint open_errors; |
@@ -110,7 +114,19 @@ struct globals { | |||
110 | }; \ | 114 | }; \ |
111 | } while (0) | 115 | } while (0) |
112 | #define max_matches (G.max_matches ) | 116 | #define max_matches (G.max_matches ) |
117 | #if !ENABLE_EXTRA_COMPAT | ||
113 | #define reflags (G.reflags ) | 118 | #define reflags (G.reflags ) |
119 | #else | ||
120 | #define case_fold (G.case_fold ) | ||
121 | /* http://www.delorie.com/gnu/docs/regex/regex_46.html */ | ||
122 | #define reflags re_syntax_options | ||
123 | #undef REG_NOSUB | ||
124 | #undef REG_EXTENDED | ||
125 | #undef REG_ICASE | ||
126 | #define REG_NOSUB bug:is:here /* should not be used */ | ||
127 | #define REG_EXTENDED RE_SYNTAX_EGREP | ||
128 | #define REG_ICASE bug:is:here /* should not be used */ | ||
129 | #endif | ||
114 | #define invert_search (G.invert_search ) | 130 | #define invert_search (G.invert_search ) |
115 | #define print_filename (G.print_filename ) | 131 | #define print_filename (G.print_filename ) |
116 | #define open_errors (G.open_errors ) | 132 | #define open_errors (G.open_errors ) |
@@ -240,6 +256,7 @@ static int grep_file(FILE *file) | |||
240 | xregcomp(&gl->compiled_regex, gl->pattern, reflags); | 256 | xregcomp(&gl->compiled_regex, gl->pattern, reflags); |
241 | #else | 257 | #else |
242 | memset(&gl->compiled_regex, 0, sizeof(gl->compiled_regex)); | 258 | memset(&gl->compiled_regex, 0, sizeof(gl->compiled_regex)); |
259 | gl->compiled_regex.translate = case_fold; /* for -i */ | ||
243 | if (re_compile_pattern(gl->pattern, strlen(gl->pattern), &gl->compiled_regex)) | 260 | if (re_compile_pattern(gl->pattern, strlen(gl->pattern), &gl->compiled_regex)) |
244 | bb_error_msg_and_die("bad regex '%s'", gl->pattern); | 261 | bb_error_msg_and_die("bad regex '%s'", gl->pattern); |
245 | #endif | 262 | #endif |
@@ -532,17 +549,34 @@ int grep_main(int argc, char **argv) | |||
532 | if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f') | 549 | if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f') |
533 | option_mask32 |= OPT_F; | 550 | option_mask32 |= OPT_F; |
534 | 551 | ||
552 | #if !ENABLE_EXTRA_COMPAT | ||
535 | if (!(option_mask32 & (OPT_o | OPT_w))) | 553 | if (!(option_mask32 & (OPT_o | OPT_w))) |
536 | reflags = REG_NOSUB; | 554 | reflags = REG_NOSUB; |
555 | #endif | ||
537 | 556 | ||
538 | if (ENABLE_FEATURE_GREP_EGREP_ALIAS | 557 | if (ENABLE_FEATURE_GREP_EGREP_ALIAS |
539 | && (applet_name[0] == 'e' || (option_mask32 & OPT_E)) | 558 | && (applet_name[0] == 'e' || (option_mask32 & OPT_E)) |
540 | ) { | 559 | ) { |
541 | reflags |= REG_EXTENDED; | 560 | reflags |= REG_EXTENDED; |
542 | } | 561 | } |
562 | #if ENABLE_EXTRA_COMPAT | ||
563 | else { | ||
564 | reflags = RE_SYNTAX_GREP; | ||
565 | } | ||
566 | #endif | ||
543 | 567 | ||
544 | if (option_mask32 & OPT_i) | 568 | if (option_mask32 & OPT_i) { |
569 | #if !ENABLE_EXTRA_COMPAT | ||
545 | reflags |= REG_ICASE; | 570 | reflags |= REG_ICASE; |
571 | #else | ||
572 | int i; | ||
573 | case_fold = xmalloc(256); | ||
574 | for (i = 0; i < 256; i++) | ||
575 | case_fold[i] = (unsigned char)i; | ||
576 | for (i = 'a'; i <= 'z'; i++) | ||
577 | case_fold[i] = (unsigned char)(i - ('a' - 'A')); | ||
578 | #endif | ||
579 | } | ||
546 | 580 | ||
547 | argv += optind; | 581 | argv += optind; |
548 | argc -= optind; | 582 | argc -= optind; |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index a68e5a3c0..c2c3ea996 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -956,24 +956,33 @@ static void input_tab(smallint *lastWasTab) | |||
956 | 956 | ||
957 | #if MAX_HISTORY > 0 | 957 | #if MAX_HISTORY > 0 |
958 | 958 | ||
959 | static void save_command_ps_at_cur_history(void) | ||
960 | { | ||
961 | if (command_ps[0] != '\0') { | ||
962 | int cur = state->cur_history; | ||
963 | free(state->history[cur]); | ||
964 | state->history[cur] = xstrdup(command_ps); | ||
965 | } | ||
966 | } | ||
967 | |||
959 | /* state->flags is already checked to be nonzero */ | 968 | /* state->flags is already checked to be nonzero */ |
960 | static void get_previous_history(void) | 969 | static int get_previous_history(void) |
961 | { | 970 | { |
962 | if (command_ps[0] != '\0' || state->history[state->cur_history] == NULL) { | 971 | if ((state->flags & DO_HISTORY) && state->cur_history) { |
963 | free(state->history[state->cur_history]); | 972 | save_command_ps_at_cur_history(); |
964 | state->history[state->cur_history] = xstrdup(command_ps); | 973 | state->cur_history--; |
974 | return 1; | ||
965 | } | 975 | } |
966 | state->cur_history--; | 976 | beep(); |
977 | return 0; | ||
967 | } | 978 | } |
968 | 979 | ||
969 | static int get_next_history(void) | 980 | static int get_next_history(void) |
970 | { | 981 | { |
971 | if (state->flags & DO_HISTORY) { | 982 | if (state->flags & DO_HISTORY) { |
972 | int ch = state->cur_history; | 983 | if (state->cur_history < state->cnt_history) { |
973 | if (ch < state->cnt_history) { | 984 | save_command_ps_at_cur_history(); /* save the current history line */ |
974 | get_previous_history(); /* save the current history line */ | 985 | return ++state->cur_history; |
975 | state->cur_history = ch + 1; | ||
976 | return state->cur_history; | ||
977 | } | 986 | } |
978 | } | 987 | } |
979 | beep(); | 988 | beep(); |
@@ -995,6 +1004,7 @@ static void load_history(const char *fromfile) | |||
995 | for (hi = state->cnt_history; hi > 0;) { | 1004 | for (hi = state->cnt_history; hi > 0;) { |
996 | hi--; | 1005 | hi--; |
997 | free(state->history[hi]); | 1006 | free(state->history[hi]); |
1007 | state->history[hi] = NULL; | ||
998 | } | 1008 | } |
999 | 1009 | ||
1000 | for (hi = 0; hi < MAX_HISTORY;) { | 1010 | for (hi = 0; hi < MAX_HISTORY;) { |
@@ -1006,14 +1016,14 @@ static void load_history(const char *fromfile) | |||
1006 | l = strlen(hl); | 1016 | l = strlen(hl); |
1007 | if (l >= MAX_LINELEN) | 1017 | if (l >= MAX_LINELEN) |
1008 | hl[MAX_LINELEN-1] = '\0'; | 1018 | hl[MAX_LINELEN-1] = '\0'; |
1009 | if (l == 0 || hl[0] == ' ') { | 1019 | if (l == 0) { |
1010 | free(hl); | 1020 | free(hl); |
1011 | continue; | 1021 | continue; |
1012 | } | 1022 | } |
1013 | state->history[hi++] = hl; | 1023 | state->history[hi++] = hl; |
1014 | } | 1024 | } |
1015 | fclose(fp); | 1025 | fclose(fp); |
1016 | state->cur_history = state->cnt_history = hi; | 1026 | state->cnt_history = hi; |
1017 | } | 1027 | } |
1018 | } | 1028 | } |
1019 | 1029 | ||
@@ -1043,19 +1053,27 @@ static void remember_in_history(const char *str) | |||
1043 | 1053 | ||
1044 | if (!(state->flags & DO_HISTORY)) | 1054 | if (!(state->flags & DO_HISTORY)) |
1045 | return; | 1055 | return; |
1046 | 1056 | if (str[0] == '\0') | |
1057 | return; | ||
1047 | i = state->cnt_history; | 1058 | i = state->cnt_history; |
1048 | free(state->history[MAX_HISTORY]); | 1059 | /* Don't save dupes */ |
1049 | state->history[MAX_HISTORY] = NULL; | 1060 | if (i && strcmp(state->history[i-1], str) == 0) |
1050 | /* After max history, remove the oldest command */ | 1061 | return; |
1062 | |||
1063 | free(state->history[MAX_HISTORY]); /* redundant, paranoia */ | ||
1064 | state->history[MAX_HISTORY] = NULL; /* redundant, paranoia */ | ||
1065 | |||
1066 | /* If history[] is full, remove the oldest command */ | ||
1067 | /* we need to keep history[MAX_HISTORY] empty, hence >=, not > */ | ||
1051 | if (i >= MAX_HISTORY) { | 1068 | if (i >= MAX_HISTORY) { |
1052 | free(state->history[0]); | 1069 | free(state->history[0]); |
1053 | for (i = 0; i < MAX_HISTORY-1; i++) | 1070 | for (i = 0; i < MAX_HISTORY-1; i++) |
1054 | state->history[i] = state->history[i+1]; | 1071 | state->history[i] = state->history[i+1]; |
1072 | /* i == MAX_HISTORY-1 */ | ||
1055 | } | 1073 | } |
1056 | // Maybe "if (!i || strcmp(history[i-1], command) != 0) ..." | 1074 | /* i <= MAX_HISTORY-1 */ |
1057 | // (i.e. do not save dups?) | ||
1058 | state->history[i++] = xstrdup(str); | 1075 | state->history[i++] = xstrdup(str); |
1076 | /* i <= MAX_HISTORY */ | ||
1059 | state->cur_history = i; | 1077 | state->cur_history = i; |
1060 | state->cnt_history = i; | 1078 | state->cnt_history = i; |
1061 | #if ENABLE_FEATURE_EDITING_SAVEHISTORY | 1079 | #if ENABLE_FEATURE_EDITING_SAVEHISTORY |
@@ -1397,6 +1415,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
1397 | if ((state->flags & SAVE_HISTORY) && state->hist_file) | 1415 | if ((state->flags & SAVE_HISTORY) && state->hist_file) |
1398 | load_history(state->hist_file); | 1416 | load_history(state->hist_file); |
1399 | #endif | 1417 | #endif |
1418 | state->cur_history = state->cnt_history; | ||
1400 | 1419 | ||
1401 | /* prepare before init handlers */ | 1420 | /* prepare before init handlers */ |
1402 | cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ | 1421 | cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ |
@@ -1432,6 +1451,13 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
1432 | } | 1451 | } |
1433 | } | 1452 | } |
1434 | #endif | 1453 | #endif |
1454 | |||
1455 | #if 0 | ||
1456 | for (ic = 0; ic <= MAX_HISTORY; ic++) | ||
1457 | bb_error_msg("history[%d]:'%s'", ic, state->history[ic]); | ||
1458 | bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history); | ||
1459 | #endif | ||
1460 | |||
1435 | /* Print out the command prompt */ | 1461 | /* Print out the command prompt */ |
1436 | parse_and_put_prompt(prompt); | 1462 | parse_and_put_prompt(prompt); |
1437 | 1463 | ||
@@ -1540,11 +1566,8 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
1540 | vi_case(CTRL('P')|vbit:) | 1566 | vi_case(CTRL('P')|vbit:) |
1541 | vi_case('k'|vbit:) | 1567 | vi_case('k'|vbit:) |
1542 | /* Control-p -- Get previous command from history */ | 1568 | /* Control-p -- Get previous command from history */ |
1543 | if ((state->flags & DO_HISTORY) && state->cur_history > 0) { | 1569 | if (get_previous_history()) |
1544 | get_previous_history(); | ||
1545 | goto rewrite_line; | 1570 | goto rewrite_line; |
1546 | } | ||
1547 | beep(); | ||
1548 | break; | 1571 | break; |
1549 | #endif | 1572 | #endif |
1550 | 1573 | ||
@@ -1733,10 +1756,8 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
1733 | #if MAX_HISTORY > 0 | 1756 | #if MAX_HISTORY > 0 |
1734 | case 'A': | 1757 | case 'A': |
1735 | /* Up Arrow -- Get previous command from history */ | 1758 | /* Up Arrow -- Get previous command from history */ |
1736 | if ((state->flags & DO_HISTORY) && state->cur_history > 0) { | 1759 | if (get_previous_history()) |
1737 | get_previous_history(); | ||
1738 | goto rewrite_line; | 1760 | goto rewrite_line; |
1739 | } | ||
1740 | beep(); | 1761 | beep(); |
1741 | break; | 1762 | break; |
1742 | case 'B': | 1763 | case 'B': |
@@ -1746,7 +1767,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
1746 | rewrite_line: | 1767 | rewrite_line: |
1747 | /* Rewrite the line with the selected history item */ | 1768 | /* Rewrite the line with the selected history item */ |
1748 | /* change command */ | 1769 | /* change command */ |
1749 | command_len = strlen(strcpy(command, state->history[state->cur_history])); | 1770 | command_len = strlen(strcpy(command, state->history[state->cur_history] ? : "")); |
1750 | /* redraw and go to eol (bol, in vi */ | 1771 | /* redraw and go to eol (bol, in vi */ |
1751 | redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0); | 1772 | redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0); |
1752 | break; | 1773 | break; |
diff --git a/miscutils/crontab.c b/miscutils/crontab.c index f8662babb..01656cc6e 100644 --- a/miscutils/crontab.c +++ b/miscutils/crontab.c | |||
@@ -93,6 +93,7 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) | |||
93 | char *new_fname; | 93 | char *new_fname; |
94 | char *user_name; /* -u USER */ | 94 | char *user_name; /* -u USER */ |
95 | int fd; | 95 | int fd; |
96 | int src_fd; | ||
96 | int opt_ler; | 97 | int opt_ler; |
97 | 98 | ||
98 | /* file [opts] Replace crontab from file | 99 | /* file [opts] Replace crontab from file |
@@ -144,15 +145,15 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) | |||
144 | bb_show_usage(); | 145 | bb_show_usage(); |
145 | 146 | ||
146 | /* Read replacement file under user's UID/GID/group vector */ | 147 | /* Read replacement file under user's UID/GID/group vector */ |
148 | src_fd = STDIN_FILENO; | ||
147 | if (!opt_ler) { /* Replace? */ | 149 | if (!opt_ler) { /* Replace? */ |
148 | if (!argv[0]) | 150 | if (!argv[0]) |
149 | bb_show_usage(); | 151 | bb_show_usage(); |
150 | if (NOT_LONE_DASH(argv[0])) { | 152 | if (NOT_LONE_DASH(argv[0])) { |
151 | fd = open_as_user(pas, argv[0]); | 153 | src_fd = open_as_user(pas, argv[0]); |
152 | if (fd < 0) | 154 | if (src_fd < 0) |
153 | bb_error_msg_and_die("user %s cannot read %s", | 155 | bb_error_msg_and_die("user %s cannot read %s", |
154 | pas->pw_name, argv[0]); | 156 | pas->pw_name, argv[0]); |
155 | xmove_fd(fd, STDIN_FILENO); | ||
156 | } | 157 | } |
157 | } | 158 | } |
158 | 159 | ||
@@ -180,23 +181,23 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) | |||
180 | tmp_fname = xasprintf("%s.%u", crontab_dir, (unsigned)getpid()); | 181 | tmp_fname = xasprintf("%s.%u", crontab_dir, (unsigned)getpid()); |
181 | /* No O_EXCL: we don't want to be stuck if earlier crontabs | 182 | /* No O_EXCL: we don't want to be stuck if earlier crontabs |
182 | * were killed, leaving stale temp file behind */ | 183 | * were killed, leaving stale temp file behind */ |
183 | fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC, 0600); | 184 | src_fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC, 0600); |
184 | xmove_fd(fd, STDIN_FILENO); | 185 | fchown(src_fd, pas->pw_uid, pas->pw_gid); |
185 | fchown(STDIN_FILENO, pas->pw_uid, pas->pw_gid); | ||
186 | fd = open(pas->pw_name, O_RDONLY); | 186 | fd = open(pas->pw_name, O_RDONLY); |
187 | if (fd >= 0) { | 187 | if (fd >= 0) { |
188 | bb_copyfd_eof(fd, STDIN_FILENO); | 188 | bb_copyfd_eof(fd, src_fd); |
189 | close(fd); | 189 | close(fd); |
190 | xlseek(src_fd, 0, SEEK_SET); | ||
190 | } | 191 | } |
192 | close_on_exec_on(src_fd); /* don't want editor to see this fd */ | ||
191 | edit_file(pas, tmp_fname); | 193 | edit_file(pas, tmp_fname); |
192 | xlseek(STDIN_FILENO, 0, SEEK_SET); | ||
193 | /* fall through */ | 194 | /* fall through */ |
194 | 195 | ||
195 | case 0: /* Replace (no -l, -e, or -r were given) */ | 196 | case 0: /* Replace (no -l, -e, or -r were given) */ |
196 | new_fname = xasprintf("%s.new", pas->pw_name); | 197 | new_fname = xasprintf("%s.new", pas->pw_name); |
197 | fd = open(new_fname, O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, 0600); | 198 | fd = open(new_fname, O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, 0600); |
198 | if (fd >= 0) { | 199 | if (fd >= 0) { |
199 | bb_copyfd_eof(STDIN_FILENO, fd); | 200 | bb_copyfd_eof(src_fd, fd); |
200 | close(fd); | 201 | close(fd); |
201 | xrename(new_fname, pas->pw_name); | 202 | xrename(new_fname, pas->pw_name); |
202 | } else { | 203 | } else { |
diff --git a/modutils/insmod.c b/modutils/insmod.c index 9dcc5b02d..80dbfd78e 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c | |||
@@ -1059,8 +1059,9 @@ arch_apply_relocation(struct obj_file *f, | |||
1059 | 1059 | ||
1060 | case R_68K_PC8: | 1060 | case R_68K_PC8: |
1061 | v -= dot; | 1061 | v -= dot; |
1062 | if ((ElfW(Sword))v > 0x7f || | 1062 | if ((ElfW(Sword))v > 0x7f |
1063 | (ElfW(Sword))v < -(ElfW(Sword))0x80) { | 1063 | || (ElfW(Sword))v < -(ElfW(Sword))0x80 |
1064 | ) { | ||
1064 | ret = obj_reloc_overflow; | 1065 | ret = obj_reloc_overflow; |
1065 | } | 1066 | } |
1066 | *(char *)loc = v; | 1067 | *(char *)loc = v; |
@@ -1068,8 +1069,9 @@ arch_apply_relocation(struct obj_file *f, | |||
1068 | 1069 | ||
1069 | case R_68K_PC16: | 1070 | case R_68K_PC16: |
1070 | v -= dot; | 1071 | v -= dot; |
1071 | if ((ElfW(Sword))v > 0x7fff || | 1072 | if ((ElfW(Sword))v > 0x7fff |
1072 | (ElfW(Sword))v < -(ElfW(Sword))0x8000) { | 1073 | || (ElfW(Sword))v < -(ElfW(Sword))0x8000 |
1074 | ) { | ||
1073 | ret = obj_reloc_overflow; | 1075 | ret = obj_reloc_overflow; |
1074 | } | 1076 | } |
1075 | *(short *)loc = v; | 1077 | *(short *)loc = v; |
@@ -1208,8 +1210,9 @@ arch_apply_relocation(struct obj_file *f, | |||
1208 | { | 1210 | { |
1209 | Elf32_Addr word; | 1211 | Elf32_Addr word; |
1210 | 1212 | ||
1211 | if ((Elf32_Sword)v > 0x7fff || | 1213 | if ((Elf32_Sword)v > 0x7fff |
1212 | (Elf32_Sword)v < -(Elf32_Sword)0x8000) { | 1214 | || (Elf32_Sword)v < -(Elf32_Sword)0x8000 |
1215 | ) { | ||
1213 | ret = obj_reloc_overflow; | 1216 | ret = obj_reloc_overflow; |
1214 | } | 1217 | } |
1215 | 1218 | ||
@@ -1238,8 +1241,9 @@ arch_apply_relocation(struct obj_file *f, | |||
1238 | Elf32_Addr word; | 1241 | Elf32_Addr word; |
1239 | 1242 | ||
1240 | v -= dot + 4; | 1243 | v -= dot + 4; |
1241 | if ((Elf32_Sword)v > 0x7fff || | 1244 | if ((Elf32_Sword)v > 0x7fff |
1242 | (Elf32_Sword)v < -(Elf32_Sword)0x8000) { | 1245 | || (Elf32_Sword)v < -(Elf32_Sword)0x8000 |
1246 | ) { | ||
1243 | ret = obj_reloc_overflow; | 1247 | ret = obj_reloc_overflow; |
1244 | } | 1248 | } |
1245 | 1249 | ||
@@ -1253,9 +1257,10 @@ arch_apply_relocation(struct obj_file *f, | |||
1253 | Elf32_Addr word, gp; | 1257 | Elf32_Addr word, gp; |
1254 | /* get _gp */ | 1258 | /* get _gp */ |
1255 | gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp")); | 1259 | gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp")); |
1256 | v-=gp; | 1260 | v -= gp; |
1257 | if ((Elf32_Sword)v > 0x7fff || | 1261 | if ((Elf32_Sword)v > 0x7fff |
1258 | (Elf32_Sword)v < -(Elf32_Sword)0x8000) { | 1262 | || (Elf32_Sword)v < -(Elf32_Sword)0x8000 |
1263 | ) { | ||
1259 | ret = obj_reloc_overflow; | 1264 | ret = obj_reloc_overflow; |
1260 | } | 1265 | } |
1261 | 1266 | ||
@@ -2132,7 +2137,6 @@ obj_find_symbol(struct obj_file *f, const char *name) | |||
2132 | for (sym = f->symtab[hash]; sym; sym = sym->next) | 2137 | for (sym = f->symtab[hash]; sym; sym = sym->next) |
2133 | if (f->symbol_cmp(sym->name, name) == 0) | 2138 | if (f->symbol_cmp(sym->name, name) == 0) |
2134 | return sym; | 2139 | return sym; |
2135 | |||
2136 | return NULL; | 2140 | return NULL; |
2137 | } | 2141 | } |
2138 | 2142 | ||
@@ -2141,12 +2145,10 @@ static ElfW(Addr) obj_symbol_final_value(struct obj_file * f, struct obj_symbol | |||
2141 | if (sym) { | 2145 | if (sym) { |
2142 | if (sym->secidx >= SHN_LORESERVE) | 2146 | if (sym->secidx >= SHN_LORESERVE) |
2143 | return sym->value; | 2147 | return sym->value; |
2144 | |||
2145 | return sym->value + f->sections[sym->secidx]->header.sh_addr; | 2148 | return sym->value + f->sections[sym->secidx]->header.sh_addr; |
2146 | } else { | ||
2147 | /* As a special case, a NULL sym has value zero. */ | ||
2148 | return 0; | ||
2149 | } | 2149 | } |
2150 | /* As a special case, a NULL sym has value zero. */ | ||
2151 | return 0; | ||
2150 | } | 2152 | } |
2151 | 2153 | ||
2152 | static struct obj_section *obj_find_section(struct obj_file *f, const char *name) | 2154 | static struct obj_section *obj_find_section(struct obj_file *f, const char *name) |
@@ -2156,7 +2158,6 @@ static struct obj_section *obj_find_section(struct obj_file *f, const char *name | |||
2156 | for (i = 0; i < n; ++i) | 2158 | for (i = 0; i < n; ++i) |
2157 | if (strcmp(f->sections[i]->name, name) == 0) | 2159 | if (strcmp(f->sections[i]->name, name) == 0) |
2158 | return f->sections[i]; | 2160 | return f->sections[i]; |
2159 | |||
2160 | return NULL; | 2161 | return NULL; |
2161 | } | 2162 | } |
2162 | 2163 | ||
@@ -2167,9 +2168,11 @@ static int obj_load_order_prio(struct obj_section *a) | |||
2167 | af = a->header.sh_flags; | 2168 | af = a->header.sh_flags; |
2168 | 2169 | ||
2169 | ac = 0; | 2170 | ac = 0; |
2170 | if (a->name[0] != '.' || strlen(a->name) != 10 || | 2171 | if (a->name[0] != '.' || strlen(a->name) != 10 |
2171 | strcmp(a->name + 5, ".init")) | 2172 | || strcmp(a->name + 5, ".init") != 0 |
2173 | ) { | ||
2172 | ac |= 32; | 2174 | ac |= 32; |
2175 | } | ||
2173 | if (af & SHF_ALLOC) | 2176 | if (af & SHF_ALLOC) |
2174 | ac |= 16; | 2177 | ac |= 16; |
2175 | if (!(af & SHF_WRITE)) | 2178 | if (!(af & SHF_WRITE)) |
@@ -2212,7 +2215,7 @@ static struct obj_section *obj_create_alloced_section(struct obj_file *f, | |||
2212 | sec->name = name; | 2215 | sec->name = name; |
2213 | sec->idx = newidx; | 2216 | sec->idx = newidx; |
2214 | if (size) | 2217 | if (size) |
2215 | sec->contents = xmalloc(size); | 2218 | sec->contents = xzalloc(size); |
2216 | 2219 | ||
2217 | obj_insert_section_load_order(f, sec); | 2220 | obj_insert_section_load_order(f, sec); |
2218 | 2221 | ||
@@ -2227,7 +2230,7 @@ static struct obj_section *obj_create_alloced_section_first(struct obj_file *f, | |||
2227 | int newidx = f->header.e_shnum++; | 2230 | int newidx = f->header.e_shnum++; |
2228 | struct obj_section *sec; | 2231 | struct obj_section *sec; |
2229 | 2232 | ||
2230 | f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); | 2233 | f->sections = xrealloc_vector(f->sections, 2, newidx); |
2231 | f->sections[newidx] = sec = arch_new_section(); | 2234 | f->sections[newidx] = sec = arch_new_section(); |
2232 | 2235 | ||
2233 | sec->header.sh_type = SHT_PROGBITS; | 2236 | sec->header.sh_type = SHT_PROGBITS; |
@@ -2237,7 +2240,7 @@ static struct obj_section *obj_create_alloced_section_first(struct obj_file *f, | |||
2237 | sec->name = name; | 2240 | sec->name = name; |
2238 | sec->idx = newidx; | 2241 | sec->idx = newidx; |
2239 | if (size) | 2242 | if (size) |
2240 | sec->contents = xmalloc(size); | 2243 | sec->contents = xzalloc(size); |
2241 | 2244 | ||
2242 | sec->load_next = f->load_order; | 2245 | sec->load_next = f->load_order; |
2243 | f->load_order = sec; | 2246 | f->load_order = sec; |
@@ -2689,8 +2692,7 @@ static void new_get_kernel_symbols(void) | |||
2689 | /* Collect the modules' symbols. */ | 2692 | /* Collect the modules' symbols. */ |
2690 | 2693 | ||
2691 | if (nmod) { | 2694 | if (nmod) { |
2692 | ext_modules = modules = xmalloc(nmod * sizeof(*modules)); | 2695 | ext_modules = modules = xzalloc(nmod * sizeof(*modules)); |
2693 | memset(modules, 0, nmod * sizeof(*modules)); | ||
2694 | for (i = 0, mn = module_names, m = modules; | 2696 | for (i = 0, mn = module_names, m = modules; |
2695 | i < nmod; ++i, ++m, mn += strlen(mn) + 1) { | 2697 | i < nmod; ++i, ++m, mn += strlen(mn) + 1) { |
2696 | struct new_module_info info; | 2698 | struct new_module_info info; |
@@ -2770,13 +2772,14 @@ static int new_is_kernel_checksummed(void) | |||
2770 | } | 2772 | } |
2771 | 2773 | ||
2772 | 2774 | ||
2773 | static void new_create_this_module(struct obj_file *f, const char *m_name) | 2775 | static void new_create_this_module(struct obj_file *f, const char *m_name) |
2774 | { | 2776 | { |
2775 | struct obj_section *sec; | 2777 | struct obj_section *sec; |
2776 | 2778 | ||
2777 | sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long, | 2779 | sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long, |
2778 | sizeof(struct new_module)); | 2780 | sizeof(struct new_module)); |
2779 | memset(sec->contents, 0, sizeof(struct new_module)); | 2781 | /* done by obj_create_alloced_section_first: */ |
2782 | /*memset(sec->contents, 0, sizeof(struct new_module));*/ | ||
2780 | 2783 | ||
2781 | obj_add_symbol(f, SPFX "__this_module", -1, | 2784 | obj_add_symbol(f, SPFX "__this_module", -1, |
2782 | ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0, | 2785 | ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0, |
@@ -2856,18 +2859,19 @@ static int new_create_module_ksymtab(struct obj_file *f) | |||
2856 | /* We don't want to export symbols residing in sections that | 2859 | /* We don't want to export symbols residing in sections that |
2857 | aren't loaded. There are a number of these created so that | 2860 | aren't loaded. There are a number of these created so that |
2858 | we make sure certain module options don't appear twice. */ | 2861 | we make sure certain module options don't appear twice. */ |
2859 | 2862 | i = f->header.e_shnum; | |
2860 | loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); | 2863 | loaded = alloca(sizeof(int) * i); |
2861 | while (--i >= 0) | 2864 | while (--i >= 0) |
2862 | loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; | 2865 | loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; |
2863 | 2866 | ||
2864 | for (nsyms = i = 0; i < HASH_BUCKETS; ++i) { | 2867 | for (nsyms = i = 0; i < HASH_BUCKETS; ++i) { |
2865 | struct obj_symbol *sym; | 2868 | struct obj_symbol *sym; |
2866 | for (sym = f->symtab[i]; sym; sym = sym->next) | 2869 | for (sym = f->symtab[i]; sym; sym = sym->next) { |
2867 | if (ELF_ST_BIND(sym->info) != STB_LOCAL | 2870 | if (ELF_ST_BIND(sym->info) != STB_LOCAL |
2868 | && sym->secidx <= SHN_HIRESERVE | 2871 | && sym->secidx <= SHN_HIRESERVE |
2869 | && (sym->secidx >= SHN_LORESERVE | 2872 | && (sym->secidx >= SHN_LORESERVE |
2870 | || loaded[sym->secidx])) { | 2873 | || loaded[sym->secidx]) |
2874 | ) { | ||
2871 | ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p; | 2875 | ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p; |
2872 | 2876 | ||
2873 | obj_symbol_patch(f, sec->idx, ofs, sym); | 2877 | obj_symbol_patch(f, sec->idx, ofs, sym); |
@@ -2876,6 +2880,7 @@ static int new_create_module_ksymtab(struct obj_file *f) | |||
2876 | 2880 | ||
2877 | nsyms++; | 2881 | nsyms++; |
2878 | } | 2882 | } |
2883 | } | ||
2879 | } | 2884 | } |
2880 | 2885 | ||
2881 | obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p); | 2886 | obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p); |
@@ -2934,9 +2939,11 @@ new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size) | |||
2934 | } | 2939 | } |
2935 | sec = obj_find_section(f, ".data.init"); | 2940 | sec = obj_find_section(f, ".data.init"); |
2936 | if (sec) { | 2941 | if (sec) { |
2937 | if (!module->runsize || | 2942 | if (!module->runsize |
2938 | module->runsize > sec->header.sh_addr - m_addr) | 2943 | || module->runsize > sec->header.sh_addr - m_addr |
2944 | ) { | ||
2939 | module->runsize = sec->header.sh_addr - m_addr; | 2945 | module->runsize = sec->header.sh_addr - m_addr; |
2946 | } | ||
2940 | } | 2947 | } |
2941 | sec = obj_find_section(f, ARCHDATA_SEC_NAME); | 2948 | sec = obj_find_section(f, ARCHDATA_SEC_NAME); |
2942 | if (sec && sec->header.sh_size) { | 2949 | if (sec && sec->header.sh_size) { |
@@ -3083,9 +3090,9 @@ static void obj_allocate_commons(struct obj_file *f) | |||
3083 | if (i == f->header.e_shnum) { | 3090 | if (i == f->header.e_shnum) { |
3084 | struct obj_section *sec; | 3091 | struct obj_section *sec; |
3085 | 3092 | ||
3093 | f->header.e_shnum++; | ||
3086 | f->sections = xrealloc_vector(f->sections, 2, i); | 3094 | f->sections = xrealloc_vector(f->sections, 2, i); |
3087 | f->sections[i] = sec = arch_new_section(); | 3095 | f->sections[i] = sec = arch_new_section(); |
3088 | f->header.e_shnum = i + 1; | ||
3089 | 3096 | ||
3090 | sec->header.sh_type = SHT_PROGBITS; | 3097 | sec->header.sh_type = SHT_PROGBITS; |
3091 | sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; | 3098 | sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; |
@@ -3124,12 +3131,9 @@ static void obj_allocate_commons(struct obj_file *f) | |||
3124 | for (i = 0; i < f->header.e_shnum; ++i) { | 3131 | for (i = 0; i < f->header.e_shnum; ++i) { |
3125 | struct obj_section *s = f->sections[i]; | 3132 | struct obj_section *s = f->sections[i]; |
3126 | if (s->header.sh_type == SHT_NOBITS) { | 3133 | if (s->header.sh_type == SHT_NOBITS) { |
3134 | s->contents = NULL; | ||
3127 | if (s->header.sh_size != 0) | 3135 | if (s->header.sh_size != 0) |
3128 | s->contents = memset(xmalloc(s->header.sh_size), | 3136 | s->contents = xzalloc(s->header.sh_size), |
3129 | 0, s->header.sh_size); | ||
3130 | else | ||
3131 | s->contents = NULL; | ||
3132 | |||
3133 | s->header.sh_type = SHT_PROGBITS; | 3137 | s->header.sh_type = SHT_PROGBITS; |
3134 | } | 3138 | } |
3135 | } | 3139 | } |
@@ -3222,8 +3226,8 @@ static int obj_relocate(struct obj_file *f, ElfW(Addr) base) | |||
3222 | #if SHT_RELM == SHT_RELA | 3226 | #if SHT_RELM == SHT_RELA |
3223 | #if defined(__alpha__) && defined(AXP_BROKEN_GAS) | 3227 | #if defined(__alpha__) && defined(AXP_BROKEN_GAS) |
3224 | /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ | 3228 | /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ |
3225 | if (!extsym || !extsym->st_name || | 3229 | if (!extsym || !extsym->st_name |
3226 | ELF_ST_BIND(extsym->st_info) != STB_LOCAL) | 3230 | || ELF_ST_BIND(extsym->st_info) != STB_LOCAL) |
3227 | #endif | 3231 | #endif |
3228 | value += rel->r_addend; | 3232 | value += rel->r_addend; |
3229 | #endif | 3233 | #endif |
@@ -3329,16 +3333,17 @@ static struct obj_file *obj_load(FILE *fp, int loadprogbits UNUSED_PARAM) | |||
3329 | } | 3333 | } |
3330 | 3334 | ||
3331 | if (f->header.e_ident[EI_MAG0] != ELFMAG0 | 3335 | if (f->header.e_ident[EI_MAG0] != ELFMAG0 |
3332 | || f->header.e_ident[EI_MAG1] != ELFMAG1 | 3336 | || f->header.e_ident[EI_MAG1] != ELFMAG1 |
3333 | || f->header.e_ident[EI_MAG2] != ELFMAG2 | 3337 | || f->header.e_ident[EI_MAG2] != ELFMAG2 |
3334 | || f->header.e_ident[EI_MAG3] != ELFMAG3) { | 3338 | || f->header.e_ident[EI_MAG3] != ELFMAG3 |
3339 | ) { | ||
3335 | bb_error_msg_and_die("not an ELF file"); | 3340 | bb_error_msg_and_die("not an ELF file"); |
3336 | } | 3341 | } |
3337 | if (f->header.e_ident[EI_CLASS] != ELFCLASSM | 3342 | if (f->header.e_ident[EI_CLASS] != ELFCLASSM |
3338 | || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN | 3343 | || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB) |
3339 | ? ELFDATA2MSB : ELFDATA2LSB) | 3344 | || f->header.e_ident[EI_VERSION] != EV_CURRENT |
3340 | || f->header.e_ident[EI_VERSION] != EV_CURRENT | 3345 | || !MATCH_MACHINE(f->header.e_machine) |
3341 | || !MATCH_MACHINE(f->header.e_machine)) { | 3346 | ) { |
3342 | bb_error_msg_and_die("ELF file not for this architecture"); | 3347 | bb_error_msg_and_die("ELF file not for this architecture"); |
3343 | } | 3348 | } |
3344 | if (f->header.e_type != ET_REL) { | 3349 | if (f->header.e_type != ET_REL) { |
@@ -3354,8 +3359,10 @@ static struct obj_file *obj_load(FILE *fp, int loadprogbits UNUSED_PARAM) | |||
3354 | } | 3359 | } |
3355 | 3360 | ||
3356 | shnum = f->header.e_shnum; | 3361 | shnum = f->header.e_shnum; |
3357 | f->sections = xmalloc(sizeof(struct obj_section *) * shnum); | 3362 | /* Growth of ->sections vector will be done by |
3358 | memset(f->sections, 0, sizeof(struct obj_section *) * shnum); | 3363 | * xrealloc_vector(..., 2, ...), therefore we must allocate |
3364 | * at least 2^2 = 4 extra elements here. */ | ||
3365 | f->sections = xzalloc(sizeof(f->sections[0]) * (shnum + 4)); | ||
3359 | 3366 | ||
3360 | section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); | 3367 | section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); |
3361 | fseek(fp, f->header.e_shoff, SEEK_SET); | 3368 | fseek(fp, f->header.e_shoff, SEEK_SET); |
@@ -3391,14 +3398,13 @@ static struct obj_file *obj_load(FILE *fp, int loadprogbits UNUSED_PARAM) | |||
3391 | case SHT_SYMTAB: | 3398 | case SHT_SYMTAB: |
3392 | case SHT_STRTAB: | 3399 | case SHT_STRTAB: |
3393 | case SHT_RELM: | 3400 | case SHT_RELM: |
3401 | sec->contents = NULL; | ||
3394 | if (sec->header.sh_size > 0) { | 3402 | if (sec->header.sh_size > 0) { |
3395 | sec->contents = xmalloc(sec->header.sh_size); | 3403 | sec->contents = xzalloc(sec->header.sh_size); |
3396 | fseek(fp, sec->header.sh_offset, SEEK_SET); | 3404 | fseek(fp, sec->header.sh_offset, SEEK_SET); |
3397 | if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { | 3405 | if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { |
3398 | bb_perror_msg_and_die("error reading ELF section data"); | 3406 | bb_perror_msg_and_die("error reading ELF section data"); |
3399 | } | 3407 | } |
3400 | } else { | ||
3401 | sec->contents = NULL; | ||
3402 | } | 3408 | } |
3403 | break; | 3409 | break; |
3404 | 3410 | ||
@@ -3860,16 +3866,20 @@ static void print_load_map(struct obj_file *f) | |||
3860 | for (nsyms = i = 0; i < HASH_BUCKETS; ++i) | 3866 | for (nsyms = i = 0; i < HASH_BUCKETS; ++i) |
3861 | for (sym = f->symtab[i]; sym; sym = sym->next) | 3867 | for (sym = f->symtab[i]; sym; sym = sym->next) |
3862 | if (sym->secidx <= SHN_HIRESERVE | 3868 | if (sym->secidx <= SHN_HIRESERVE |
3863 | && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])) | 3869 | && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]) |
3870 | ) { | ||
3864 | ++nsyms; | 3871 | ++nsyms; |
3872 | } | ||
3865 | 3873 | ||
3866 | all = alloca(nsyms * sizeof(struct obj_symbol *)); | 3874 | all = alloca(nsyms * sizeof(struct obj_symbol *)); |
3867 | 3875 | ||
3868 | for (i = 0, p = all; i < HASH_BUCKETS; ++i) | 3876 | for (i = 0, p = all; i < HASH_BUCKETS; ++i) |
3869 | for (sym = f->symtab[i]; sym; sym = sym->next) | 3877 | for (sym = f->symtab[i]; sym; sym = sym->next) |
3870 | if (sym->secidx <= SHN_HIRESERVE | 3878 | if (sym->secidx <= SHN_HIRESERVE |
3871 | && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])) | 3879 | && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]) |
3880 | ) { | ||
3872 | *p++ = sym; | 3881 | *p++ = sym; |
3882 | } | ||
3873 | 3883 | ||
3874 | /* And list them. */ | 3884 | /* And list them. */ |
3875 | printf("\nSymbols:\n"); | 3885 | printf("\nSymbols:\n"); |
@@ -4265,7 +4275,7 @@ static int insmod_ng_main(int argc UNUSED_PARAM, char **argv) | |||
4265 | } | 4275 | } |
4266 | #else | 4276 | #else |
4267 | len = MAXINT(ssize_t); | 4277 | len = MAXINT(ssize_t); |
4268 | map = xmalloc_open_read_close(filename, &len); | 4278 | map = xmalloc_xopen_read_close(filename, &len); |
4269 | #endif | 4279 | #endif |
4270 | 4280 | ||
4271 | if (init_module(map, len, options) != 0) | 4281 | if (init_module(map, len, options) != 0) |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 5caa00c83..92ebe3676 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -259,9 +259,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
259 | if (opt & OPT_o) | 259 | if (opt & OPT_o) |
260 | client_config.no_default_options = 1; | 260 | client_config.no_default_options = 1; |
261 | while (list_O) { | 261 | while (list_O) { |
262 | int n = index_in_strings(dhcp_option_strings, llist_pop(&list_O)); | 262 | char *optstr = llist_pop(&list_O); |
263 | int n = index_in_strings(dhcp_option_strings, optstr); | ||
263 | if (n < 0) | 264 | if (n < 0) |
264 | bb_error_msg_and_die("unknown option '%s'", list_O->data); | 265 | bb_error_msg_and_die("unknown option '%s'", optstr); |
265 | n = dhcp_options[n].code; | 266 | n = dhcp_options[n].code; |
266 | client_config.opt_mask[n >> 3] |= 1 << (n & 7); | 267 | client_config.opt_mask[n >> 3] |= 1 << (n & 7); |
267 | } | 268 | } |
diff --git a/procps/top.c b/procps/top.c index 663eac674..46e29a9dd 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -745,7 +745,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
745 | int iterations; | 745 | int iterations; |
746 | unsigned lines, col; | 746 | unsigned lines, col; |
747 | unsigned interval; | 747 | unsigned interval; |
748 | char *sinterval; | 748 | char *str_interval, *str_iterations; |
749 | SKIP_FEATURE_TOPMEM(const) unsigned scan_mask = TOP_MASK; | 749 | SKIP_FEATURE_TOPMEM(const) unsigned scan_mask = TOP_MASK; |
750 | #if ENABLE_FEATURE_USE_TERMIOS | 750 | #if ENABLE_FEATURE_USE_TERMIOS |
751 | struct termios new_settings; | 751 | struct termios new_settings; |
@@ -762,10 +762,19 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
762 | iterations = 0; /* infinite */ | 762 | iterations = 0; /* infinite */ |
763 | 763 | ||
764 | /* all args are options; -n NUM */ | 764 | /* all args are options; -n NUM */ |
765 | opt_complementary = "-:n+"; | 765 | opt_complementary = "-"; |
766 | if (getopt32(argv, "d:n:b", &sinterval, &iterations) & OPT_d) { | 766 | col = getopt32(argv, "d:n:b", &str_interval, &str_iterations); |
767 | if (col & OPT_d) { | ||
768 | /* work around for "-d 1" -> "-d -1" done by getopt32 */ | ||
769 | if (str_interval[0] == '-') | ||
770 | str_interval++; | ||
767 | /* Need to limit it to not overflow poll timeout */ | 771 | /* Need to limit it to not overflow poll timeout */ |
768 | interval = xatou16(sinterval); // -d | 772 | interval = xatou16(str_interval); |
773 | } | ||
774 | if (col & OPT_n) { | ||
775 | if (str_iterations[0] == '-') | ||
776 | str_iterations++; | ||
777 | iterations = xatou(str_iterations); | ||
769 | } | 778 | } |
770 | 779 | ||
771 | /* change to /proc */ | 780 | /* change to /proc */ |