From dc9c10a7b29c93a36ff17c562cb14e11eb169f19 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 16 Nov 2020 13:00:44 +0100 Subject: hush: make interactive ^C break out of PS2 mode function old new delta syntax_error_unterm_str - 26 +26 parse_stream 2238 2251 +13 fgetc_interactive 243 249 +6 parse_dollar 824 817 -7 syntax_error_unterm_ch 29 21 -8 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/2 up/down: 45/-15) Total: 30 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 86 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 35 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index ab7263381..f1a7e07ee 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -916,6 +916,9 @@ struct globals { char opt_c; #if ENABLE_HUSH_INTERACTIVE smallint promptmode; /* 0: PS1, 1: PS2 */ +# if ENABLE_FEATURE_EDITING + smallint flag_ctrlC; /* when set, suppresses syntax error messages */ +# endif #endif smallint flag_SIGINT; #if ENABLE_HUSH_LOOPS @@ -1425,7 +1428,10 @@ static void syntax_error_at(unsigned lineno UNUSED_PARAM, const char *msg) static void syntax_error_unterm_str(unsigned lineno UNUSED_PARAM, const char *s) { - bb_error_msg("syntax error: unterminated %s", s); +#if ENABLE_FEATURE_EDITING + if (!G.flag_ctrlC) +#endif + bb_error_msg("syntax error: unterminated %s", s); //? source4.tests fails: in bash, echo ${^} in script does not terminate the script // die_if_script(); } @@ -2629,26 +2635,27 @@ static int get_user_input(struct in_str *i) # if ENABLE_FEATURE_EDITING for (;;) { reinit_unicode_for_hush(); - if (G.flag_SIGINT) { - /* There was ^C'ed, make it look prettier: */ - bb_putchar('\n'); - G.flag_SIGINT = 0; - } + G.flag_SIGINT = 0; /* buglet: SIGINT will not make new prompt to appear _at once_, * only after . (^C works immediately) */ r = read_line_input(G.line_input_state, prompt_str, G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1 ); /* read_line_input intercepts ^C, "convert" it to SIGINT */ - if (r == 0) + if (r == 0) { + G.flag_ctrlC = 1; raise(SIGINT); + } check_and_run_traps(); if (r != 0 && !G.flag_SIGINT) break; - /* ^C or SIGINT: repeat */ + /* ^C or SIGINT: return EOF */ /* bash prints ^C even on real SIGINT (non-kbd generated) */ - write(STDOUT_FILENO, "^C", 2); + write(STDOUT_FILENO, "^C\n", 3); G.last_exitcode = 128 + SIGINT; + i->p = NULL; + i->peek_buf[0] = r = EOF; + return r; } if (r < 0) { /* EOF/error detected */ @@ -5260,22 +5267,31 @@ static struct pipe *parse_stream(char **pstring, ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); if (ch == EOF) { struct pipe *pi; - +#if ENABLE_FEATURE_EDITING + if (G.flag_ctrlC) { + /* testcase: interactively entering + * 'qwe ^C + * should not leave input in PS2 mode, waiting to close single quote. + */ + G.flag_ctrlC = 0; + goto parse_error; + } +#endif if (heredoc_cnt) { syntax_error_unterm_str("here document"); - goto parse_error; + goto parse_error_exitcode1; } if (end_trigger == ')') { syntax_error_unterm_ch('('); - goto parse_error; + goto parse_error_exitcode1; } if (end_trigger == '}') { syntax_error_unterm_ch('{'); - goto parse_error; + goto parse_error_exitcode1; } if (done_word(&ctx)) { - goto parse_error; + goto parse_error_exitcode1; } o_free_and_set_NULL(&ctx.word); done_pipe(&ctx, PIPE_SEQ); @@ -5345,7 +5361,7 @@ static struct pipe *parse_stream(char **pstring, while (1) { if (ch == EOF) { syntax_error_unterm_ch('\''); - goto parse_error; + goto parse_error_exitcode1; } nommu_addchr(&ctx.as_string, ch); if (ch == '\'') @@ -5424,7 +5440,7 @@ static struct pipe *parse_stream(char **pstring, /* ch == last eaten whitespace char */ #endif if (done_word(&ctx)) { - goto parse_error; + goto parse_error_exitcode1; } if (ch == '\n') { /* Is this a case when newline is simply ignored? @@ -5467,7 +5483,7 @@ static struct pipe *parse_stream(char **pstring, if (heredoc_cnt) { heredoc_cnt = fetch_heredocs(&ctx.as_string, ctx.list_head, heredoc_cnt, input); if (heredoc_cnt != 0) - goto parse_error; + goto parse_error_exitcode1; } ctx.is_assignment = MAYBE_ASSIGNMENT; debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]); @@ -5517,7 +5533,7 @@ static struct pipe *parse_stream(char **pstring, #endif ) { if (done_word(&ctx)) { - goto parse_error; + goto parse_error_exitcode1; } done_pipe(&ctx, PIPE_SEQ); ctx.is_assignment = MAYBE_ASSIGNMENT; @@ -5538,7 +5554,7 @@ static struct pipe *parse_stream(char **pstring, /* Example: bare "{ }", "()" */ G.last_exitcode = 2; /* bash compat */ syntax_error_unexpected_ch(ch); - goto parse_error2; + goto parse_error; } if (heredoc_cnt_ptr) *heredoc_cnt_ptr = heredoc_cnt; @@ -5560,7 +5576,7 @@ static struct pipe *parse_stream(char **pstring, case '>': redir_fd = redirect_opt_num(&ctx.word); if (done_word(&ctx)) { - goto parse_error; + goto parse_error_exitcode1; } redir_style = REDIRECT_OVERWRITE; if (next == '>') { @@ -5571,16 +5587,16 @@ static struct pipe *parse_stream(char **pstring, #if 0 else if (next == '(') { syntax_error(">(process) not supported"); - goto parse_error; + goto parse_error_exitcode1; } #endif if (parse_redirect(&ctx, redir_fd, redir_style, input)) - goto parse_error; + goto parse_error_exitcode1; continue; /* get next char */ case '<': redir_fd = redirect_opt_num(&ctx.word); if (done_word(&ctx)) { - goto parse_error; + goto parse_error_exitcode1; } redir_style = REDIRECT_INPUT; if (next == '<') { @@ -5597,11 +5613,11 @@ static struct pipe *parse_stream(char **pstring, #if 0 else if (next == '(') { syntax_error("<(process) not supported"); - goto parse_error; + goto parse_error_exitcode1; } #endif if (parse_redirect(&ctx, redir_fd, redir_style, input)) - goto parse_error; + goto parse_error_exitcode1; continue; /* get next char */ case '#': if (ctx.word.length == 0 && !ctx.word.has_quoted_part) { @@ -5655,7 +5671,7 @@ static struct pipe *parse_stream(char **pstring, if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) { debug_printf_parse("parse_stream parse error: " "parse_dollar returned 0 (error)\n"); - goto parse_error; + goto parse_error_exitcode1; } continue; /* get next char */ case '"': @@ -5671,7 +5687,7 @@ static struct pipe *parse_stream(char **pstring, if (ctx.is_assignment == NOT_ASSIGNMENT) ctx.word.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS; if (!encode_string(&ctx.as_string, &ctx.word, input, '"')) - goto parse_error; + goto parse_error_exitcode1; ctx.word.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS; continue; /* get next char */ #if ENABLE_HUSH_TICK @@ -5682,7 +5698,7 @@ static struct pipe *parse_stream(char **pstring, o_addchr(&ctx.word, '`'); USE_FOR_NOMMU(pos = ctx.word.length;) if (!add_till_backquote(&ctx.word, input, /*in_dquote:*/ 0)) - goto parse_error; + goto parse_error_exitcode1; # if !BB_MMU o_addstr(&ctx.as_string, ctx.word.data + pos); o_addchr(&ctx.as_string, '`'); @@ -5697,7 +5713,7 @@ static struct pipe *parse_stream(char **pstring, case_semi: #endif if (done_word(&ctx)) { - goto parse_error; + goto parse_error_exitcode1; } done_pipe(&ctx, PIPE_SEQ); #if ENABLE_HUSH_CASE @@ -5724,7 +5740,7 @@ static struct pipe *parse_stream(char **pstring, continue; /* get next char */ case '&': if (done_word(&ctx)) { - goto parse_error; + goto parse_error_exitcode1; } if (next == '&') { ch = i_getch(input); @@ -5736,7 +5752,7 @@ static struct pipe *parse_stream(char **pstring, goto new_cmd; case '|': if (done_word(&ctx)) { - goto parse_error; + goto parse_error_exitcode1; } #if ENABLE_HUSH_CASE if (ctx.ctx_res_w == RES_MATCH) @@ -5768,7 +5784,7 @@ static struct pipe *parse_stream(char **pstring, case '{': { int n = parse_group(&ctx, input, ch); if (n < 0) { - goto parse_error; + goto parse_error_exitcode1; } debug_printf_heredoc("parse_group done, needs heredocs:%d\n", n); heredoc_cnt += n; @@ -5786,16 +5802,16 @@ static struct pipe *parse_stream(char **pstring, * and it will match } earlier (not here). */ G.last_exitcode = 2; syntax_error_unexpected_ch(ch); - goto parse_error2; + goto parse_error; default: if (HUSH_DEBUG) bb_error_msg_and_die("BUG: unexpected %c", ch); } } /* while (1) */ - parse_error: + parse_error_exitcode1: G.last_exitcode = 1; - parse_error2: + parse_error: { struct parse_context *pctx; IF_HAS_KEYWORDS(struct parse_context *p2;) -- cgit v1.2.3-55-g6feb From 4ac35a30db0c9badd9895c5eaa1d4d3a118b5259 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 16 Nov 2020 13:09:37 +0100 Subject: ash: make interactive ^C break out of PS2 mode Based on patch by Joachim Nilsson function old new delta pgetc 570 547 -23 Signed-off-by: Denys Vlasenko --- shell/ash.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 674a41bd3..d1ca3451d 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10593,7 +10593,7 @@ preadfd(void) g_parsefile->next_to_pgetc = buf; #if ENABLE_FEATURE_EDITING - retry: + /* retry: */ if (!iflag || g_parsefile->pf_fd != STDIN_FILENO) nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1); else { @@ -10615,15 +10615,14 @@ preadfd(void) if (nr == 0) { /* ^C pressed, "convert" to SIGINT */ write(STDOUT_FILENO, "^C", 2); + raise(SIGINT); if (trap[SIGINT]) { buf[0] = '\n'; buf[1] = '\0'; - raise(SIGINT); return 1; } exitstatus = 128 + SIGINT; - bb_putchar('\n'); - goto retry; + return -1; } if (nr < 0) { if (errno == 0) { -- cgit v1.2.3-55-g6feb From ddfdf68ca1d925712a042700118e29f26137f9bd Mon Sep 17 00:00:00 2001 From: Cristian Ionescu-Idbohrn Date: Wed, 18 Nov 2020 10:41:14 +0100 Subject: fix warning: label 'out1' defined but not used Signed-off-by: Cristian Ionescu-Idbohrn Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index d1ca3451d..8c9a590d1 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -7277,7 +7277,9 @@ subevalvar(char *start, char *str, int strloc, out: amount = loc - expdest; STADJUST(amount, expdest); +#if BASH_PATTERN_SUBST out1: +#endif /* Remove any recorded regions beyond start of variable */ removerecordregions(startloc); -- cgit v1.2.3-55-g6feb From 965b795b87c59ed45cc7f16a62301dbae65b1627 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 30 Nov 2020 13:03:03 +0100 Subject: decrease paddign: gcc-9.3.1 slaps 32-byte alignment on arrays willy-nilly text data bss dec hex filename 1021988 559 5052 1027599 fae0f busybox_old 1021236 559 5052 1026847 fab1f busybox_unstripped Signed-off-by: Denys Vlasenko --- archival/dpkg.c | 2 +- archival/libarchive/bz/blocksort.c | 2 +- archival/libarchive/data_extract_to_command.c | 2 +- coreutils/od_bloaty.c | 4 ++-- coreutils/split.c | 2 +- coreutils/stat.c | 2 +- coreutils/stty.c | 4 ++-- coreutils/test.c | 2 +- e2fsprogs/e2fs_lib.c | 2 +- editors/awk.c | 2 +- findutils/find.c | 2 +- include/libbb.h | 3 ++- include/platform.h | 2 ++ libbb/capability.c | 2 +- libbb/duration.c | 2 +- libbb/hash_md5_sha.c | 22 +++++++++++----------- libbb/mode_string.c | 2 +- libbb/pw_encrypt_des.c | 15 +++++++-------- libbb/speed_table.c | 2 +- libbb/xatonum.c | 6 +++--- miscutils/crond.c | 2 +- miscutils/dc.c | 2 +- miscutils/hdparm.c | 2 +- miscutils/i2c_tools.c | 15 +++++---------- miscutils/mt.c | 2 +- miscutils/setserial.c | 3 +-- miscutils/ubi_tools.c | 2 +- miscutils/watchdog.c | 2 +- modutils/modinfo.c | 2 +- networking/ifplugd.c | 2 +- networking/interface.c | 2 +- networking/ip.c | 2 +- networking/libiproute/rt_names.c | 2 +- networking/route.c | 6 +++--- networking/tls.c | 2 +- networking/udhcp/dhcpd.c | 2 +- procps/nmeter.c | 2 +- procps/ps.c | 2 +- runit/svlogd.c | 2 +- shell/ash.c | 6 +++--- shell/hush.c | 12 ++++++------ shell/shell_common.c | 2 +- util-linux/acpid.c | 4 ++-- util-linux/fbset.c | 2 +- util-linux/fdisk.c | 2 +- util-linux/fdisk_osf.c | 4 ++-- util-linux/fdisk_sgi.c | 2 +- util-linux/fdisk_sun.c | 4 ++-- util-linux/mkfs_ext2.c | 2 +- util-linux/mount.c | 2 +- util-linux/volume_id/volume_id.c | 8 ++++---- 51 files changed, 92 insertions(+), 96 deletions(-) (limited to 'shell') diff --git a/archival/dpkg.c b/archival/dpkg.c index 68a40bf6e..bf070a001 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c @@ -1304,7 +1304,7 @@ postrm abort-install postrm abort-upgrade postrm disappear */ -static const char *const all_control_files[] = { +static const char *const all_control_files[] ALIGN_PTR = { "preinst", "postinst", "prerm", "postrm", "list", "md5sums", "shlibs", "conffiles", "config", "templates" diff --git a/archival/libarchive/bz/blocksort.c b/archival/libarchive/bz/blocksort.c index 92d6d8251..062fd0f54 100644 --- a/archival/libarchive/bz/blocksort.c +++ b/archival/libarchive/bz/blocksort.c @@ -459,7 +459,7 @@ int mainGtU(EState* state, * usually small, typically <= 20. */ static -const uint32_t incs[14] = { +const uint32_t incs[14] ALIGN4 = { 1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161, 2391484 diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index 0fcabb4a9..f8b2ff8d2 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c @@ -20,7 +20,7 @@ enum { TAR_MAX, }; -static const char *const tar_var[] = { +static const char *const tar_var[] ALIGN_PTR = { // "FILETYPE", "MODE", "FILENAME", diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c index e9c071f3a..d5bd7bfe8 100644 --- a/coreutils/od_bloaty.c +++ b/coreutils/od_bloaty.c @@ -627,7 +627,7 @@ decode_one_format(const char *s_orig, const char *s, struct tspec *tspec) bytes_to_unsigned_dec_digits, bytes_to_hex_digits, }; - static const char doux_fmtstring[][sizeof(" %%0%u%s")] = { + static const char doux_fmtstring[][sizeof(" %%0%u%s")] ALIGN1 = { " %%%u%s", " %%0%u%s", " %%%u%s", @@ -1148,7 +1148,7 @@ dump_strings(off_t address, off_t end_offset) static int parse_old_offset(const char *s, off_t *offset) { - static const struct suffix_mult Bb[] = { + static const struct suffix_mult Bb[] ALIGN_SUFFIX = { { "B", 1024 }, { "b", 512 }, { "", 0 } diff --git a/coreutils/split.c b/coreutils/split.c index ecbc9d2d8..3fcfd95f2 100644 --- a/coreutils/split.c +++ b/coreutils/split.c @@ -44,7 +44,7 @@ #include "common_bufsiz.h" #if ENABLE_FEATURE_SPLIT_FANCY -static const struct suffix_mult split_suffixes[] = { +static const struct suffix_mult split_suffixes[] ALIGN_SUFFIX = { { "b", 512 }, { "k", 1024 }, { "m", 1024*1024 }, diff --git a/coreutils/stat.c b/coreutils/stat.c index 8a23d687b..ee5e03edd 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c @@ -208,7 +208,7 @@ FS_TYPE(0x62656572, "sysfs") static const char *human_fstype(uint32_t f_type) { # define FS_TYPE(type, name) type, - static const uint32_t fstype[] = { + static const uint32_t fstype[] ALIGN4 = { FS_TYPE_LIST }; # undef FS_TYPE diff --git a/coreutils/stty.c b/coreutils/stty.c index 40e812799..19253964c 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c @@ -487,7 +487,7 @@ static const char mode_name[] ALIGN1 = #undef MI_ENTRY #define MI_ENTRY(N,T,F,B,M) { T, F, M, B }, -static const struct mode_info mode_info[] = { +static const struct mode_info mode_info[] ALIGN4 = { /* This should be verbatim cut-n-paste copy of the above MI_ENTRYs */ MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 ) MI_ENTRY("parity", combination, REV | OMIT, 0, 0 ) @@ -905,7 +905,7 @@ static void display_window_size(int fancy) } } -static const struct suffix_mult stty_suffixes[] = { +static const struct suffix_mult stty_suffixes[] ALIGN_SUFFIX = { { "b", 512 }, { "k", 1024 }, { "B", 1024 }, diff --git a/coreutils/test.c b/coreutils/test.c index ac7b546a3..7c6574334 100644 --- a/coreutils/test.c +++ b/coreutils/test.c @@ -306,7 +306,7 @@ struct operator_t { unsigned char op_num, op_type; }; -static const struct operator_t ops_table[] = { +static const struct operator_t ops_table[] ALIGN2 = { { /* "-r" */ FILRD , UNOP }, { /* "-w" */ FILWR , UNOP }, { /* "-x" */ FILEX , UNOP }, diff --git a/e2fsprogs/e2fs_lib.c b/e2fsprogs/e2fs_lib.c index 6ce655be3..8bd4da622 100644 --- a/e2fsprogs/e2fs_lib.c +++ b/e2fsprogs/e2fs_lib.c @@ -127,7 +127,7 @@ int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_f /* Print file attributes on an ext2 file system */ -const uint32_t e2attr_flags_value[] = { +const uint32_t e2attr_flags_value[] ALIGN4 = { #ifdef ENABLE_COMPRESSION EXT2_COMPRBLK_FL, EXT2_DIRTY_FL, diff --git a/editors/awk.c b/editors/awk.c index 59dae4770..d56d6330d 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -405,7 +405,7 @@ static const char tokenlist[] ALIGN1 = #define OC_B OC_BUILTIN -static const uint32_t tokeninfo[] = { +static const uint32_t tokeninfo[] ALIGN4 = { 0, 0, OC_REGEXP, diff --git a/findutils/find.c b/findutils/find.c index e2947afb4..a8c3fa346 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -1441,7 +1441,7 @@ static action*** parse_params(char **argv) #else #define XATOU_SFX xatoul_sfx #endif - static const struct suffix_mult find_suffixes[] = { + static const struct suffix_mult find_suffixes[] ALIGN_SUFFIX = { { "c", 1 }, { "w", 2 }, { "", 512 }, diff --git a/include/libbb.h b/include/libbb.h index 18dc9f935..9872dc1fb 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1026,8 +1026,9 @@ void generate_uuid(uint8_t *buf) FAST_FUNC; /* Last element is marked by mult == 0 */ struct suffix_mult { char suffix[4]; - unsigned mult; + uint32_t mult; }; +#define ALIGN_SUFFIX ALIGN4 extern const struct suffix_mult bkm_suffixes[]; #define km_suffixes (bkm_suffixes + 1) extern const struct suffix_mult cwbkMG_suffixes[]; diff --git a/include/platform.h b/include/platform.h index 43bb391bd..085387fd8 100644 --- a/include/platform.h +++ b/include/platform.h @@ -342,6 +342,8 @@ typedef unsigned smalluint; # define ALIGN2 # define ALIGN4 #endif +#define ALIGN8 __attribute__((aligned(8))) +#define ALIGN_PTR __attribute__((aligned(sizeof(void*)))) /* * For 0.9.29 and svn, __ARCH_USE_MMU__ indicates no-mmu reliably. diff --git a/libbb/capability.c b/libbb/capability.c index 23afd8eb9..e3c252a5a 100644 --- a/libbb/capability.c +++ b/libbb/capability.c @@ -17,7 +17,7 @@ extern int capget(cap_user_header_t header, const cap_user_data_t data); // This way, libcap needs not be installed in build environment. #include "libbb.h" -static const char *const capabilities[] = { +static const char *const capabilities[] ALIGN_PTR = { "chown", "dac_override", "dac_read_search", diff --git a/libbb/duration.c b/libbb/duration.c index 22b209f4d..086da15fb 100644 --- a/libbb/duration.c +++ b/libbb/duration.c @@ -21,7 +21,7 @@ #include "libbb.h" -static const struct suffix_mult duration_suffixes[] = { +static const struct suffix_mult duration_suffixes[] ALIGN_SUFFIX = { { "s", 1 }, { "m", 60 }, { "h", 60*60 }, diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index d8f210173..e0db8ce67 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c @@ -111,7 +111,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) They are defined in RFC 1321 as T[i] = (int)(2^32 * fabs(sin(i))), i=1..64 */ - static const uint32_t C_array[] = { + static const uint32_t C_array[] ALIGN4 = { /* round 1 */ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, @@ -492,7 +492,7 @@ unsigned FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx) { - static const uint32_t rconsts[] = { + static const uint32_t rconsts[] ALIGN4 = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 }; int i, j; @@ -567,7 +567,7 @@ typedef uint64_t sha_K_int; typedef uint32_t sha_K_int; # define K(v) (uint32_t)(v >> 32) #endif -static const sha_K_int sha_K[] = { +static const sha_K_int sha_K[] ALIGN8 = { K(0x428a2f98d728ae22ULL), K(0x7137449123ef65cdULL), K(0xb5c0fbcfec4d3b2fULL), K(0xe9b5dba58189dbbcULL), K(0x3956c25bf348b538ULL), K(0x59f111f1b605d019ULL), @@ -760,7 +760,7 @@ void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) ctx->process_block = sha1_process_block64; } -static const uint32_t init256[] = { +static const uint32_t init256[] ALIGN4 = { 0, 0, 0x6a09e667, @@ -773,7 +773,7 @@ static const uint32_t init256[] = { 0x5be0cd19, }; #if NEED_SHA512 -static const uint32_t init512_lo[] = { +static const uint32_t init512_lo[] ALIGN4 = { 0, 0, 0xf3bcc908, @@ -1009,7 +1009,7 @@ static void sha3_process_block72(uint64_t *state) #if OPTIMIZE_SHA3_FOR_32 /* - static const uint32_t IOTA_CONST_0[NROUNDS] = { + static const uint32_t IOTA_CONST_0[NROUNDS] ALIGN4 = { 0x00000001UL, 0x00000000UL, 0x00000000UL, @@ -1038,7 +1038,7 @@ static void sha3_process_block72(uint64_t *state) ** bits are in lsb: 0101 0000 1111 0100 1111 0001 */ uint32_t IOTA_CONST_0bits = (uint32_t)(0x0050f4f1); - static const uint32_t IOTA_CONST_1[NROUNDS] = { + static const uint32_t IOTA_CONST_1[NROUNDS] ALIGN4 = { 0x00000000UL, 0x00000089UL, 0x8000008bUL, @@ -1174,7 +1174,7 @@ static void sha3_process_block72(uint64_t *state) combine_halves(state); #else /* Native 64-bit algorithm */ - static const uint16_t IOTA_CONST[NROUNDS] = { + static const uint16_t IOTA_CONST[NROUNDS] ALIGN2 = { /* Elements should be 64-bit, but top half is always zero * or 0x80000000. We encode 63rd bits in a separate word below. * Same is true for 31th bits, which lets us use 16-bit table @@ -1210,15 +1210,15 @@ static void sha3_process_block72(uint64_t *state) /* bit for CONST[0] is in msb: 0001 0110 0011 1000 0001 1011 */ const uint32_t IOTA_CONST_bit31 = (uint32_t)(0x16381b00); - static const uint8_t ROT_CONST[24] = { + static const uint8_t ROT_CONST[24] ALIGN1 = { 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44, }; - static const uint8_t PI_LANE[24] = { + static const uint8_t PI_LANE[24] ALIGN1 = { 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1, }; - /*static const uint8_t MOD5[10] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, };*/ + /*static const uint8_t MOD5[10] ALIGN1 = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, };*/ unsigned x; unsigned round; diff --git a/libbb/mode_string.c b/libbb/mode_string.c index 5ffd5683e..9a286f3ff 100644 --- a/libbb/mode_string.c +++ b/libbb/mode_string.c @@ -27,7 +27,7 @@ #define mode_t unsigned short #endif -static const mode_t mode_flags[] = { +static const mode_t mode_flags[] ALIGN4 = { S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID, S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID, S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX diff --git a/libbb/pw_encrypt_des.c b/libbb/pw_encrypt_des.c index 19a9ab15b..c6fc328d8 100644 --- a/libbb/pw_encrypt_des.c +++ b/libbb/pw_encrypt_des.c @@ -65,25 +65,25 @@ /* A pile of data */ -static const uint8_t IP[64] = { +static const uint8_t IP[64] ALIGN1 = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 }; -static const uint8_t key_perm[56] = { +static const uint8_t key_perm[56] ALIGN1 = { 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 }; -static const uint8_t key_shifts[16] = { +static const uint8_t key_shifts[16] ALIGN1 = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; -static const uint8_t comp_perm[48] = { +static const uint8_t comp_perm[48] ALIGN1 = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, @@ -181,13 +181,12 @@ static const uint8_t u_sbox[8][32] = { }; #endif -static const uint8_t pbox[32] = { +static const uint8_t pbox[32] ALIGN1 = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 }; -static const uint32_t bits32[32] = -{ +static const uint32_t bits32[32] ALIGN4 = { 0x80000000, 0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000, 0x01000000, 0x00800000, 0x00400000, 0x00200000, 0x00100000, @@ -198,7 +197,7 @@ static const uint32_t bits32[32] = 0x00000008, 0x00000004, 0x00000002, 0x00000001 }; -static const uint8_t bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; +static const uint8_t bits8[8] ALIGN1 = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; static int diff --git a/libbb/speed_table.c b/libbb/speed_table.c index 967cf8de8..cf7101e64 100644 --- a/libbb/speed_table.c +++ b/libbb/speed_table.c @@ -28,7 +28,7 @@ struct speed_map { }; /* On Linux, Bxx constants are 0..15 (up to B38400) and 0x1001..0x100f */ -static const struct speed_map speeds[] = { +static const struct speed_map speeds[] ALIGN4 = { {B0, 0}, {B50, 50}, {B75, 75}, diff --git a/libbb/xatonum.c b/libbb/xatonum.c index 7639a62aa..36b06c849 100644 --- a/libbb/xatonum.c +++ b/libbb/xatonum.c @@ -68,14 +68,14 @@ uint16_t FAST_FUNC xatou16(const char *numstr) return xatou_range(numstr, 0, 0xffff); } -const struct suffix_mult bkm_suffixes[] = { +const struct suffix_mult bkm_suffixes[] ALIGN_SUFFIX = { { "b", 512 }, { "k", 1024 }, { "m", 1024*1024 }, { "", 0 } }; -const struct suffix_mult cwbkMG_suffixes[] = { +const struct suffix_mult cwbkMG_suffixes[] ALIGN_SUFFIX = { { "c", 1 }, { "w", 2 }, { "b", 512 }, @@ -96,7 +96,7 @@ const struct suffix_mult cwbkMG_suffixes[] = { { "", 0 } }; -const struct suffix_mult kmg_i_suffixes[] = { +const struct suffix_mult kmg_i_suffixes[] ALIGN_SUFFIX = { { "KiB", 1024 }, { "kiB", 1024 }, { "K", 1024 }, diff --git a/miscutils/crond.c b/miscutils/crond.c index 2e8ca8b68..fb3adc180 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c @@ -492,7 +492,7 @@ static void load_crontab(const char *fileName) const char *name; const char tokens[8]; } SpecialEntry; - static const SpecialEntry SpecAry[] = { + static const SpecialEntry SpecAry[] ALIGN8 = { /* hour day month weekday */ { "yearly", "0\0" "1\0" "1\0" "*" }, { "annually", "0\0" "1\0" "1\0" "*" }, diff --git a/miscutils/dc.c b/miscutils/dc.c index ef93c20ba..51376dd75 100644 --- a/miscutils/dc.c +++ b/miscutils/dc.c @@ -195,7 +195,7 @@ struct op { void (*function) (void); }; -static const struct op operators[] = { +static const struct op operators[] ALIGN_PTR = { #if ENABLE_FEATURE_DC_LIBM {"^", power}, // {"exp", power}, diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index 431a0ad96..01b4e8e2e 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c @@ -1366,7 +1366,7 @@ static NOINLINE void dump_identity(const struct hd_driveid *id) } if (id->capability & 1) { if (id->dma_1word | id->dma_mword) { - static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 }; + static const int dma_wmode_masks[] ALIGN4 = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 }; printf("\n DMA modes: "); print_flags_separated(dma_wmode_masks, "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0", diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index cc8b99a92..09364e396 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -1053,18 +1053,13 @@ struct adap_desc { }; static const struct adap_desc adap_descs[] = { - { .funcs = "dummy", - .algo = "Dummy bus", }, - { .funcs = "isa", - .algo = "ISA bus", }, - { .funcs = "i2c", - .algo = "I2C adapter", }, - { .funcs = "smbus", - .algo = "SMBus adapter", }, + { .funcs = "dummy", .algo = "Dummy bus", }, + { .funcs = "isa", .algo = "ISA bus", }, + { .funcs = "i2c", .algo = "I2C adapter", }, + { .funcs = "smbus", .algo = "SMBus adapter", }, }; -struct i2c_func -{ +struct i2c_func { long value; const char* name; }; diff --git a/miscutils/mt.c b/miscutils/mt.c index 9f1aecfca..dbb8c13ad 100644 --- a/miscutils/mt.c +++ b/miscutils/mt.c @@ -30,7 +30,7 @@ #include /* missing: eod/seod, stoptions, stwrthreshold, densities */ -static const short opcode_value[] = { +static const short opcode_value[] ALIGN2 = { MTBSF, MTBSFM, MTBSR, diff --git a/miscutils/setserial.c b/miscutils/setserial.c index 1e75bf433..2006861e2 100644 --- a/miscutils/setserial.c +++ b/miscutils/setserial.c @@ -381,8 +381,7 @@ static bool cmd_needs_arg(int cmd) # error "Unexpected flags size" #endif -static const uint16_t setbits[CMD_FLAG_LAST + 1] = -{ +static const uint16_t setbits[CMD_FLAG_LAST + 1] ALIGN2 = { 0, ASYNC_SPD_HI, ASYNC_SPD_VHI, diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c index 94a637eee..69ead7a13 100644 --- a/miscutils/ubi_tools.c +++ b/miscutils/ubi_tools.c @@ -97,7 +97,7 @@ static unsigned get_num_from_file(const char *path, unsigned max) int ubi_tools_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int ubi_tools_main(int argc UNUSED_PARAM, char **argv) { - static const struct suffix_mult size_suffixes[] = { + static const struct suffix_mult size_suffixes[] ALIGN_SUFFIX = { { "KiB", 1024 }, { "MiB", 1024*1024 }, { "GiB", 1024*1024*1024 }, diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c index 971b777a3..0ed10bcf1 100644 --- a/miscutils/watchdog.c +++ b/miscutils/watchdog.c @@ -88,7 +88,7 @@ int watchdog_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int watchdog_main(int argc UNUSED_PARAM, char **argv) { static const int enable = WDIOS_ENABLECARD; - static const struct suffix_mult suffixes[] = { + static const struct suffix_mult suffixes[] ALIGN_SUFFIX = { { "ms", 1 }, { "", 1000 }, { "", 0 } diff --git a/modutils/modinfo.c b/modutils/modinfo.c index c5cdc7980..d15772f0d 100644 --- a/modutils/modinfo.c +++ b/modutils/modinfo.c @@ -20,7 +20,7 @@ #include "libbb.h" #include "modutils.h" -static const char *const shortcuts[] = { +static const char *const shortcuts[] ALIGN_PTR = { "filename", // -n "author", // -a "description", // -d diff --git a/networking/ifplugd.c b/networking/ifplugd.c index 60916eae6..18dcaff96 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c @@ -304,7 +304,7 @@ static const char api_modes[] ALIGN1 = "empwia"; static const struct { const char *name; smallint (*func)(void); -} method_table[] = { +} method_table[] ALIGN_PTR = { { "SIOCETHTOOL" , &detect_link_ethtool }, { "SIOCGMIIPHY" , &detect_link_mii }, { "SIOCDEVPRIVATE" , &detect_link_priv }, diff --git a/networking/interface.c b/networking/interface.c index e5e55d8d4..ea6a2c8a8 100644 --- a/networking/interface.c +++ b/networking/interface.c @@ -746,7 +746,7 @@ static const struct hwtype *const hwtypes[] = { }; #ifdef IFF_PORTSEL -static const char *const if_port_text[] = { +static const char *const if_port_text[] ALIGN_PTR = { /* Keep in step with */ "unknown", "10base2", diff --git a/networking/ip.c b/networking/ip.c index 33bea5f49..85b1ba080 100644 --- a/networking/ip.c +++ b/networking/ip.c @@ -400,7 +400,7 @@ int ip_main(int argc UNUSED_PARAM, char **argv) IF_FEATURE_IP_RULE("rule\0") IF_FEATURE_IP_NEIGH("neigh\0") ; - static const ip_func_ptr_t ip_func_ptrs[] = { + static const ip_func_ptr_t ip_func_ptrs[] ALIGN_PTR = { ip_print_help, IF_FEATURE_IP_ADDRESS(do_ipaddr,) IF_FEATURE_IP_ROUTE(do_iproute,) diff --git a/networking/libiproute/rt_names.c b/networking/libiproute/rt_names.c index 51f2e9bdb..3c2fad912 100644 --- a/networking/libiproute/rt_names.c +++ b/networking/libiproute/rt_names.c @@ -77,7 +77,7 @@ static rtnl_tab_t *rtnl_rtprot_tab; static void rtnl_rtprot_initialize(void) { - static const char *const init_tab[] = { + static const char *const init_tab[] ALIGN_PTR = { "none", "redirect", "kernel", diff --git a/networking/route.c b/networking/route.c index 4d9aad6cc..4901109f1 100644 --- a/networking/route.c +++ b/networking/route.c @@ -460,9 +460,9 @@ static NOINLINE void INET6_setroute(int action, char **args) #endif static const -IF_NOT_FEATURE_IPV6(uint16_t) -IF_FEATURE_IPV6(unsigned) -flagvals[] = { /* Must agree with flagchars[]. */ +IF_NOT_FEATURE_IPV6(uint16_t flagvals[] ALIGN2 = ) +IF_FEATURE_IPV6(uint32_t flagvals[] ALIGN4 = ) +{ /* Must agree with flagchars[]. */ RTF_UP, RTF_GATEWAY, RTF_HOST, diff --git a/networking/tls.c b/networking/tls.c index 341225207..e34acd69f 100644 --- a/networking/tls.c +++ b/networking/tls.c @@ -1953,7 +1953,7 @@ static void send_client_key_exchange(tls_state_t *tls) premaster_size = sizeof(rsa_premaster); } else { /* ECDHE */ - static const uint8_t basepoint9[CURVE25519_KEYSIZE] = {9}; + static const uint8_t basepoint9[CURVE25519_KEYSIZE] ALIGN1 = {9}; uint8_t privkey[CURVE25519_KEYSIZE]; //[32] if (!(tls->flags & GOT_EC_KEY)) diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index acfdaa8c3..de16cf955 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -398,7 +398,7 @@ struct config_keyword { #define OFS(field) offsetof(struct server_data_t, field) -static const struct config_keyword keywords[] = { +static const struct config_keyword keywords[] ALIGN_PTR = { /* keyword handler variable address default */ {"start" , udhcp_str2nip , OFS(start_ip ), "192.168.0.20"}, {"end" , udhcp_str2nip , OFS(end_ip ), "192.168.0.254"}, diff --git a/procps/nmeter.c b/procps/nmeter.c index 856ce0202..07b7abe2f 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -838,7 +838,7 @@ static void FAST_FUNC collect_info(s_stat *s) typedef s_stat* init_func(const char *param); static const char options[] ALIGN1 = "ncmsfixptTbr"; -static init_func *const init_functions[] = { +static init_func *const init_functions[] ALIGN_PTR = { init_if, init_cpu, init_mem, diff --git a/procps/ps.c b/procps/ps.c index 48f96209f..711b180a0 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -375,7 +375,7 @@ static void func_pcpu(char *buf, int size, const procps_status_t *ps) } */ -static const ps_out_t out_spec[] = { +static const ps_out_t out_spec[] ALIGN_PTR = { /* Mandated by http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html: */ { 8 , "user" ,"USER" ,func_user ,PSSCAN_UIDGID }, { 8 , "group" ,"GROUP" ,func_group ,PSSCAN_UIDGID }, diff --git a/runit/svlogd.c b/runit/svlogd.c index a250058a1..040e71104 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c @@ -775,7 +775,7 @@ static NOINLINE unsigned logdir_open(struct logdir *ld, const char *fn) ld->nmin = xatoi_positive(&s[1]); break; case 't': { - static const struct suffix_mult mh_suffixes[] = { + static const struct suffix_mult mh_suffixes[] ALIGN_SUFFIX = { { "m", 60 }, { "h", 60*60 }, /*{ "d", 24*60*60 },*/ diff --git a/shell/ash.c b/shell/ash.c index 8c9a590d1..40695dee0 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -2091,7 +2091,7 @@ static const struct { int flags; const char *var_text; void (*var_func)(const char *) FAST_FUNC; -} varinit_data[] = { +} varinit_data[] ALIGN_PTR = { /* * Note: VEXPORT would not work correctly here for NOFORK applets: * some environment strings may be constant. @@ -4811,7 +4811,7 @@ static char *cmdnextc; static void cmdputs(const char *s) { - static const char vstype[VSTYPE + 1][3] = { + static const char vstype[VSTYPE + 1][3] ALIGN1 = { "", "}", "-", "+", "?", "=", "%", "%%", "#", "##" IF_BASH_SUBSTR(, ":") @@ -8510,7 +8510,7 @@ enum { , /* thus far 29 bits used */ }; -static const char *const tokname_array[] = { +static const char *const tokname_array[] ALIGN_PTR = { "end of file", "newline", "redirection", diff --git a/shell/hush.c b/shell/hush.c index f1a7e07ee..b6d9d7abb 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -596,10 +596,10 @@ typedef struct in_str { /* The descrip member of this structure is only used to make * debugging output pretty */ static const struct { - int mode; + int32_t mode; signed char default_fd; char descrip[3]; -} redir_table[] = { +} redir_table[] ALIGN4 = { { O_RDONLY, 0, "<" }, { O_CREAT|O_TRUNC|O_WRONLY, 1, ">" }, { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" }, @@ -1143,7 +1143,7 @@ struct built_in_command { #endif }; -static const struct built_in_command bltins1[] = { +static const struct built_in_command bltins1[] ALIGN_PTR = { BLTIN("." , builtin_source , "Run commands in file"), BLTIN(":" , builtin_true , NULL), #if ENABLE_HUSH_JOB @@ -1228,7 +1228,7 @@ static const struct built_in_command bltins1[] = { /* These builtins won't be used if we are on NOMMU and need to re-exec * (it's cheaper to run an external program in this case): */ -static const struct built_in_command bltins2[] = { +static const struct built_in_command bltins2[] ALIGN_PTR = { #if ENABLE_HUSH_TEST BLTIN("[" , builtin_test , NULL), #endif @@ -3895,7 +3895,7 @@ struct reserved_combo { char literal[6]; unsigned char res; unsigned char assignment_flag; - int flag; + uint32_t flag; }; enum { FLAG_END = (1 << RES_NONE ), @@ -3928,7 +3928,7 @@ static const struct reserved_combo* match_reserved_word(o_string *word) * to turn the compound list into a command. * FLAG_START means the word must start a new compound list. */ - static const struct reserved_combo reserved_list[] = { + static const struct reserved_combo reserved_list[] ALIGN4 = { # if ENABLE_HUSH_IF { "!", RES_NONE, NOT_ASSIGNMENT , 0 }, { "if", RES_IF, MAYBE_ASSIGNMENT, FLAG_THEN | FLAG_START }, diff --git a/shell/shell_common.c b/shell/shell_common.c index 42c4c9c97..dcbe0d109 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -324,7 +324,7 @@ struct limits { uint8_t factor_shift; /* shift by to get rlim_{cur,max} values */ }; -static const struct limits limits_tbl[] = { +static const struct limits limits_tbl[] ALIGN2 = { { RLIMIT_CORE, 9, }, // -c { RLIMIT_DATA, 10, }, // -d { RLIMIT_NICE, 0, }, // -e diff --git a/util-linux/acpid.c b/util-linux/acpid.c index d473e24fc..00613f8e3 100644 --- a/util-linux/acpid.c +++ b/util-linux/acpid.c @@ -99,7 +99,7 @@ struct acpi_event { const char *desc; }; -static const struct acpi_event f_evt_tab[] = { +static const struct acpi_event f_evt_tab[] ALIGN_PTR = { { "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRF 00000080" }, { "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRB 00000080" }, { "EV_SW", 0x05, "SW_LID", 0x00, 1, "button/lid LID0 00000080" }, @@ -110,7 +110,7 @@ struct acpi_action { const char *action; }; -static const struct acpi_action f_act_tab[] = { +static const struct acpi_action f_act_tab[] ALIGN_PTR = { { "PWRF", "PWRF/00000080" }, { "LID0", "LID/00000080" }, }; diff --git a/util-linux/fbset.c b/util-linux/fbset.c index 0b9a9a6bc..cc5413b40 100644 --- a/util-linux/fbset.c +++ b/util-linux/fbset.c @@ -193,7 +193,7 @@ static const struct cmdoptions_t { const char name[9]; const unsigned char param_count; const unsigned char code; -} g_cmdoptions[] = { +} g_cmdoptions[] ALIGN1 = { /*"12345678" + NUL */ //TODO: convert to index_in_strings() { "fb" , 1, CMD_FB }, diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 0df3ebf7d..6454baab8 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c @@ -303,7 +303,7 @@ static sector_t get_nr_sects(const struct partition *p); /* DOS partition types */ -static const char *const i386_sys_types[] = { +static const char *const i386_sys_types[] ALIGN_PTR = { "\x00" "Empty", "\x01" "FAT12", "\x04" "FAT16 <32M", diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c index 92180b2bc..765740ff1 100644 --- a/util-linux/fdisk_osf.c +++ b/util-linux/fdisk_osf.c @@ -144,7 +144,7 @@ struct xbsd_disklabel { #define BSD_DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */ #define BSD_DSTYPE_GEOMETRY 0x10 /* drive params in label */ -static const char *const xbsd_dktypenames[] = { +static const char *const xbsd_dktypenames[] ALIGN_PTR = { "unknown", "SMD", "MSCP", @@ -190,7 +190,7 @@ static const char *const xbsd_dktypenames[] = { #define BSD_FS_MSDOS 8 /* MS-DOS file system */ #endif -static const char *const xbsd_fstypes[] = { +static const char *const xbsd_fstypes[] ALIGN_PTR = { "\x00" "unused", /* BSD_FS_UNUSED */ "\x01" "swap", /* BSD_FS_SWAP */ "\x02" "Version 6", /* BSD_FS_V6 */ diff --git a/util-linux/fdisk_sgi.c b/util-linux/fdisk_sgi.c index c90c801e2..acb438ac0 100644 --- a/util-linux/fdisk_sgi.c +++ b/util-linux/fdisk_sgi.c @@ -174,7 +174,7 @@ isinfreelist(unsigned int b) * end of free blocks section */ -static const char *const sgi_sys_types[] = { +static const char *const sgi_sys_types[] ALIGN_PTR = { /* SGI_VOLHDR */ "\x00" "SGI volhdr" , /* 0x01 */ "\x01" "SGI trkrepl" , /* 0x02 */ "\x02" "SGI secrepl" , diff --git a/util-linux/fdisk_sun.c b/util-linux/fdisk_sun.c index 29d7c283a..427b9487b 100644 --- a/util-linux/fdisk_sun.c +++ b/util-linux/fdisk_sun.c @@ -61,7 +61,7 @@ guess_device_type(void) } } -static const char *const sun_sys_types[] = { +static const char *const sun_sys_types[] ALIGN_PTR = { "\x00" "Empty" , /* 0 */ "\x01" "Boot" , /* 1 */ "\x02" "SunOS root" , /* 2 */ @@ -133,7 +133,7 @@ static const struct sun_predefined_drives { unsigned short ntrks; unsigned short nsect; unsigned short rspeed; -} sun_drives[] = { +} sun_drives[] ALIGN_PTR = { { "Quantum","ProDrive 80S",1,832,2,834,6,34,3662}, { "Quantum","ProDrive 105S",1,974,2,1019,6,35,3662}, { "CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600}, diff --git a/util-linux/mkfs_ext2.c b/util-linux/mkfs_ext2.c index 1f525d75b..fcf374b2d 100644 --- a/util-linux/mkfs_ext2.c +++ b/util-linux/mkfs_ext2.c @@ -131,7 +131,7 @@ static void allocate(uint8_t *bitmap, uint32_t blocksize, uint32_t start, uint32 static uint32_t has_super(uint32_t x) { // 0, 1 and powers of 3, 5, 7 up to 2^32 limit - static const uint32_t supers[] = { + static const uint32_t supers[] ALIGN4 = { 0, 1, 3, 5, 7, 9, 25, 27, 49, 81, 125, 243, 343, 625, 729, 2187, 2401, 3125, 6561, 15625, 16807, 19683, 59049, 78125, 117649, 177147, 390625, 531441, 823543, 1594323, 1953125, diff --git a/util-linux/mount.c b/util-linux/mount.c index fc5161d7f..aa38847ec 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -323,7 +323,7 @@ enum { // Standard mount options (from -o options or --options), // with corresponding flags -static const int32_t mount_options[] = { +static const int32_t mount_options[] ALIGN4 = { // MS_FLAGS set a bit. ~MS_FLAGS disable that bit. 0 flags are NOPs. IF_FEATURE_MOUNT_LOOP( diff --git a/util-linux/volume_id/volume_id.c b/util-linux/volume_id/volume_id.c index 99150a5b7..8ceb61bde 100644 --- a/util-linux/volume_id/volume_id.c +++ b/util-linux/volume_id/volume_id.c @@ -49,7 +49,7 @@ typedef int FAST_FUNC (*raid_probe_fptr)(struct volume_id *id, /*uint64_t off,*/ uint64_t size); typedef int FAST_FUNC (*probe_fptr)(struct volume_id *id /*, uint64_t off*/); -static const raid_probe_fptr raid1[] = { +static const raid_probe_fptr raid1[] ALIGN_PTR = { #if ENABLE_FEATURE_VOLUMEID_LINUXRAID volume_id_probe_linux_raid, #endif @@ -76,7 +76,7 @@ static const raid_probe_fptr raid1[] = { #endif }; -static const probe_fptr raid2[] = { +static const probe_fptr raid2[] ALIGN_PTR = { #if ENABLE_FEATURE_VOLUMEID_LVM volume_id_probe_lvm1, volume_id_probe_lvm2, @@ -90,7 +90,7 @@ static const probe_fptr raid2[] = { }; /* signature in the first block, only small buffer needed */ -static const probe_fptr fs1[] = { +static const probe_fptr fs1[] ALIGN_PTR = { #if ENABLE_FEATURE_VOLUMEID_FAT volume_id_probe_vfat, #endif @@ -118,7 +118,7 @@ static const probe_fptr fs1[] = { }; /* fill buffer with maximum */ -static const probe_fptr fs2[] = { +static const probe_fptr fs2[] ALIGN_PTR = { #if ENABLE_FEATURE_VOLUMEID_LINUXSWAP volume_id_probe_linux_swap, #endif -- cgit v1.2.3-55-g6feb From 31df5a3eee74862312bbf89449d223aeae13aaf7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 13 Dec 2020 16:36:28 +0100 Subject: ash: reset SIGHUP earlier: allows HUP traps in .profile, closes 13371 function old new delta ash_main 1188 1203 +15 Signed-off-by: Denys Vlasenko --- shell/ash.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 40695dee0..b271dd031 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -14340,6 +14340,17 @@ procargs(char **argv) shellparam.nparam++; xargv++; } + + /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry. + * Try: + * trap '' hup; bash; echo RET # type "kill -hup $$", see SIGHUP having effect + * trap '' hup; bash -c 'kill -hup $$; echo ALIVE' # here SIGHUP is SIG_IGNed + * NB: must do it before setting up signals (in optschanged()) + * and reading .profile etc (after we return from here): + */ + if (iflag) + signal(SIGHUP, SIG_DFL); + optschanged(); return login_sh; @@ -14510,14 +14521,6 @@ int ash_main(int argc UNUSED_PARAM, char **argv) } #endif state4: /* XXX ??? - why isn't this before the "if" statement */ - - /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry. - * Try: - * trap '' hup; bash; echo RET # type "kill -hup $$", see SIGHUP having effect - * trap '' hup; bash -c 'kill -hup $$; echo ALIVE' # here SIGHUP is SIG_IGNed - */ - signal(SIGHUP, SIG_DFL); - cmdloop(1); } #if PROFILE -- cgit v1.2.3-55-g6feb From 9cabd17e555db8f1a48e1cd5db0a8a7a947bced9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 13 Dec 2020 18:24:11 +0100 Subject: hush: fix -c SCRIPT handling function old new delta hush_main 1763 1759 -4 Signed-off-by: Denys Vlasenko --- shell/hush.c | 114 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 51 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index b6d9d7abb..219158f18 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -10096,6 +10096,19 @@ int hush_main(int argc, char **argv) * PS4='+ ' */ +#if NUM_SCRIPTS > 0 + if (argc < 0) { + char *script = get_script_content(-argc - 1); + G.global_argv = argv; + G.global_argc = string_array_len(argv); + G.root_pid = getpid(); + G.root_ppid = getppid(); + //install_special_sighandlers(); - needed? + parse_and_run_string(script); + goto final_return; + } +#endif + /* Initialize some more globals to non-zero values */ die_func = restore_ttypgrp_and__exit; @@ -10110,16 +10123,8 @@ int hush_main(int argc, char **argv) /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */ flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0; builtin_argc = 0; -#if NUM_SCRIPTS > 0 - if (argc < 0) { - optarg = get_script_content(-argc - 1); - optind = 0; - argc = string_array_len(argv); - goto run_script; - } -#endif while (1) { - int opt = getopt(argc, argv, "+c:exinsl" + int opt = getopt(argc, argv, "+cexinsl" #if !BB_MMU "<:$:R:V:" # if ENABLE_HUSH_FUNCTIONS @@ -10131,50 +10136,11 @@ int hush_main(int argc, char **argv) break; switch (opt) { case 'c': - /* Possibilities: - * sh ... -c 'script' - * sh ... -c 'script' ARG0 [ARG1...] - * On NOMMU, if builtin_argc != 0, - * sh ... -c 'builtin' BARGV... "" ARG0 [ARG1...] - * "" needs to be replaced with NULL - * and BARGV vector fed to builtin function. - * Note: the form without ARG0 never happens: - * sh ... -c 'builtin' BARGV... "" + /* Note: -c is not a param with option! + * "hush -c -l SCRIPT" is valid. "hush -cSCRIPT" is not. */ -#if NUM_SCRIPTS > 0 - run_script: -#endif - if (!G.root_pid) { - G.root_pid = getpid(); - G.root_ppid = getppid(); - } - G.global_argv = argv + optind; - G.global_argc = argc - optind; - if (builtin_argc) { - /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */ - const struct built_in_command *x; - - install_special_sighandlers(); - x = find_builtin(optarg); - if (x) { /* paranoia */ - G.global_argc -= builtin_argc; /* skip [BARGV...] "" */ - G.global_argv += builtin_argc; - G.global_argv[-1] = NULL; /* replace "" */ - fflush_all(); - G.last_exitcode = x->b_function(argv + optind - 1); - } - goto final_return; - } G.opt_c = 1; - if (!G.global_argv[0]) { - /* -c 'script' (no params): prevent empty $0 */ - G.global_argv--; /* points to argv[i] of 'script' */ - G.global_argv[0] = argv[0]; - G.global_argc++; - } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */ - install_special_sighandlers(); - parse_and_run_string(optarg); - goto final_return; + break; case 'i': /* Well, we cannot just declare interactiveness, * we have to have some stuff (ctty, etc) */ @@ -10290,6 +10256,52 @@ int hush_main(int argc, char **argv) */ } + /* -c takes effect *after* -l */ + if (G.opt_c) { + /* Possibilities: + * sh ... -c 'script' + * sh ... -c 'script' ARG0 [ARG1...] + * On NOMMU, if builtin_argc != 0, + * sh ... -c 'builtin' BARGV... "" ARG0 [ARG1...] + * "" needs to be replaced with NULL + * and BARGV vector fed to builtin function. + * Note: the form without ARG0 never happens: + * sh ... -c 'builtin' BARGV... "" + */ + char *script; + + install_special_sighandlers(); + + G.global_argc--; + G.global_argv++; + if (builtin_argc) { + /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */ + const struct built_in_command *x; + x = find_builtin(G.global_argv[0]); + if (x) { /* paranoia */ + argv = G.global_argv; + G.global_argc -= builtin_argc + 1; /* skip [BARGV...] "" */ + G.global_argv += builtin_argc + 1; + G.global_argv[-1] = NULL; /* replace "" */ + G.last_exitcode = x->b_function(argv); + } + goto final_return; + } + + script = G.global_argv[0]; + if (!script) + bb_error_msg_and_die(bb_msg_requires_arg, "-c"); + if (!G.global_argv[1]) { + /* -c 'script' (no params): prevent empty $0 */ + G.global_argv[0] = argv[0]; + } else { /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */ + G.global_argc--; + G.global_argv++; + } + parse_and_run_string(script); + goto final_return; + } + /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */ if (!G.opt_s && G.global_argv[1]) { HFILE *input; -- cgit v1.2.3-55-g6feb From 49142d48bd12c87d52e1316050f5cf4749e64e51 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 13 Dec 2020 18:44:07 +0100 Subject: hush: NOMMU fix for hush-psubst/tick6.tests function old new delta hush_main 1759 1766 +7 Signed-off-by: Denys Vlasenko --- shell/hush.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index 219158f18..f9b5623fd 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -10187,6 +10187,11 @@ int hush_main(int argc, char **argv) optarg++; G.depth_of_loop = bb_strtou(optarg, &optarg, 16); # endif + /* Suppress "killed by signal" message, -$ hack is used + * for subshells: echo `sh -c 'kill -9 $$'` + * should be silent. + */ + IF_HUSH_JOB(G.run_list_level = 1;) # if ENABLE_HUSH_FUNCTIONS /* nommu uses re-exec trick for "... | func | ...", * should allow "return". @@ -10274,6 +10279,7 @@ int hush_main(int argc, char **argv) G.global_argc--; G.global_argv++; +#if !BB_MMU if (builtin_argc) { /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */ const struct built_in_command *x; @@ -10287,6 +10293,7 @@ int hush_main(int argc, char **argv) } goto final_return; } +#endif script = G.global_argv[0]; if (!script) -- cgit v1.2.3-55-g6feb From 63139b531f7f1d71d8274810b163da1a78d4609e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 13 Dec 2020 22:00:56 +0100 Subject: hush: if login shell, also source ~/.profile function old new delta hush_main 1101 1151 +50 Signed-off-by: Denys Vlasenko --- shell/hush.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index f9b5623fd..ba9540c98 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -9992,7 +9992,9 @@ int hush_main(int argc, char **argv) OPT_login = (1 << 0), }; unsigned flags; - unsigned builtin_argc; +#if !BB_MMU + unsigned builtin_argc = 0; +#endif char **e; struct variable *cur_var; struct variable *shell_ver; @@ -10122,7 +10124,6 @@ int hush_main(int argc, char **argv) /* Parse options */ /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */ flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0; - builtin_argc = 0; while (1) { int opt = getopt(argc, argv, "+cexinsl" #if !BB_MMU @@ -10222,13 +10223,7 @@ int hush_main(int argc, char **argv) if (set_mode(1, opt, NULL) == 0) /* no error */ break; default: -#ifndef BB_VER - fprintf(stderr, "Usage: sh [FILE]...\n" - " or: sh -c command [args]...\n\n"); - exit(EXIT_FAILURE); -#else bb_show_usage(); -#endif } } /* option parsing loop */ @@ -10244,9 +10239,12 @@ int hush_main(int argc, char **argv) /* If we are login shell... */ if (flags & OPT_login) { + const char *hp = NULL; HFILE *input; + debug_printf("sourcing /etc/profile\n"); input = hfopen("/etc/profile"); + run_profile: if (input != NULL) { install_special_sighandlers(); parse_and_run_file(input); @@ -10259,6 +10257,16 @@ int hush_main(int argc, char **argv) * bash also sources ~/.bash_logout on exit. * If called as sh, skips .bash_XXX files. */ + if (!hp) { /* unless we looped on the "goto" already */ + hp = get_local_var_value("HOME"); + if (hp && hp[0]) { + debug_printf("sourcing ~/.profile\n"); + hp = concat_path_file(hp, ".profile"); + input = hfopen(hp); + free((char*)hp); + goto run_profile; + } + } } /* -c takes effect *after* -l */ -- cgit v1.2.3-55-g6feb From a8e19608fc9d2f775a4f81eaf9c38a5844684237 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 14 Dec 2020 03:52:54 +0100 Subject: hush: code shrink function old new delta run_applet_main - 20 +20 builtin_kill 296 288 -8 builtin_test 19 10 -9 builtin_printf 19 10 -9 builtin_echo 19 10 -9 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/4 up/down: 20/-35) Total: -15 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index ba9540c98..3ccc18146 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -10499,7 +10499,7 @@ static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM) } #if ENABLE_HUSH_TEST || ENABLE_HUSH_ECHO || ENABLE_HUSH_PRINTF || ENABLE_HUSH_KILL -static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv)) +static NOINLINE int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv)) { int argc = string_array_len(argv); return applet_main_func(argc, argv); -- cgit v1.2.3-55-g6feb From 91e330a53fc8052addec941a9e1e6fcd4b68702b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 17 Dec 2020 12:07:54 +0100 Subject: shells: a fix for systems without RLIMIT_NICE Signed-off-by: Denys Vlasenko --- shell/shell_common.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'shell') diff --git a/shell/shell_common.c b/shell/shell_common.c index dcbe0d109..f95a35e8b 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -324,12 +324,18 @@ struct limits { uint8_t factor_shift; /* shift by to get rlim_{cur,max} values */ }; +/* Order of entries matches order in which bash prints "ulimit -a" */ static const struct limits limits_tbl[] ALIGN2 = { { RLIMIT_CORE, 9, }, // -c { RLIMIT_DATA, 10, }, // -d +#ifdef RLIMIT_NICE { RLIMIT_NICE, 0, }, // -e - { RLIMIT_FSIZE, 9, }, // -f #define LIMIT_F_IDX 3 +#else +/* for example, Hurd */ +#define LIMIT_F_IDX 2 +#endif + { RLIMIT_FSIZE, 9, }, // -f #ifdef RLIMIT_SIGPENDING { RLIMIT_SIGPENDING, 0, }, // -i #endif @@ -364,13 +370,16 @@ static const struct limits limits_tbl[] ALIGN2 = { { RLIMIT_LOCKS, 0, }, // -x #endif }; -// bash also shows: +// 1) bash also shows: //pipe size (512 bytes, -p) 8 +// 2) RLIMIT_RTTIME ("timeout for RT tasks in us") is not in the table static const char limits_help[] ALIGN1 = "core file size (blocks)" // -c "\0""data seg size (kb)" // -d +#ifdef RLIMIT_NICE "\0""scheduling priority" // -e +#endif "\0""file size (blocks)" // -f #ifdef RLIMIT_SIGPENDING "\0""pending signals" // -i @@ -410,7 +419,9 @@ static const char limits_help[] ALIGN1 = static const char limit_chars[] ALIGN1 = "c" "d" +#ifdef RLIMIT_NICE "e" +#endif "f" #ifdef RLIMIT_SIGPENDING "i" @@ -451,7 +462,9 @@ static const char limit_chars[] ALIGN1 = static const char ulimit_opt_string[] ALIGN1 = "-HSa" "c::" "d::" +#ifdef RLIMIT_NICE "e::" +#endif "f::" #ifdef RLIMIT_SIGPENDING "i::" @@ -668,7 +681,7 @@ shell_builtin_ulimit(char **argv) if (opt_cnt == 0) { /* "bare ulimit": treat it as if it was -f */ - getrlimit(limits_tbl[LIMIT_F_IDX].cmd, &limit); + getrlimit(RLIMIT_FSIZE, &limit); printlim(opts, &limit, &limits_tbl[LIMIT_F_IDX]); } -- cgit v1.2.3-55-g6feb From 2124c0ec97249b66889b6486ab5b5223993d31c0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 19 Dec 2020 14:33:02 +0100 Subject: ash: clear ungetc counter on syntax errors function old new delta raise_exception 26 39 +13 Signed-off-by: Denys Vlasenko --- shell/ash.c | 112 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 57 insertions(+), 55 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index b271dd031..87d329f87 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -544,6 +544,61 @@ var_end(const char *var) } +/* ============ Parser data */ + +/* + * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up. + */ +struct strlist { + struct strlist *next; + char *text; +}; + +struct alias; + +struct strpush { + struct strpush *prev; /* preceding string on stack */ + char *prev_string; + int prev_left_in_line; +#if ENABLE_ASH_ALIAS + struct alias *ap; /* if push was associated with an alias */ +#endif + char *string; /* remember the string since it may change */ + + /* Remember last two characters for pungetc. */ + int lastc[2]; + + /* Number of outstanding calls to pungetc. */ + int unget; +}; + +/* + * The parsefile structure pointed to by the global variable parsefile + * contains information about the current file being read. + */ +struct parsefile { + struct parsefile *prev; /* preceding file on stack */ + int linno; /* current line */ + int pf_fd; /* file descriptor (or -1 if string) */ + int left_in_line; /* number of chars left in this line */ + int left_in_buffer; /* number of chars left in this buffer past the line */ + char *next_to_pgetc; /* next char in buffer */ + char *buf; /* input buffer */ + struct strpush *strpush; /* for pushing strings at this level */ + struct strpush basestrpush; /* so pushing one is fast */ + + /* Remember last two characters for pungetc. */ + int lastc[2]; + + /* Number of outstanding calls to pungetc. */ + int unget; +}; + +static struct parsefile basepf; /* top level input file */ +static struct parsefile *g_parsefile = &basepf; /* current input file */ +static char *commandname; /* currently executing command */ + + /* ============ Interrupts / exceptions */ static void exitshell(void) NORETURN; @@ -581,6 +636,8 @@ raise_exception(int e) abort(); #endif INT_OFF; + /* Prevent this: ";l" -> syntax error, then "s" -> runs "ls" */ + g_parsefile->unget = 0; exception_type = e; longjmp(exception_handler->loc, 1); } @@ -1299,61 +1356,6 @@ showtree(union node *n) #endif /* DEBUG */ -/* ============ Parser data */ - -/* - * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up. - */ -struct strlist { - struct strlist *next; - char *text; -}; - -struct alias; - -struct strpush { - struct strpush *prev; /* preceding string on stack */ - char *prev_string; - int prev_left_in_line; -#if ENABLE_ASH_ALIAS - struct alias *ap; /* if push was associated with an alias */ -#endif - char *string; /* remember the string since it may change */ - - /* Remember last two characters for pungetc. */ - int lastc[2]; - - /* Number of outstanding calls to pungetc. */ - int unget; -}; - -/* - * The parsefile structure pointed to by the global variable parsefile - * contains information about the current file being read. - */ -struct parsefile { - struct parsefile *prev; /* preceding file on stack */ - int linno; /* current line */ - int pf_fd; /* file descriptor (or -1 if string) */ - int left_in_line; /* number of chars left in this line */ - int left_in_buffer; /* number of chars left in this buffer past the line */ - char *next_to_pgetc; /* next char in buffer */ - char *buf; /* input buffer */ - struct strpush *strpush; /* for pushing strings at this level */ - struct strpush basestrpush; /* so pushing one is fast */ - - /* Remember last two characters for pungetc. */ - int lastc[2]; - - /* Number of outstanding calls to pungetc. */ - int unget; -}; - -static struct parsefile basepf; /* top level input file */ -static struct parsefile *g_parsefile = &basepf; /* current input file */ -static char *commandname; /* currently executing command */ - - /* ============ Message printing */ static void -- cgit v1.2.3-55-g6feb From bb4e32befaf86f80a108d2b7a4b7c47ffcc64e9c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 20 Dec 2020 16:36:00 +0100 Subject: hush: remove one redundant getpid() on every startup function old new delta hush_main 1151 1147 -4 Signed-off-by: Denys Vlasenko --- shell/hush.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index 3ccc18146..f29c985ad 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -9988,6 +9988,7 @@ static int set_mode(int state, char mode, const char *o_opt) int hush_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int hush_main(int argc, char **argv) { + pid_t cached_getpid; enum { OPT_login = (1 << 0), }; @@ -10016,6 +10017,10 @@ int hush_main(int argc, char **argv) G.argv0_for_re_execing = argv[0]; #endif + cached_getpid = getpid(); /* for tcsetpgrp() during init */ + G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ + G.root_ppid = getppid(); /* for $$PPID (NOMMU can override) */ + /* Deal with HUSH_VERSION */ debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); unsetenv("HUSH_VERSION"); /* in case it exists in initial env */ @@ -10103,8 +10108,6 @@ int hush_main(int argc, char **argv) char *script = get_script_content(-argc - 1); G.global_argv = argv; G.global_argc = string_array_len(argv); - G.root_pid = getpid(); - G.root_ppid = getppid(); //install_special_sighandlers(); - needed? parse_and_run_string(script); goto final_return; @@ -10232,11 +10235,6 @@ int hush_main(int argc, char **argv) G.global_argv = argv + (optind - 1); G.global_argv[0] = argv[0]; - if (!G.root_pid) { - G.root_pid = getpid(); - G.root_ppid = getppid(); - } - /* If we are login shell... */ if (flags & OPT_login) { const char *hp = NULL; @@ -10406,7 +10404,7 @@ int hush_main(int argc, char **argv) * (bash, too, does this only if ctty is available) */ bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */ /* Grab control of the terminal */ - tcsetpgrp(G_interactive_fd, getpid()); + tcsetpgrp(G_interactive_fd, cached_getpid); } enable_restore_tty_pgrp_on_exit(); -- cgit v1.2.3-55-g6feb From 07abc7c6f7dd0875e0aa548bba952174a54c8797 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 21 Dec 2020 10:09:48 +0100 Subject: hush: deal with FIXMEs for corner cases in parameter expansion function old new delta expand_one_var 2323 2344 +21 Signed-off-by: Denys Vlasenko --- shell/hush.c | 52 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 18 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index f29c985ad..a8f7237d5 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -6506,9 +6506,11 @@ static NOINLINE int expand_one_var(o_string *output, int n, * Word is expanded to produce a glob pattern. * Then var's value is matched to it and matching part removed. */ -//FIXME: ${x#...${...}...} -//should evaluate inner ${...} even if x is "" and no shrinking of it is possible - -//inner ${...} may have side effects! + /* bash compat: if x is "" and no shrinking of it is possible, + * inner ${...} is not evaluated. Example: + * unset b; : ${a%${b=B}}; echo $b + * assignment b=B only happens if $a is not "". + */ if (val && val[0]) { char *t; char *exp_exp_word; @@ -6547,7 +6549,12 @@ static NOINLINE int expand_one_var(o_string *output, int n, * and if // is used, it is encoded as \: * var\patternrepl */ - if (val && val[0]) { + /* bash compat: if var is "", both pattern and repl + * are still evaluated, if it is unset, then not: + * unset b; a=; : ${a/z/${b=3}}; echo $b # b=3 + * unset b; unset a; : ${a/z/${b=3}}; echo $b # b not set + */ + if (val /*&& val[0]*/) { /* pattern uses non-standard expansion. * repl should be unbackslashed and globbed * by the usual expansion rules: @@ -6583,8 +6590,9 @@ static NOINLINE int expand_one_var(o_string *output, int n, free(pattern); free(repl); } else { - /* Empty variable always gives nothing */ - // "v=''; echo ${v/*/w}" prints "", not "w" + /* Unset variable always gives nothing */ + // a=; echo ${a/*/w} # "w" + // unset a; echo ${a/*/w} # "" /* Just skip "replace" part */ *p++ = SPECIAL_VAR_SYMBOL; p = strchr(p, SPECIAL_VAR_SYMBOL); @@ -6599,40 +6607,48 @@ static NOINLINE int expand_one_var(o_string *output, int n, * var:NM */ arith_t beg, len; + unsigned vallen; const char *errmsg; beg = expand_and_evaluate_arith(exp_word, &errmsg); if (errmsg) - goto arith_err; + goto empty_result; debug_printf_varexp("beg:'%s'=%lld\n", exp_word, (long long)beg); *p++ = SPECIAL_VAR_SYMBOL; exp_word = p; p = strchr(p, SPECIAL_VAR_SYMBOL); *p = '\0'; - len = expand_and_evaluate_arith(exp_word, &errmsg); - if (errmsg) - goto arith_err; - debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len); + vallen = strlen(val); if (beg < 0) { /* negative beg counts from the end */ - beg = (arith_t)strlen(val) + beg; - if (beg < 0) /* ${v: -999999} is "" */ - beg = len = 0; + beg = (arith_t)vallen + beg; } + /* If expansion will be empty, do not even evaluate len */ + if (!val || beg < 0 || beg > vallen) { + /* Why > vallen, not >=? bash: + * unset b; a=ab; : ${a:2:${b=3}}; echo $b # "", b=3 (!!!) + * unset b; a=a; : ${a:2:${b=3}}; echo $b # "", b not set + */ + goto empty_result; + } + len = expand_and_evaluate_arith(exp_word, &errmsg); + if (errmsg) + goto empty_result; + debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len); debug_printf_varexp("from val:'%s'\n", val); if (len < 0) { /* in bash, len=-n means strlen()-n */ - len = (arith_t)strlen(val) - beg + len; + len = (arith_t)vallen - beg + len; if (len < 0) /* bash compat */ msg_and_die_if_script("%s: substring expression < 0", var); } - if (len <= 0 || !val || beg >= strlen(val)) { - arith_err: + if (len <= 0 || !val /*|| beg >= vallen*/) { + empty_result: val = NULL; } else { /* Paranoia. What if user entered 9999999999999 * which fits in arith_t but not int? */ - if (len >= INT_MAX) + if (len > INT_MAX) len = INT_MAX; val = to_be_freed = xstrndup(val + beg, len); } -- cgit v1.2.3-55-g6feb From 00eb23b47aa79461b913b320eba3c95b90e6eec4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 21 Dec 2020 21:36:58 +0100 Subject: bc: do not allocate line editing state until needed function old new delta xc_read_line 324 353 +29 free_line_input_t 34 39 +5 xc_vm_init 656 640 -16 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 34/-16) Total: 18 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 4 ++++ libbb/lineedit.c | 18 +++++++++++------- miscutils/bc.c | 37 ++++++++++++++++++------------------- shell/ash.c | 3 +-- shell/hush.c | 3 +-- 5 files changed, 35 insertions(+), 30 deletions(-) (limited to 'shell') diff --git a/include/libbb.h b/include/libbb.h index 1c3d905b6..cae54658b 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1906,7 +1906,11 @@ enum { FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION, }; line_input_t *new_line_input_t(int flags) FAST_FUNC; +#if ENABLE_FEATURE_EDITING_SAVEHISTORY void free_line_input_t(line_input_t *n) FAST_FUNC; +#else +# define free_line_input_t(n) free(n) +#endif /* * maxsize must be >= 2. * Returns: diff --git a/libbb/lineedit.c b/libbb/lineedit.c index c3b5738e2..b3e7abac5 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -1417,15 +1417,19 @@ void FAST_FUNC show_history(const line_input_t *st) printf("%4d %s\n", i, st->history[i]); } +# if ENABLE_FEATURE_EDITING_SAVEHISTORY void FAST_FUNC free_line_input_t(line_input_t *n) { -# if ENABLE_FEATURE_EDITING_SAVEHISTORY - int i = n->cnt_history; - while (i > 0) - free(n->history[--i]); -#endif - free(n); + if (n) { + int i = n->cnt_history; + while (i > 0) + free(n->history[--i]); + free(n); + } } +# else +/* #defined to free() in libbb.h */ +# endif # if ENABLE_FEATURE_EDITING_SAVEHISTORY /* We try to ensure that concurrent additions to the history @@ -1506,7 +1510,7 @@ void save_history(line_input_t *st) { FILE *fp; - if (!st->hist_file) + if (!st || !st->hist_file) return; if (st->cnt_history <= st->cnt_history_in_file) return; diff --git a/miscutils/bc.c b/miscutils/bc.c index f339b895c..1227e2d13 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -2545,6 +2545,8 @@ static void xc_read_line(BcVec *vec, FILE *fp) # if ENABLE_FEATURE_EDITING if (G_ttyin && fp == stdin) { int n, i; + if (!G.line_input_state) + G.line_input_state = new_line_input_t(DO_HISTORY); # define line_buf bb_common_bufsiz1 n = read_line_input(G.line_input_state, "", line_buf, COMMON_BUFSIZE); if (n <= 0) { // read errors or EOF, or ^D, or ^C @@ -6872,22 +6874,6 @@ static BC_STATUS zxc_program_exec(void) } #define zxc_program_exec(...) (zxc_program_exec(__VA_ARGS__) COMMA_SUCCESS) -static unsigned xc_vm_envLen(const char *var) -{ - char *lenv; - unsigned len; - - lenv = getenv(var); - len = BC_NUM_PRINT_WIDTH; - if (!lenv) return len; - - len = bb_strtou(lenv, NULL, 10) - 1; - if (errno || len < 2 || len >= INT_MAX) - len = BC_NUM_PRINT_WIDTH; - - return len; -} - static BC_STATUS zxc_vm_process(const char *text) { BcStatus s; @@ -7377,12 +7363,25 @@ static void xc_program_init(void) bc_char_vec_init(&G.input_buffer); } +static unsigned xc_vm_envLen(const char *var) +{ + char *lenv; + unsigned len; + + lenv = getenv(var); + len = BC_NUM_PRINT_WIDTH; + if (!lenv) return len; + + len = bb_strtou(lenv, NULL, 10) - 1; + if (errno || len < 2 || len >= INT_MAX) + len = BC_NUM_PRINT_WIDTH; + + return len; +} + static int xc_vm_init(const char *env_len) { G.prog.len = xc_vm_envLen(env_len); -#if ENABLE_FEATURE_EDITING - G.line_input_state = new_line_input_t(DO_HISTORY); -#endif bc_vec_init(&G.files, sizeof(char *), NULL); xc_program_init(); diff --git a/shell/ash.c b/shell/ash.c index 87d329f87..f4d296289 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -14177,8 +14177,7 @@ exitshell(void) char *p; #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT - if (line_input_state) - save_history(line_input_state); + save_history(line_input_state); /* may be NULL */ #endif savestatus = exitstatus; TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus)); diff --git a/shell/hush.c b/shell/hush.c index a8f7237d5..f0f0da746 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2056,8 +2056,7 @@ static sighandler_t pick_sighandler(unsigned sig) static void hush_exit(int exitcode) { #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT - if (G.line_input_state) - save_history(G.line_input_state); + save_history(G.line_input_state); /* may be NULL */ #endif fflush_all(); -- cgit v1.2.3-55-g6feb From 0ab2dd4f28bfcfc0a8043c6b30fba6dca806dcb9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 23 Dec 2020 02:22:08 +0100 Subject: hush: fix comment Signed-off-by: Denys Vlasenko --- shell/hush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index f0f0da746..dec5d544b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -10155,7 +10155,7 @@ int hush_main(int argc, char **argv) break; switch (opt) { case 'c': - /* Note: -c is not a param with option! + /* Note: -c is not an option with param! * "hush -c -l SCRIPT" is valid. "hush -cSCRIPT" is not. */ G.opt_c = 1; -- cgit v1.2.3-55-g6feb From 93e2a22482b72b3076377f71347e3dd07d7dd2f8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 23 Dec 2020 12:23:21 +0100 Subject: shell: for signal exitcode, use 128 | sig, not 128 + sig - MIPS has signal 128 function old new delta wait_for_child_or_signal 213 214 +1 refill_HFILE_and_getc 89 88 -1 getstatus 97 96 -1 builtin_wait 339 337 -2 checkjobs 187 183 -4 process_wait_result 450 444 -6 waitcmd 290 281 -9 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/6 up/down: 1/-23) Total: -22 bytes Signed-off-by: Denys Vlasenko --- shell/ash.c | 6 +++--- shell/hush.c | 28 +++++++++++++++------------- 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index f4d296289..aa2a93bca 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -4610,7 +4610,7 @@ getstatus(struct job *job) job->sigint = 1; #endif } - retval += 128; + retval |= 128; } TRACE(("getstatus: job %d, nproc %d, status 0x%x, retval 0x%x\n", jobno(job), job->nprocs, status, retval)); @@ -4676,7 +4676,7 @@ waitcmd(int argc UNUSED_PARAM, char **argv) if (status != -1 && !WIFSTOPPED(status)) { retval = WEXITSTATUS(status); if (WIFSIGNALED(status)) - retval = WTERMSIG(status) + 128; + retval = 128 | WTERMSIG(status); goto ret; } } @@ -4711,7 +4711,7 @@ waitcmd(int argc UNUSED_PARAM, char **argv) ret: return retval; sigout: - retval = 128 + pending_sig; + retval = 128 | pending_sig; return retval; } diff --git a/shell/hush.c b/shell/hush.c index dec5d544b..6b8f1c88c 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1656,12 +1656,12 @@ static int refill_HFILE_and_getc(HFILE *fp) return EOF; } /* Try to buffer more input */ - fp->cur = fp->buf; n = safe_read(fp->fd, fp->buf, sizeof(fp->buf)); if (n < 0) { bb_simple_perror_msg("read error"); n = 0; } + fp->cur = fp->buf; fp->end = fp->buf + n; if (n == 0) { /* EOF/error */ @@ -2651,7 +2651,7 @@ static int get_user_input(struct in_str *i) /* ^C or SIGINT: return EOF */ /* bash prints ^C even on real SIGINT (non-kbd generated) */ write(STDOUT_FILENO, "^C\n", 3); - G.last_exitcode = 128 + SIGINT; + G.last_exitcode = 128 | SIGINT; i->p = NULL; i->peek_buf[0] = r = EOF; return r; @@ -2685,7 +2685,7 @@ static int get_user_input(struct in_str *i) */ check_and_run_traps(); if (G.flag_SIGINT) - G.last_exitcode = 128 + SIGINT; + G.last_exitcode = 128 | SIGINT; if (r != '\0') break; } @@ -8756,9 +8756,10 @@ static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status) puts(sig == SIGINT || sig == SIGPIPE ? "" : strsignal(sig)); } /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */ - /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here? - * Maybe we need to use sig | 128? */ - ex = sig + 128; + /* MIPS has 128 sigs (1..128), if sig==128, + * 128 + sig would result in exitcode 256 -> 0! + */ + ex = 128 | sig; } fg_pipe->cmds[i].cmd_exitcode = ex; } else { @@ -8805,7 +8806,8 @@ static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status) /* child exited */ int rcode = WEXITSTATUS(status); if (WIFSIGNALED(status)) - rcode = 128 + WTERMSIG(status); + /* NB: not 128 + sig, MIPS has sig 128 */ + rcode = 128 | WTERMSIG(status); pi->cmds[i].cmd_exitcode = rcode; if (G.last_bg_pid == pi->cmds[i].pid) G.last_bg_pid_exitcode = rcode; @@ -8925,10 +8927,10 @@ static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid) debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status); rcode = WEXITSTATUS(status); if (WIFSIGNALED(status)) - rcode = 128 + WTERMSIG(status); + rcode = 128 | WTERMSIG(status); if (WIFSTOPPED(status)) - /* bash: "cmd & wait $!" and cmd stops: $? = 128 + stopsig */ - rcode = 128 + WSTOPSIG(status); + /* bash: "cmd & wait $!" and cmd stops: $? = 128 | stopsig */ + rcode = 128 | WSTOPSIG(status); rcode++; break; /* "wait PID" called us, give it exitcode+1 */ } @@ -9318,7 +9320,7 @@ static NOINLINE int run_pipe(struct pipe *pi) * during builtin/nofork. */ if (sigismember(&G.pending_set, SIGINT)) - rcode = 128 + SIGINT; + rcode = 128 | SIGINT; } free(argv_expanded); IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;) @@ -11718,7 +11720,7 @@ static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid sig = check_and_run_traps(); if (sig /*&& sig != SIGCHLD - always true */) { /* Do this for any (non-ignored) signal, not only for ^C */ - ret = 128 + sig; + ret = 128 | sig; break; } /* SIGCHLD, or no signal, or ignored one, such as SIGQUIT. Repeat */ @@ -11818,7 +11820,7 @@ static int FAST_FUNC builtin_wait(char **argv) process_wait_result(NULL, pid, status); ret = WEXITSTATUS(status); if (WIFSIGNALED(status)) - ret = 128 + WTERMSIG(status); + ret = 128 | WTERMSIG(status); } } while (*++argv); -- cgit v1.2.3-55-g6feb From a7b52d26c435c35336ddc5ff93d5680e648345c8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 23 Dec 2020 12:38:03 +0100 Subject: hush: fix fallout from tweaking ${var:START:LEN} code function old new delta expand_one_var 2344 2353 +9 Signed-off-by: Denys Vlasenko --- shell/hush.c | 2 +- shell/hush_test/hush-vars/var_bash_repl_empty_var.right | 1 + shell/hush_test/hush-vars/var_bash_repl_empty_var.tests | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index 6b8f1c88c..9403e1f6c 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -6617,7 +6617,7 @@ static NOINLINE int expand_one_var(o_string *output, int n, exp_word = p; p = strchr(p, SPECIAL_VAR_SYMBOL); *p = '\0'; - vallen = strlen(val); + vallen = val ? strlen(val) : 0; if (beg < 0) { /* negative beg counts from the end */ beg = (arith_t)vallen + beg; diff --git a/shell/hush_test/hush-vars/var_bash_repl_empty_var.right b/shell/hush_test/hush-vars/var_bash_repl_empty_var.right index 892916783..a8d1a3bef 100644 --- a/shell/hush_test/hush-vars/var_bash_repl_empty_var.right +++ b/shell/hush_test/hush-vars/var_bash_repl_empty_var.right @@ -1,2 +1,3 @@ +w Ok:0 diff --git a/shell/hush_test/hush-vars/var_bash_repl_empty_var.tests b/shell/hush_test/hush-vars/var_bash_repl_empty_var.tests index 73a43d38e..22aaba560 100755 --- a/shell/hush_test/hush-vars/var_bash_repl_empty_var.tests +++ b/shell/hush_test/hush-vars/var_bash_repl_empty_var.tests @@ -1,3 +1,5 @@ +unset v +echo ${v/*/w} v='' echo ${v/*/w} echo Ok:$? -- cgit v1.2.3-55-g6feb From 649acb9e235d1fb04e060cf0638bf9d28bb6fd7f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 23 Dec 2020 15:29:13 +0100 Subject: hush: fix PS1 prompth in !EDITING config Signed-off-by: Denys Vlasenko --- shell/hush.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index 9403e1f6c..c4381f7a7 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2619,7 +2619,7 @@ static const char *setup_prompt_string(void) /* bash uses $PWD value, even if it is set by user. * It uses current dir only if PWD is unset. * We always use current dir. */ - G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#'); + prompt_str = G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#'); } # endif debug_printf("prompt_str '%s'\n", prompt_str); @@ -2709,14 +2709,14 @@ static int fgetc_interactive(struct in_str *i) } return ch; } -#else +#else /* !INTERACTIVE */ static ALWAYS_INLINE int fgetc_interactive(struct in_str *i) { int ch; do ch = hfgetc(i->file); while (ch == '\0'); return ch; } -#endif /* INTERACTIVE */ +#endif /* !INTERACTIVE */ static int i_getch(struct in_str *i) { -- cgit v1.2.3-55-g6feb From 18bcaf374cc8eb7bb1db22a1163dc7d38ee6c7c0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 23 Dec 2020 23:01:18 +0100 Subject: hush: revert "make interactive ^C break out of PS2 mode" It made ^C break out of the entire shell, if we aren't in PS2 mode. Need a better idea. function old new delta expand_one_var 2344 2353 +9 syntax_error_unterm_ch 21 29 +8 parse_dollar 817 824 +7 parse_stream 2251 2238 -13 fgetc_interactive 249 227 -22 syntax_error_unterm_str 26 - -26 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 3/2 up/down: 24/-61) Total: -37 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index c4381f7a7..e0b519217 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -916,9 +916,6 @@ struct globals { char opt_c; #if ENABLE_HUSH_INTERACTIVE smallint promptmode; /* 0: PS1, 1: PS2 */ -# if ENABLE_FEATURE_EDITING - smallint flag_ctrlC; /* when set, suppresses syntax error messages */ -# endif #endif smallint flag_SIGINT; #if ENABLE_HUSH_LOOPS @@ -1428,10 +1425,7 @@ static void syntax_error_at(unsigned lineno UNUSED_PARAM, const char *msg) static void syntax_error_unterm_str(unsigned lineno UNUSED_PARAM, const char *s) { -#if ENABLE_FEATURE_EDITING - if (!G.flag_ctrlC) -#endif - bb_error_msg("syntax error: unterminated %s", s); + bb_error_msg("syntax error: unterminated %s", s); //? source4.tests fails: in bash, echo ${^} in script does not terminate the script // die_if_script(); } @@ -2642,19 +2636,15 @@ static int get_user_input(struct in_str *i) ); /* read_line_input intercepts ^C, "convert" it to SIGINT */ if (r == 0) { - G.flag_ctrlC = 1; raise(SIGINT); } check_and_run_traps(); if (r != 0 && !G.flag_SIGINT) break; - /* ^C or SIGINT: return EOF */ + /* ^C or SIGINT: repeat */ /* bash prints ^C even on real SIGINT (non-kbd generated) */ write(STDOUT_FILENO, "^C\n", 3); G.last_exitcode = 128 | SIGINT; - i->p = NULL; - i->peek_buf[0] = r = EOF; - return r; } if (r < 0) { /* EOF/error detected */ @@ -5266,16 +5256,7 @@ static struct pipe *parse_stream(char **pstring, ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); if (ch == EOF) { struct pipe *pi; -#if ENABLE_FEATURE_EDITING - if (G.flag_ctrlC) { - /* testcase: interactively entering - * 'qwe ^C - * should not leave input in PS2 mode, waiting to close single quote. - */ - G.flag_ctrlC = 0; - goto parse_error; - } -#endif + if (heredoc_cnt) { syntax_error_unterm_str("here document"); goto parse_error_exitcode1; -- cgit v1.2.3-55-g6feb From 521220ed1aa63e53e2f30042ae8f00f683e2254d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 23 Dec 2020 23:44:55 +0100 Subject: hush: fix ^C in INTERACTIVE, !EDITING config function old new delta refill_HFILE_and_getc 88 170 +82 fgetc_interactive 226 250 +24 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 106/0) Total: 106 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index e0b519217..d3444c556 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1649,6 +1649,26 @@ static int refill_HFILE_and_getc(HFILE *fp) /* Already saw EOF */ return EOF; } +#if ENABLE_HUSH_INTERACTIVE && !ENABLE_FEATURE_EDITING + /* If user presses ^C, read() restarts after SIGINT (we use SA_RESTART). + * IOW: ^C will not immediately stop line input. + * But poll() is different: it does NOT restart after signals. + */ + if (fp == G.HFILE_stdin) { + struct pollfd pfd[1]; + pfd[0].fd = fp->fd; + pfd[0].events = POLLIN; + n = poll(pfd, 1, -1); + if (n < 0 + /*&& errno == EINTR - assumed true */ + && sigismember(&G.pending_set, SIGINT) + ) { + return '\0'; + } + } +#else +/* if FEATURE_EDITING=y, we do not use this routine for interactive input */ +#endif /* Try to buffer more input */ n = safe_read(fp->fd, fp->buf, sizeof(fp->buf)); if (n < 0) { @@ -2090,7 +2110,6 @@ static void hush_exit(int exitcode) #endif } - //TODO: return a mask of ALL handled sigs? static int check_and_run_traps(void) { @@ -2665,19 +2684,23 @@ static int get_user_input(struct in_str *i) */ check_and_run_traps(); fputs(prompt_str, stdout); + fflush_all(); } - fflush_all(); -//FIXME: here ^C or SIGINT will have effect only after r = hfgetc(i->file); /* In !ENABLE_FEATURE_EDITING we don't use read_line_input, * no ^C masking happens during fgetc, no special code for ^C: * it generates SIGINT as usual. */ check_and_run_traps(); - if (G.flag_SIGINT) - G.last_exitcode = 128 | SIGINT; - if (r != '\0') + if (r != '\0' && !G.flag_SIGINT) break; + if (G.flag_SIGINT) { + /* ^C or SIGINT: repeat */ + /* bash prints ^C even on real SIGINT (non-kbd generated) */ + /* kernel prints "^C" itself, just print newline: */ + write(STDOUT_FILENO, "\n", 1); + G.last_exitcode = 128 | SIGINT; + } } return r; # endif -- cgit v1.2.3-55-g6feb From 51a471d05d637e928ed26b0240645ff3e51ef396 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 24 Dec 2020 00:22:24 +0100 Subject: ash: change "clear ungetc counter on syntax errors" fix to match dash function old new delta ash_main 1203 1210 +7 raise_exception 39 26 -13 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 7/-13) Total: -6 bytes Signed-off-by: Denys Vlasenko --- shell/ash.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index aa2a93bca..f16d7fb6a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -636,8 +636,6 @@ raise_exception(int e) abort(); #endif INT_OFF; - /* Prevent this: ";l" -> syntax error, then "s" -> runs "ls" */ - g_parsefile->unget = 0; exception_type = e; longjmp(exception_handler->loc, 1); } @@ -14161,6 +14159,7 @@ reset(void) /* from input.c: */ g_parsefile->left_in_buffer = 0; g_parsefile->left_in_line = 0; /* clear input buffer */ + g_parsefile->unget = 0; popallfiles(); /* from var.c: */ -- cgit v1.2.3-55-g6feb From 46a71dc30c62dde71d4e6714790b40187d378e82 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 25 Dec 2020 18:49:29 +0100 Subject: hush: if !EDITING, do not regenerate prompt for every input char function old new delta fgetc_interactive 261 258 -3 pseudo_exec_argv 406 399 -7 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-10) Total: -10 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index d3444c556..3bdbe26d8 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2640,11 +2640,14 @@ static const char *setup_prompt_string(void) } static int get_user_input(struct in_str *i) { +# if ENABLE_FEATURE_EDITING + /* In EDITING case, this function reads next input line, + * saves it in i->p, then returns 1st char of it. + */ int r; const char *prompt_str; prompt_str = setup_prompt_string(); -# if ENABLE_FEATURE_EDITING for (;;) { reinit_unicode_for_hush(); G.flag_SIGINT = 0; @@ -2674,9 +2677,15 @@ static int get_user_input(struct in_str *i) i->p = G.user_input_buf; return (unsigned char)*i->p++; # else + /* In !EDITING case, this function gets called for every char. + * Buffering happens deeper in the call chain, in hfgetc(i->file). + */ + int r; + for (;;) { G.flag_SIGINT = 0; if (i->last_char == '\0' || i->last_char == '\n') { + const char *prompt_str = setup_prompt_string(); /* Why check_and_run_traps here? Try this interactively: * $ trap 'echo INT' INT; (sleep 2; kill -INT $$) & * $ <[enter], repeatedly...> @@ -8171,7 +8180,6 @@ static void exec_function(char ***to_free, /* On MMU, funcp->body is always non-NULL */ n = run_list(funcp->body); - fflush_all(); _exit(n); # else //? close_saved_fds_and_FILE_fds(); @@ -8246,7 +8254,6 @@ static void exec_builtin(char ***to_free, { #if BB_MMU int rcode; - fflush_all(); //? close_saved_fds_and_FILE_fds(); rcode = x->b_function(argv); fflush_all(); @@ -10039,8 +10046,8 @@ int hush_main(int argc, char **argv) #endif cached_getpid = getpid(); /* for tcsetpgrp() during init */ - G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ - G.root_ppid = getppid(); /* for $$PPID (NOMMU can override) */ + G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ + G.root_ppid = getppid(); /* for $PPID (NOMMU can override) */ /* Deal with HUSH_VERSION */ debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); -- cgit v1.2.3-55-g6feb From 1237d627e9fd996cc3d96ba72629371739fef776 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 25 Dec 2020 19:01:49 +0100 Subject: hush: fix this case: echo "SCRIPT" | hush Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-misc/piped_input.right | 2 ++ shell/ash_test/ash-misc/piped_input.tests | 3 +++ shell/hush.c | 6 +++++- shell/hush_test/hush-misc/piped_input.right | 2 ++ shell/hush_test/hush-misc/piped_input.tests | 3 +++ 5 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 shell/ash_test/ash-misc/piped_input.right create mode 100755 shell/ash_test/ash-misc/piped_input.tests create mode 100644 shell/hush_test/hush-misc/piped_input.right create mode 100755 shell/hush_test/hush-misc/piped_input.tests (limited to 'shell') diff --git a/shell/ash_test/ash-misc/piped_input.right b/shell/ash_test/ash-misc/piped_input.right new file mode 100644 index 000000000..7b8bf6758 --- /dev/null +++ b/shell/ash_test/ash-misc/piped_input.right @@ -0,0 +1,2 @@ +TEST +One:1 diff --git a/shell/ash_test/ash-misc/piped_input.tests b/shell/ash_test/ash-misc/piped_input.tests new file mode 100755 index 000000000..ec7e49837 --- /dev/null +++ b/shell/ash_test/ash-misc/piped_input.tests @@ -0,0 +1,3 @@ +exed 2>&1 +echo 'echo TEST; false' | $THIS_SH +echo One:$? diff --git a/shell/hush.c b/shell/hush.c index 3bdbe26d8..f9a295e8d 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -7787,7 +7787,11 @@ static void restore_redirects(struct squirrel *sq) free(sq); } if (G.HFILE_stdin - && G.HFILE_stdin->fd != STDIN_FILENO + && G.HFILE_stdin->fd > STDIN_FILENO + /* we compare > STDIN, not == STDIN, since hfgetc() + * closes fd and sets ->fd to -1 if EOF is reached. + * Testcase: echo 'pwd' | hush + */ ) { /* Testcase: interactive "read r fd to e.g. 10, diff --git a/shell/hush_test/hush-misc/piped_input.right b/shell/hush_test/hush-misc/piped_input.right new file mode 100644 index 000000000..7b8bf6758 --- /dev/null +++ b/shell/hush_test/hush-misc/piped_input.right @@ -0,0 +1,2 @@ +TEST +One:1 diff --git a/shell/hush_test/hush-misc/piped_input.tests b/shell/hush_test/hush-misc/piped_input.tests new file mode 100755 index 000000000..ec7e49837 --- /dev/null +++ b/shell/hush_test/hush-misc/piped_input.tests @@ -0,0 +1,3 @@ +exed 2>&1 +echo 'echo TEST; false' | $THIS_SH +echo One:$? -- cgit v1.2.3-55-g6feb From cad20ced8603f2d4c1ff13fbf01cdccc9cb1b7aa Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 25 Dec 2020 19:08:16 +0100 Subject: typo fix Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-misc/piped_input.tests | 2 +- shell/hush_test/hush-misc/piped_input.tests | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'shell') diff --git a/shell/ash_test/ash-misc/piped_input.tests b/shell/ash_test/ash-misc/piped_input.tests index ec7e49837..929fec0db 100755 --- a/shell/ash_test/ash-misc/piped_input.tests +++ b/shell/ash_test/ash-misc/piped_input.tests @@ -1,3 +1,3 @@ -exed 2>&1 +exec 2>&1 echo 'echo TEST; false' | $THIS_SH echo One:$? diff --git a/shell/hush_test/hush-misc/piped_input.tests b/shell/hush_test/hush-misc/piped_input.tests index ec7e49837..929fec0db 100755 --- a/shell/hush_test/hush-misc/piped_input.tests +++ b/shell/hush_test/hush-misc/piped_input.tests @@ -1,3 +1,3 @@ -exed 2>&1 +exec 2>&1 echo 'echo TEST; false' | $THIS_SH echo One:$? -- cgit v1.2.3-55-g6feb From c7ef8187688b0e7f92d19b3fed2c4ecffe39a688 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 27 Dec 2020 16:04:54 +0100 Subject: hush: make comment more clear Signed-off-by: Denys Vlasenko --- shell/hush.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index f9a295e8d..f5cbbc39f 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -6694,12 +6694,13 @@ static NOINLINE int expand_one_var(o_string *output, int n, * * Word-splitting and single quote behavior: * - * $ f() { for i; do echo "|$i|"; done; }; + * $ f() { for i; do echo "|$i|"; done; } * - * $ x=; f ${x:?'x y' z} - * bash: x: x y z #BUG: does not abort, ${} results in empty expansion + * $ x=; f ${x:?'x y' z}; echo $? + * bash: x: x y z # neither f nor "echo $?" executes + * (if interactive, bash does not exit, but merely aborts to prompt. $? is set to 1) * $ x=; f "${x:?'x y' z}" - * bash: x: x y z # dash prints: dash: x: 'x y' z #BUG: does not abort, ${} results in "" + * bash: x: x y z # dash prints: dash: x: 'x y' z * * $ x=; f ${x:='x y' z} * |x| -- cgit v1.2.3-55-g6feb From 77a51a2709de1b646ab493f0bf771d896de6efc2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 29 Dec 2020 16:53:11 +0100 Subject: randomconfig fixes Signed-off-by: Denys Vlasenko --- libbb/procps.c | 2 +- loginutils/login.c | 4 ++-- miscutils/dc.c | 2 +- miscutils/devfsd.c | 4 ++-- miscutils/i2c_tools.c | 6 ++++-- networking/libiproute/ipaddress.c | 6 ++++++ networking/telnet.c | 4 ++++ networking/traceroute.c | 2 +- runit/runsv.c | 18 +++++++++++++----- shell/hush.c | 4 +++- testsuite/mount.tests | 2 ++ testsuite/xargs.tests | 2 +- util-linux/fdisk.c | 7 +++++-- 13 files changed, 45 insertions(+), 18 deletions(-) (limited to 'shell') diff --git a/libbb/procps.c b/libbb/procps.c index 975e0d4dc..75969947b 100644 --- a/libbb/procps.c +++ b/libbb/procps.c @@ -177,6 +177,7 @@ static char *skip_fields(char *str, int count) } #endif +#if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP static char* skip_whitespace_if_prefixed_with(char *buf, const char *prefix) { char *tp = is_prefixed_with(buf, prefix); @@ -186,7 +187,6 @@ static char* skip_whitespace_if_prefixed_with(char *buf, const char *prefix) return tp; } -#if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, void (*cb)(struct smaprec *, void *), void *data) { diff --git a/loginutils/login.c b/loginutils/login.c index de05631d2..21c32fc25 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -341,7 +341,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_LOGIN_SESSION_AS_CHILD pid_t child_pid; #endif - pid_t my_pid; + IF_FEATURE_UTMP(pid_t my_pid;) INIT_G(); @@ -524,7 +524,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) if (pw->pw_uid != 0) die_if_nologin(); - my_pid = getpid(); + IF_FEATURE_UTMP(my_pid = getpid();) update_utmp(my_pid, USER_PROCESS, short_tty, username, run_by_root ? opt_host : NULL); #if ENABLE_LOGIN_SESSION_AS_CHILD diff --git a/miscutils/dc.c b/miscutils/dc.c index 51376dd75..e94dc39e0 100644 --- a/miscutils/dc.c +++ b/miscutils/dc.c @@ -100,7 +100,7 @@ static void mod(void) * 0 */ if (d == 0) { - bb_error_msg("remainder by zero"); + bb_simple_error_msg("remainder by zero"); pop(); push(0); return; diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index 17d8fb6b9..e5bb8a2d8 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c @@ -362,7 +362,7 @@ static const char bb_msg_variable_not_found[] ALIGN1 = "variable: %s not found"; static void safe_memcpy(char *dest, const char *src, int len) { - memcpy(dest , src, len); + memcpy(dest, src, len); dest[len] = '\0'; } @@ -1106,7 +1106,7 @@ static int copy_inode(const char *destpath, const struct stat *dest_stat, do_chown: if (chown(destpath, source_stat->st_uid, source_stat->st_gid) == 0) return TRUE; - /*break;*/ + /*break;*/ } return FALSE; } /* End Function copy_inode */ diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 57cac5d47..cda17ee00 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -273,7 +273,7 @@ static int i2c_bus_lookup(const char *bus_str) return xstrtou_range(bus_str, 10, 0, 0xfffff); } -#if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP || ENABLE_I2CTRANSFER +#if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP static int i2c_parse_bus_addr(const char *addr_str) { /* Slave address must be in range 0x03 - 0x77. */ @@ -286,14 +286,16 @@ static void i2c_set_pec(int fd, int pec) itoptr(pec ? 1 : 0), "can't set PEC"); } +#endif +#if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP || ENABLE_I2CTRANSFER static void i2c_set_slave_addr(int fd, int addr, int force) { ioctl_or_perror_and_die(fd, force ? I2C_SLAVE_FORCE : I2C_SLAVE, itoptr(addr), "can't set address to 0x%02x", addr); } -#endif /* ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP */ +#endif #if ENABLE_I2CGET || ENABLE_I2CSET static int i2c_parse_data_addr(const char *data_addr) diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index 71e8fb6a7..91fabb1fd 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -21,6 +21,12 @@ #define IFF_LOWER_UP 0x10000 /* driver signals L1 up */ #endif +#ifndef IFA_F_NOPREFIXROUTE +# define IFA_FLAGS 8 +/* ifa_flags */ +# define IFA_F_NOPREFIXROUTE 0x200 +#endif + struct filter_t { char *label; /* Flush cmd buf. If !NULL, print_addrinfo() constructs flush commands in it */ diff --git a/networking/telnet.c b/networking/telnet.c index 19a414b30..7a0253525 100644 --- a/networking/telnet.c +++ b/networking/telnet.c @@ -368,12 +368,16 @@ static void put_iac2_msb_lsb(unsigned x_y) } #define put_iac2_x_y(x,y) put_iac2_msb_lsb(((x)<<8) + (y)) +#if ENABLE_FEATURE_TELNET_WIDTH \ + || ENABLE_FEATURE_TELNET_TTYPE \ + || ENABLE_FEATURE_TELNET_AUTOLOGIN static void put_iac4_msb_lsb(unsigned x_y_z_t) { put_iac2_msb_lsb(x_y_z_t >> 16); put_iac2_msb_lsb(x_y_z_t); /* "... & 0xffff" is implicit */ } #define put_iac4_x_y_z_t(x,y,z,t) put_iac4_msb_lsb(((x)<<24) + ((y)<<16) + ((z)<<8) + (t)) +#endif static void put_iac3_IAC_x_y_merged(unsigned wwdd_and_c) { diff --git a/networking/traceroute.c b/networking/traceroute.c index ec3ac8b6f..3f1a9ab46 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -483,7 +483,7 @@ wait_for_reply(unsigned *timestamp_us, int *left_ms) &G.from_lsa->u.sa, &G.from_lsa->len); #endif if (read_len < 0) - bb_perror_msg_and_die("recv"); + bb_simple_perror_msg_and_die("recv"); t = monotonic_us(); *left_ms -= (t - *timestamp_us) / 1000; *timestamp_us = t; diff --git a/runit/runsv.c b/runit/runsv.c index 7e22862cd..d395d4528 100644 --- a/runit/runsv.c +++ b/runit/runsv.c @@ -58,11 +58,19 @@ static void gettimeofday_ns(struct timespec *ts) #else static void gettimeofday_ns(struct timespec *ts) { - BUILD_BUG_ON(sizeof(struct timeval) != sizeof(struct timespec)); - BUILD_BUG_ON(sizeof(((struct timeval*)ts)->tv_usec) != sizeof(ts->tv_nsec)); - /* Cheat */ - gettimeofday((void*)ts, NULL); - ts->tv_nsec *= 1000; + if (sizeof(struct timeval) == sizeof(struct timespec) + && sizeof(((struct timeval*)ts)->tv_usec) == sizeof(ts->tv_nsec) + ) { + /* Cheat */ + gettimeofday((void*)ts, NULL); + ts->tv_nsec *= 1000; + } else { + /* For example, musl has "incompatible" layouts */ + struct timeval tv; + gettimeofday(&tv, NULL); + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; + } } #endif diff --git a/shell/hush.c b/shell/hush.c index f5cbbc39f..9fead37da 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -653,7 +653,7 @@ struct command { /* used for "[[ EXPR ]]" */ # define CMD_TEST2_SINGLEWORD_NOGLOB 2 #endif -#if ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY +#if BASH_TEST2 || ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY /* used to prevent word splitting and globbing in "export v=t*" */ # define CMD_SINGLEWORD_NOGLOB 3 #endif @@ -8762,6 +8762,7 @@ static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status) */ if (WIFSIGNALED(status)) { int sig = WTERMSIG(status); +#if ENABLE_HUSH_JOB if (G.run_list_level == 1 /* ^^^^^ Do not print in nested contexts, example: * echo `sleep 1; sh -c 'kill -9 $$'` - prints "137", NOT "Killed 137" @@ -8771,6 +8772,7 @@ static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status) /* strsignal() is for bash compat. ~600 bloat versus bbox's get_signame() */ puts(sig == SIGINT || sig == SIGPIPE ? "" : strsignal(sig)); } +#endif /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */ /* MIPS has 128 sigs (1..128), if sig==128, * 128 + sig would result in exitcode 256 -> 0! diff --git a/testsuite/mount.tests b/testsuite/mount.tests index 91c2e8b42..b6d5ebe08 100755 --- a/testsuite/mount.tests +++ b/testsuite/mount.tests @@ -34,6 +34,8 @@ umount -d "$testdir" 2>/dev/null # file input will be file called "input" # test can create a file "actual" instead of writing to stdout +# This will always fail on !CONFIG_MANDATORY_FILE_LOCKING kernels +test "$SKIP_MOUNT_MAND_TESTS" = "1" || \ testing "mount -o remount,mand" \ "mount -o loop mount.image1m $testdir "\ "&& grep -Fc $testdir Date: Wed, 30 Dec 2020 23:48:01 +0100 Subject: libbb: introduce and use xgettimeofday(), do not truncate 64-bit time_t in shells function old new delta xgettimeofday - 11 +11 get_local_var_value 280 281 +1 svlogd_main 1323 1322 -1 change_epoch 67 66 -1 timestamp_and_log 461 458 -3 hwclock_main 301 298 -3 fmt_time_bernstein_25 135 132 -3 step_time 331 326 -5 script_main 1207 1202 -5 machtime 34 28 -6 curtime 61 54 -7 ts_main 423 415 -8 nmeter_main 761 751 -10 gettime1900d 67 46 -21 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/12 up/down: 12/-73) Total: -61 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 1 + libbb/time.c | 6 +++--- libbb/xfuncs_printf.c | 11 +++++++++++ miscutils/ts.c | 4 ++-- networking/inetd.c | 2 +- networking/ntpd.c | 4 ++-- networking/traceroute.c | 2 +- procps/nmeter.c | 8 ++++---- runit/runsv.c | 4 ++-- runit/svlogd.c | 4 ++-- shell/ash.c | 10 +++++----- shell/hush.c | 10 +++++----- sysklogd/syslogd.c | 2 +- util-linux/hwclock.c | 8 ++++---- util-linux/mdev.c | 2 +- util-linux/script.c | 2 +- 16 files changed, 46 insertions(+), 34 deletions(-) (limited to 'shell') diff --git a/include/libbb.h b/include/libbb.h index cae54658b..dad6fc687 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -657,6 +657,7 @@ void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC; time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC; char *strftime_HHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC; char *strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC; +void xgettimeofday(struct timeval *tv) FAST_FUNC; void xsettimeofday(const struct timeval *tv) FAST_FUNC; diff --git a/libbb/time.c b/libbb/time.c index 74a69eefb..cf5f2e5c8 100644 --- a/libbb/time.c +++ b/libbb/time.c @@ -291,19 +291,19 @@ unsigned FAST_FUNC monotonic_sec(void) unsigned long long FAST_FUNC monotonic_ns(void) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000; } unsigned long long FAST_FUNC monotonic_us(void) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); return tv.tv_sec * 1000000ULL + tv.tv_usec; } unsigned long long FAST_FUNC monotonic_ms(void) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); return tv.tv_sec * 1000ULL + tv.tv_usec / 1000; } unsigned FAST_FUNC monotonic_sec(void) diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index aea995a5c..99596b9d0 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c @@ -720,3 +720,14 @@ void FAST_FUNC xsettimeofday(const struct timeval *tv) if (settimeofday(tv, NULL)) bb_simple_perror_msg_and_die("settimeofday"); } + +void FAST_FUNC xgettimeofday(struct timeval *tv) +{ +#if 0 + if (gettimeofday(tv, NULL)) + bb_simple_perror_msg_and_die("gettimeofday"); +#else + /* Never fails on Linux */ + gettimeofday(tv, NULL); +#endif +} diff --git a/miscutils/ts.c b/miscutils/ts.c index f2d367654..6e5d77bda 100644 --- a/miscutils/ts.c +++ b/miscutils/ts.c @@ -47,13 +47,13 @@ int ts_main(int argc UNUSED_PARAM, char **argv) #define date_buf bb_common_bufsiz1 setup_common_bufsiz(); - gettimeofday(&base, NULL); + xgettimeofday(&base); while ((line = xmalloc_fgets(stdin)) != NULL) { struct timeval ts; struct tm tm_time; - gettimeofday(&ts, NULL); + xgettimeofday(&ts); if (opt) { /* -i and/or -s */ struct timeval ts1 = ts1; diff --git a/networking/inetd.c b/networking/inetd.c index 9f5a436d6..febfb7b73 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -1701,7 +1701,7 @@ static uint32_t machtime(void) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); return htonl((uint32_t)(tv.tv_sec + 2208988800U)); } /* ARGSUSED */ diff --git a/networking/ntpd.c b/networking/ntpd.c index 5a540a391..46d8f3495 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -560,7 +560,7 @@ static double gettime1900d(void) { struct timeval tv; - gettimeofday(&tv, NULL); /* never fails */ + xgettimeofday(&tv); G.cur_time = tv.tv_sec + (1.0e-6 * tv.tv_usec) + OFFSET_1900_1970; return G.cur_time; } @@ -1144,7 +1144,7 @@ step_time(double offset) char buf[sizeof("yyyy-mm-dd hh:mm:ss") + /*paranoia:*/ 4]; time_t tval; - gettimeofday(&tvc, NULL); /* never fails */ + xgettimeofday(&tvc); dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset; d_to_tv(dtime, &tvn); xsettimeofday(&tvn); diff --git a/networking/traceroute.c b/networking/traceroute.c index 3f1a9ab46..bd63e4449 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -505,7 +505,7 @@ send_probe(int seq, int ttl) struct outdata6_t *pkt = (void *) outdata; pkt->ident6 = ident; pkt->seq6 = htonl(seq); - /*gettimeofday(&pkt->tv, &tz);*/ + /*xgettimeofday(&pkt->tv);*/ icp = outicmp6; } else #endif diff --git a/procps/nmeter.c b/procps/nmeter.c index 07b7abe2f..f08938654 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -952,11 +952,11 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) reset_outbuf(); if (G.delta >= 0) { - gettimeofday(&G.tv, NULL); + xgettimeofday(&G.tv); usleep(G.delta > 1000000 ? 1000000 : G.delta - G.tv.tv_usec % G.deltanz); } - gettimeofday(&G.start, NULL); + xgettimeofday(&G.start); G.tv = G.start; while (1) { collect_info(first); @@ -971,7 +971,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) if (G.delta >= 0) { int rem; // can be commented out, will sacrifice sleep time precision a bit - gettimeofday(&G.tv, NULL); + xgettimeofday(&G.tv); if (need_seconds) rem = G.delta - ((ullong)G.tv.tv_sec*1000000 + G.tv.tv_usec) % G.deltanz; else @@ -983,7 +983,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) } usleep(rem); } - gettimeofday(&G.tv, NULL); + xgettimeofday(&G.tv); } /*return 0;*/ diff --git a/runit/runsv.c b/runit/runsv.c index d395d4528..ecab8cdf5 100644 --- a/runit/runsv.c +++ b/runit/runsv.c @@ -62,12 +62,12 @@ static void gettimeofday_ns(struct timespec *ts) && sizeof(((struct timeval*)ts)->tv_usec) == sizeof(ts->tv_nsec) ) { /* Cheat */ - gettimeofday((void*)ts, NULL); + xgettimeofday((void*)ts); ts->tv_nsec *= 1000; } else { /* For example, musl has "incompatible" layouts */ struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); ts->tv_sec = tv.tv_sec; ts->tv_nsec = tv.tv_usec * 1000; } diff --git a/runit/svlogd.c b/runit/svlogd.c index 040e71104..294e31aca 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c @@ -351,7 +351,7 @@ static void fmt_time_human_30nul(char *s, char dt_delim) struct tm *ptm; struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); ptm = gmtime_r(&tv.tv_sec, &tm); /* ^^^ using gmtime_r() instead of gmtime() to not use static data */ sprintf(s, "%04u-%02u-%02u%c%02u:%02u:%02u.%06u000", @@ -376,7 +376,7 @@ static void fmt_time_bernstein_25(char *s) struct timeval tv; unsigned sec_hi; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); sec_hi = (0x400000000000000aULL + tv.tv_sec) >> 32; tv.tv_sec = (time_t)(0x400000000000000aULL) + tv.tv_sec; tv.tv_usec *= 1000; diff --git a/shell/ash.c b/shell/ash.c index f16d7fb6a..54f004375 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -11371,10 +11371,10 @@ static void FAST_FUNC change_epoch(struct var *vepoch, const char *fmt) { struct timeval tv; - char buffer[sizeof("%lu.nnnnnn") + sizeof(long)*3]; + char buffer[sizeof("%llu.nnnnnn") + sizeof(long long)*3]; - gettimeofday(&tv, NULL); - sprintf(buffer, fmt, (unsigned long)tv.tv_sec, (unsigned)tv.tv_usec); + xgettimeofday(&tv); + sprintf(buffer, fmt, (unsigned long long)tv.tv_sec, (unsigned)tv.tv_usec); setvar(vepoch->var_text, buffer, VNOFUNC); vepoch->flags &= ~VNOFUNC; } @@ -11382,13 +11382,13 @@ change_epoch(struct var *vepoch, const char *fmt) static void FAST_FUNC change_seconds(const char *value UNUSED_PARAM) { - change_epoch(&vepochs, "%lu"); + change_epoch(&vepochs, "%llu"); } static void FAST_FUNC change_realtime(const char *value UNUSED_PARAM) { - change_epoch(&vepochr, "%lu.%06u"); + change_epoch(&vepochr, "%llu.%06u"); } #endif diff --git a/shell/hush.c b/shell/hush.c index 9fead37da..65f08659f 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1027,7 +1027,7 @@ struct globals { struct sigaction sa; char optstring_buf[sizeof("eixcs")]; #if BASH_EPOCH_VARS - char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3]; + char epoch_buf[sizeof("%llu.nnnnnn") + sizeof(long long)*3]; #endif #if ENABLE_FEATURE_EDITING char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN]; @@ -2277,13 +2277,13 @@ static const char* FAST_FUNC get_local_var_value(const char *name) { const char *fmt = NULL; if (strcmp(name, "EPOCHSECONDS") == 0) - fmt = "%lu"; + fmt = "%llu"; else if (strcmp(name, "EPOCHREALTIME") == 0) - fmt = "%lu.%06u"; + fmt = "%llu.%06u"; if (fmt) { struct timeval tv; - gettimeofday(&tv, NULL); - sprintf(G.epoch_buf, fmt, (unsigned long)tv.tv_sec, + xgettimeofday(&tv); + sprintf(G.epoch_buf, fmt, (unsigned long long)tv.tv_sec, (unsigned)tv.tv_usec); return G.epoch_buf; } diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 598f28d0c..6ddfd771a 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -842,7 +842,7 @@ static void timestamp_and_log(int pri, char *msg, int len) #if ENABLE_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS if (!timestamp) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); now = tv.tv_sec; timestamp = ctime(&now) + 4; /* skip day of week */ /* overwrite year by milliseconds, zero terminate */ diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index 25db7cdad..723b09589 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c @@ -79,7 +79,7 @@ static time_t read_rtc(const char **pp_rtcname, struct timeval *sys_tv, int utc) int before = tm_time.tm_sec; while (1) { rtc_read_tm(&tm_time, fd); - gettimeofday(sys_tv, NULL); + xgettimeofday(sys_tv); if (before != (int)tm_time.tm_sec) break; } @@ -205,7 +205,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc) int rtc; rtc = rtc_xopen(pp_rtcname, O_WRONLY); - gettimeofday(&tv, NULL); + xgettimeofday(&tv); /* Prepare tm_time */ if (sizeof(time_t) == sizeof(tv.tv_sec)) { if (utc) @@ -253,7 +253,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc) unsigned rem_usec; time_t t; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); t = tv.tv_sec; rem_usec = 1000000 - tv.tv_usec; @@ -274,7 +274,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc) } /* gmtime/localtime took some time, re-get cur time */ - gettimeofday(&tv, NULL); + xgettimeofday(&tv); if (tv.tv_sec < t /* we are still in old second */ || (tv.tv_sec == t && tv.tv_usec < adj) /* not too far into next second */ diff --git a/util-linux/mdev.c b/util-linux/mdev.c index ebf83d1a3..dbbcbc655 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -963,7 +963,7 @@ static void load_firmware(const char *firmware, const char *sysfs_path) static char *curtime(void) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); sprintf( strftime_HHMMSS(G.timestr, sizeof(G.timestr), &tv.tv_sec), ".%06u", diff --git a/util-linux/script.c b/util-linux/script.c index 4eac5e94f..963435335 100644 --- a/util-linux/script.c +++ b/util-linux/script.c @@ -172,7 +172,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) struct timeval tv; double newtime; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); newtime = tv.tv_sec + (double) tv.tv_usec / 1000000; fprintf(timing_fp, "%f %u\n", newtime - oldtime, count); oldtime = newtime; -- cgit v1.2.3-55-g6feb From 3f8ec00b0c54790283cfec675716ef4b8e00bd8a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 3 Jan 2021 10:55:39 +0100 Subject: ash: make a strdup copy of $HISTFILE for line editing Otherwise if $HISTFILE is unset or reassigned, bad things can happen. function old new delta ash_main 1210 1218 +8 Signed-off-by: Denys Vlasenko --- shell/ash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 54f004375..f9d59e50e 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -14499,7 +14499,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) if (sflag || minusc == NULL) { #if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY - if (iflag) { + if (line_input_state) { const char *hp = lookupvar("HISTFILE"); if (!hp) { hp = lookupvar("HOME"); @@ -14513,7 +14513,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) } } if (hp) - line_input_state->hist_file = hp; + line_input_state->hist_file = xstrdup(hp); # if ENABLE_FEATURE_SH_HISTFILESIZE hp = lookupvar("HISTFILESIZE"); line_input_state->max_history = size_from_HISTFILESIZE(hp); -- cgit v1.2.3-55-g6feb From 85158b600d161bea3fc9d62df8e4ecf4d642fbf0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 3 Jan 2021 12:14:58 +0100 Subject: ash: code shrink function old new delta ash_main 1218 1202 -16 Signed-off-by: Denys Vlasenko --- shell/ash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index f9d59e50e..e24b74c03 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -14312,9 +14312,9 @@ procargs(char **argv) } if (mflag == 2) mflag = iflag; + /* Unset options which weren't explicitly set or unset */ for (i = 0; i < NOPTS; i++) - if (optlist[i] == 2) - optlist[i] = 0; + optlist[i] &= 1; /* same effect as "if (optlist[i] == 2) optlist[i] = 0;" */ #if DEBUG == 2 debug = 1; #endif -- cgit v1.2.3-55-g6feb From 3b053051c7c6f1e4776fce8a97d8f6a3c54f3f0e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 4 Jan 2021 03:05:34 +0100 Subject: hush: code shrink function old new delta hush_main 1071 1066 -5 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-5) Total: -5 bytes text data bss dec hex filename 1020110 559 5020 1025689 fa699 busybox_old 1020037 559 5020 1025616 fa650 busybox_unstripped Signed-off-by: Denys Vlasenko --- shell/hush.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index 65f08659f..77f90f82f 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -10163,7 +10163,8 @@ int hush_main(int argc, char **argv) /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */ flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0; while (1) { - int opt = getopt(argc, argv, "+cexinsl" + int opt = getopt(argc, argv, "+" /* stop at 1st non-option */ + "cexinsl" #if !BB_MMU "<:$:R:V:" # if ENABLE_HUSH_FUNCTIONS @@ -10255,12 +10256,13 @@ int hush_main(int argc, char **argv) } # endif #endif - case 'n': - case 'x': - case 'e': + /*case '?': invalid option encountered (set_mode('?') will fail) */ + /*case 'n':*/ + /*case 'x':*/ + /*case 'e':*/ + default: if (set_mode(1, opt, NULL) == 0) /* no error */ break; - default: bb_show_usage(); } } /* option parsing loop */ -- cgit v1.2.3-55-g6feb From 4e039bab375a273344b6c847daa04f13d8317c04 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 4 Jan 2021 03:50:38 +0100 Subject: ash: improve --help function old new delta packed_usage 33504 33499 -5 Signed-off-by: Denys Vlasenko --- shell/ash.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index e24b74c03..37f9dd71b 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -314,9 +314,12 @@ typedef long arith_t; /* ============ Shell options */ +/* If you add/change options hare, update --help text too */ static const char *const optletters_optnames[] = { "e" "errexit", "f" "noglob", +/* bash has '-o ignoreeof', but no short synonym -I for it */ +/* (in bash, set -I disables invisible variables (what's that?)) */ "I" "ignoreeof", /* The below allowed this invocation: * ash -c 'set -i; echo $-; sleep 5; echo $-' @@ -325,9 +328,10 @@ static const char *const optletters_optnames[] = { * In our code, this is denoted by empty long name: */ "i" "", +/* (removing "i" altogether would remove it from "$-", not good) */ "m" "monitor", "n" "noexec", -/* Ditto: bash has no "set -s" */ +/* Ditto: bash has no "set -s", "set -c" */ "s" "", "c" "", "x" "xtrace", @@ -14265,7 +14269,8 @@ init(void) //usage:#define ash_trivial_usage -//usage: "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" +//usage: "[-il] [-/+Cabefmnuvx] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" +//////// comes from ^^^^^^^^^^optletters //usage:#define ash_full_usage "\n\n" //usage: "Unix shell interpreter" -- cgit v1.2.3-55-g6feb From 883cdb79a440d0425766f67aaef0cabde0a5060e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 9 Jan 2021 08:27:37 +0100 Subject: ash: fix ${unset_var/pattern/repl} function old new delta subevalvar 1349 1353 +4 Signed-off-by: Denys Vlasenko --- shell/ash.c | 3 ++- shell/ash_test/ash-vars/var_bash_repl_empty_var.right | 1 + shell/ash_test/ash-vars/var_bash_repl_empty_var.tests | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 37f9dd71b..76bf39ec2 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -7015,7 +7015,8 @@ subevalvar(char *start, char *str, int strloc, slash_pos = -1; if (repl) { slash_pos = expdest - ((char *)stackblock() + strloc); - STPUTC('/', expdest); + if (!(flag & EXP_DISCARD)) + STPUTC('/', expdest); //bb_error_msg("repl+1:'%s'", repl + 1); p = argstr(repl + 1, (flag & EXP_DISCARD) | EXP_TILDE); /* EXP_TILDE: echo "${v/x/~}" expands ~ ! */ *repl = '/'; diff --git a/shell/ash_test/ash-vars/var_bash_repl_empty_var.right b/shell/ash_test/ash-vars/var_bash_repl_empty_var.right index 892916783..cf8f088c1 100644 --- a/shell/ash_test/ash-vars/var_bash_repl_empty_var.right +++ b/shell/ash_test/ash-vars/var_bash_repl_empty_var.right @@ -1,2 +1,3 @@ + Ok:0 diff --git a/shell/ash_test/ash-vars/var_bash_repl_empty_var.tests b/shell/ash_test/ash-vars/var_bash_repl_empty_var.tests index 73a43d38e..22aaba560 100755 --- a/shell/ash_test/ash-vars/var_bash_repl_empty_var.tests +++ b/shell/ash_test/ash-vars/var_bash_repl_empty_var.tests @@ -1,3 +1,5 @@ +unset v +echo ${v/*/w} v='' echo ${v/*/w} echo Ok:$? -- cgit v1.2.3-55-g6feb From 2b7c1aa92c68524559a2067609d09309d5c09adc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 9 Jan 2021 08:46:54 +0100 Subject: ash: match bash behavior for ${empty_var/*/repl} Signed-off-by: Denys Vlasenko --- shell/ash.c | 6 +++--- shell/ash_test/ash-vars/var_bash_repl_empty_var.right | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 76bf39ec2..1aead6df4 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -7178,7 +7178,7 @@ subevalvar(char *start, char *str, int strloc, len = 0; idx = startp; end = str - 1; - while (idx < end) { + while (idx <= end) { try_to_match: loc = scanright(idx, rmesc, rmescend, str, quotes, 1); //bb_error_msg("scanright('%s'):'%s'", str, loc); @@ -7186,6 +7186,8 @@ subevalvar(char *start, char *str, int strloc, /* No match, advance */ char *restart_detect = stackblock(); skip_matching: + if (idx >= end) + break; STPUTC(*idx, expdest); if (quotes && (unsigned char)*idx == CTLESC) { idx++; @@ -7198,8 +7200,6 @@ subevalvar(char *start, char *str, int strloc, len++; rmesc++; /* continue; - prone to quadratic behavior, smarter code: */ - if (idx >= end) - break; if (str[0] == '*') { /* Pattern is "*foo". If "*foo" does not match "long_string", * it would never match "ong_string" etc, no point in trying. diff --git a/shell/ash_test/ash-vars/var_bash_repl_empty_var.right b/shell/ash_test/ash-vars/var_bash_repl_empty_var.right index cf8f088c1..a8d1a3bef 100644 --- a/shell/ash_test/ash-vars/var_bash_repl_empty_var.right +++ b/shell/ash_test/ash-vars/var_bash_repl_empty_var.right @@ -1,3 +1,3 @@ - +w Ok:0 -- cgit v1.2.3-55-g6feb