From 9bc2b6e88474a8ebb50c94f29320d343bd374928 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 10 Apr 2023 14:33:20 +0200 Subject: seq: accept negative parameters function old new delta seq_main 429 476 +47 packed_usage 34557 34538 -19 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 47/-19) Total: 28 bytes Signed-off-by: Denys Vlasenko --- coreutils/seq.c | 23 +++++++++++++++++++++-- testsuite/seq.tests | 3 +++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/coreutils/seq.c b/coreutils/seq.c index beb339d1e..c0e2d1e06 100644 --- a/coreutils/seq.c +++ b/coreutils/seq.c @@ -22,7 +22,7 @@ //usage:#define seq_full_usage "\n\n" //usage: "Print numbers from FIRST to LAST, in steps of INC.\n" //usage: "FIRST, INC default to 1.\n" -//usage: "\n -w Pad to last with leading zeros" +//usage: "\n -w Pad with leading zeros" //usage: "\n -s SEP String separator" #include "libbb.h" @@ -41,6 +41,7 @@ int seq_main(int argc, char **argv) unsigned width; unsigned frac_part; const char *sep, *opt_s = "\n"; + char *saved; unsigned opt; #if ENABLE_LOCALE_SUPPORT @@ -49,7 +50,25 @@ int seq_main(int argc, char **argv) setlocale(LC_NUMERIC, "C"); #endif - opt = getopt32(argv, "+ws:", &opt_s); + /* Cater for negative arguments: if we see one, truncate argv[] on it */ + n = 0; + for (;;) { + char c; + saved = argv[++n]; + if (!saved) + break; + if (saved[0] != '-') + break; + c = saved[1]; + if (c == '.' || (c >= '0' && c <= '9')) { + argv[n] = NULL; + break; + } + } + opt = getopt32(argv, "+ws:", &opt_s); /* "+": stop at first non-option */ + /* Restore possibly truncated argv[] */ + argv[n] = saved; + argc -= optind; argv += optind; first = increment = 1; diff --git a/testsuite/seq.tests b/testsuite/seq.tests index 1e1116c7d..d414169c9 100755 --- a/testsuite/seq.tests +++ b/testsuite/seq.tests @@ -43,4 +43,7 @@ testing "seq count down by 3 with padding" "seq -w 8 -3 04" "08\n05\n" "" "" testing "seq count by .3 with padding 1" "seq -w 09 .3 11" "09.0\n09.3\n09.6\n09.9\n10.2\n10.5\n10.8\n" "" "" testing "seq count by .3 with padding 2" "seq -w 03 .3 0004" "0003.0\n0003.3\n0003.6\n0003.9\n" "" "" +testing "seq from -4 count down by 2" "seq -4 -2 -8" "-4\n-6\n-8\n" "" "" +testing "seq from -.0 count down by .25" "seq -.0 -.25 -.9" "-0.00\n-0.25\n-0.50\n-0.75\n" "" "" + exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From 611729eff386234b09d40780cdcc21fe72f6f8b8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 10 Apr 2023 14:46:09 +0200 Subject: mkfs_vfat: do not generate same volume_id when run in rapid succession function old new delta mkfs_vfat_main 1502 1523 +21 Signed-off-by: Denys Vlasenko --- util-linux/mkfs_vfat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/util-linux/mkfs_vfat.c b/util-linux/mkfs_vfat.c index 821371953..d2db78e1d 100644 --- a/util-linux/mkfs_vfat.c +++ b/util-linux/mkfs_vfat.c @@ -267,8 +267,9 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) // cache device name device_name = argv[0]; - // default volume ID = creation time - volume_id = time(NULL); + // default volume ID: somewhat random (not crypto-strong) + // (mix in pid to avoid same IDs when run in rapid succession) + volume_id = time(NULL) ^ getpid(); // truncate to exactly 11 chars, pad with spaces sprintf(volume_label11, "%-11.11s", arg_volume_label); -- cgit v1.2.3-55-g6feb From 7362d2979434c565ae70b0ccf9d4b09d7597fb48 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 10 Apr 2023 16:30:27 +0200 Subject: ash: fix sleep built-in not running INT trap immediately on ^C function old new delta sleep_for_duration 169 149 -20 Signed-off-by: Denys Vlasenko --- libbb/duration.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/libbb/duration.c b/libbb/duration.c index 793d02f42..0024f1a66 100644 --- a/libbb/duration.c +++ b/libbb/duration.c @@ -76,16 +76,14 @@ void FAST_FUNC sleep_for_duration(duration_t duration) ts.tv_sec = duration; ts.tv_nsec = (duration - ts.tv_sec) * 1000000000; } - /* NB: if ENABLE_ASH_SLEEP, we end up here if "sleep N" - * is run in ash. ^C will still work, because ash's signal handler - * does not return (it longjumps), the below loop - * will not continue looping. - * (This wouldn't work in hush) + /* NB: ENABLE_ASH_SLEEP requires that we do NOT loop on EINTR here: + * otherwise, traps won't execute until we finish looping. */ - do { - errno = 0; - nanosleep(&ts, &ts); - } while (errno == EINTR); + //do { + // errno = 0; + // nanosleep(&ts, &ts); + //} while (errno == EINTR); + nanosleep(&ts, &ts); } #else duration_t FAST_FUNC parse_duration_str(char *str) -- cgit v1.2.3-55-g6feb From 85e4805ae94ce653d8088d6575dc01114cd00bcf Mon Sep 17 00:00:00 2001 From: Tomas Paukrt Date: Sun, 9 Apr 2023 10:18:51 +0200 Subject: appletlib: fix "warning: unused variable applet_no" Signed-off-by: Tomas Paukrt Signed-off-by: Denys Vlasenko --- libbb/appletlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index d5335d353..d9cc48423 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -918,7 +918,7 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) # endif # if NUM_APPLETS > 0 -void FAST_FUNC show_usage_if_dash_dash_help(int applet_no, char **argv) +void FAST_FUNC show_usage_if_dash_dash_help(int applet_no UNUSED_PARAM, char **argv) { /* Special case. POSIX says "test --help" * should be no different from e.g. "test --foo". -- cgit v1.2.3-55-g6feb From 200a9669fbf6f06894e4243cccc9fc11a1a6073a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 10 Apr 2023 17:26:04 +0200 Subject: seedrng: fix for glibc <= 2.24 not providing getrandom() Signed-off-by: Denys Vlasenko --- miscutils/seedrng.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/miscutils/seedrng.c b/miscutils/seedrng.c index 967741dc7..7cc855141 100644 --- a/miscutils/seedrng.c +++ b/miscutils/seedrng.c @@ -45,6 +45,20 @@ #include #include +/* Fix up glibc <= 2.24 not having getrandom() */ +#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 24 +#include +# define getrandom(...) bb_getrandom(__VA_ARGS__) +static ssize_t getrandom(void *buffer, size_t length, unsigned flags) +{ +# if defined(__NR_getrandom) + return syscall(__NR_getrandom, buffer, length, flags); +# else + return ENOSYS; +# endif +} +#endif + #ifndef GRND_INSECURE #define GRND_INSECURE 0x0004 /* Apparently some headers don't ship with this yet. */ #endif -- cgit v1.2.3-55-g6feb From cb57abb46f06f4ede8d9ccbdaac67377fdf416cf Mon Sep 17 00:00:00 2001 From: Thomas Devoogdt Date: Mon, 10 Apr 2023 19:58:15 +0200 Subject: seedrng: fix for glibc <= 2.24 not providing random header - dropped the wrong define (not sure why it was there) - not available if glibc <= 2.24 - GRND_NONBLOCK not defined if not included - ret < 0 && errno == ENOSYS has to be true to get creditable set Signed-off-by: Thomas Devoogdt Signed-off-by: Denys Vlasenko --- miscutils/seedrng.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/miscutils/seedrng.c b/miscutils/seedrng.c index 7cc855141..3bf6e2ea7 100644 --- a/miscutils/seedrng.c +++ b/miscutils/seedrng.c @@ -42,25 +42,31 @@ #include "libbb.h" #include -#include #include /* Fix up glibc <= 2.24 not having getrandom() */ #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 24 #include -# define getrandom(...) bb_getrandom(__VA_ARGS__) static ssize_t getrandom(void *buffer, size_t length, unsigned flags) { # if defined(__NR_getrandom) return syscall(__NR_getrandom, buffer, length, flags); # else - return ENOSYS; + errno = ENOSYS; + return -1; # endif } +#else +#include +#endif + +/* Apparently some headers don't ship with this yet. */ +#ifndef GRND_NONBLOCK +#define GRND_NONBLOCK 0x0001 #endif #ifndef GRND_INSECURE -#define GRND_INSECURE 0x0004 /* Apparently some headers don't ship with this yet. */ +#define GRND_INSECURE 0x0004 #endif #define DEFAULT_SEED_DIR "/var/lib/seedrng" -- cgit v1.2.3-55-g6feb From 478b5ac2bcdb5014d8e6a6e8d7647b4c599cc1a7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 11 Apr 2023 20:29:59 +0200 Subject: seq: fix yet another case of negative parameters not working Signed-off-by: Denys Vlasenko --- coreutils/seq.c | 8 ++++++-- testsuite/seq.tests | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/coreutils/seq.c b/coreutils/seq.c index c0e2d1e06..77a8aba8a 100644 --- a/coreutils/seq.c +++ b/coreutils/seq.c @@ -57,8 +57,12 @@ int seq_main(int argc, char **argv) saved = argv[++n]; if (!saved) break; - if (saved[0] != '-') - break; + if (saved[0] != '-') { + // break; // "seq -s : -1 1" won't be treated correctly + continue; + } +// "seq -s -1 1 9" is not treated correctly, but such usage +// (delimiter string which looks like negative number) is very unlikely c = saved[1]; if (c == '.' || (c >= '0' && c <= '9')) { argv[n] = NULL; diff --git a/testsuite/seq.tests b/testsuite/seq.tests index d414169c9..d0da8c119 100755 --- a/testsuite/seq.tests +++ b/testsuite/seq.tests @@ -45,5 +45,6 @@ testing "seq count by .3 with padding 2" "seq -w 03 .3 0004" "0003.0\n0003.3\n00 testing "seq from -4 count down by 2" "seq -4 -2 -8" "-4\n-6\n-8\n" "" "" testing "seq from -.0 count down by .25" "seq -.0 -.25 -.9" "-0.00\n-0.25\n-0.50\n-0.75\n" "" "" +testing "seq -s : with negative start" "seq -s : -1 1" "-1:0:1\n" "" "" exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From 550e6d8fbd05ea0ab60ff3e542327efb4e9cc254 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 12 Apr 2023 12:23:36 +0200 Subject: sleep: fix error exit when called as "sh" builtin Signed-off-by: Denys Vlasenko --- coreutils/sleep.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/coreutils/sleep.c b/coreutils/sleep.c index 667db558d..a0cee5a4a 100644 --- a/coreutils/sleep.c +++ b/coreutils/sleep.c @@ -74,7 +74,8 @@ int sleep_main(int argc UNUSED_PARAM, char **argv) ++argv; if (!*argv) { /* Without this, bare "sleep" in ash shows _ash_ --help */ - if (ENABLE_ASH_SLEEP && applet_name[0] != 's') { + /* (ash can be the "sh" applet as well, so check 2nd char) */ + if (ENABLE_ASH_SLEEP && applet_name[1] != 'l') { bb_simple_error_msg("sleep: missing operand"); return EXIT_FAILURE; } -- cgit v1.2.3-55-g6feb From 853cfe927fd656a2688ac2bfc81c69e1004c44df Mon Sep 17 00:00:00 2001 From: Akos Somfai Date: Mon, 3 Apr 2023 22:52:06 +0200 Subject: lineedit: fix crash when icanon set with -echo When icanon is set with -echo (e.g. ssh from an emacs shell) then S.state will remain null but later it will be deferenced causing ash to crash. Fix: additional check on state. Signed-off-by: Akos Somfai Signed-off-by: Denys Vlasenko --- libbb/lineedit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 625884adf..bdae10914 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -254,7 +254,7 @@ static NOINLINE const char *get_homedir_or_NULL(void) const char *home; # if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH - home = state->sh_get_var ? state->sh_get_var("HOME") : getenv("HOME"); + home = state && state->sh_get_var ? state->sh_get_var("HOME") : getenv("HOME"); # else home = getenv("HOME"); # endif @@ -2038,7 +2038,7 @@ static void parse_and_put_prompt(const char *prmt_ptr) if (!cwd_buf) { const char *home; # if EDITING_HAS_sh_get_var - cwd_buf = state->sh_get_var + cwd_buf = state && state->sh_get_var ? xstrdup(state->sh_get_var("PWD")) : xrealloc_getcwd_or_warn(NULL); # else -- cgit v1.2.3-55-g6feb From 238dab322a630b493843a6bdf3203e93db87469a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 12 Apr 2023 14:47:24 +0200 Subject: shuf: add (disabled) code to support very long numbers in -i LO-HI Signed-off-by: Denys Vlasenko --- coreutils/shuf.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/coreutils/shuf.c b/coreutils/shuf.c index 337366b45..fe0358e07 100644 --- a/coreutils/shuf.c +++ b/coreutils/shuf.c @@ -66,6 +66,12 @@ static void shuffle_lines(char **lines, unsigned numlines, unsigned outlines) } } +/* We can handle insanity like this: + * shuf -i 3333333333333333333333333333333333333333333333333333333333333123456789001-3333333333333333333333333333333333333333333333333333333333333123456789019 + * but do we want to have +200 bytes of code (~40% code growth)? + */ +#define COMMON_PREFIX_HACK 0 + int shuf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int shuf_main(int argc, char **argv) { @@ -76,6 +82,11 @@ int shuf_main(int argc, char **argv) unsigned numlines, outlines; unsigned i; char eol; +#if COMMON_PREFIX_HACK + unsigned pfx_len = 0; + unsigned padding_width = padding_width; + const char *pfx = pfx; +#endif opts = getopt32(argv, "^" OPT_STR @@ -104,10 +115,46 @@ int shuf_main(int argc, char **argv) if (!dash) { bb_error_msg_and_die("bad range '%s'", opt_i_str); } - *dash = '\0'; + *dash++ = '\0'; +#if COMMON_PREFIX_HACK + { + const char *a = opt_i_str; + const char *b = dash; + /* Skip leading zeros (they may mask that common prefix does exist) */ + while (*a == '0') a++; + while (*b == '0') b++; + /* Do we have a common prefix (long enough to bother)? */ + padding_width = strlen(a); + if (padding_width > 5 && padding_width == strlen(b)) { + /* How long is it? */ + pfx = a; + while (isdigit(*a) && *a == *b) { + a++; + b++; + } + if (*a == '\0') { + /* "123456-123456", and we 'ate' all of them */ + /* prevent trying to xatoull("") */ + a--; + b--; + } + pfx_len = a - opt_i_str; /* can end up being 0 */ + padding_width -= pfx_len; + lo = xatoull(a); + hi = xatoull(b); + } else { + /* Undo leading zero 'eating' (think "0-9") */ + a = opt_i_str; + b = dash; + } + lo = xatoull(a); + hi = xatoull(b); + } +#else lo = xatoull(opt_i_str); - hi = xatoull(dash + 1); - *dash = '-'; + hi = xatoull(dash); +#endif + dash[-1] = '-'; if (hi < lo) bb_error_msg_and_die("bad range '%s'", opt_i_str); hi -= lo; @@ -165,9 +212,14 @@ int shuf_main(int argc, char **argv) eol = '\0'; for (i = numlines - outlines; i < numlines; i++) { - if (opts & OPT_i) - printf("%llu%c", lo + (uintptr_t)lines[i], eol); - else + if (opts & OPT_i) { +#if COMMON_PREFIX_HACK + if (pfx_len != 0) + printf("%.*s%0*llu%c", pfx_len, pfx, padding_width, lo + (uintptr_t)lines[i], eol); + else +#endif + printf("%llu%c", lo + (uintptr_t)lines[i], eol); + } else printf("%s%c", lines[i], eol); } -- cgit v1.2.3-55-g6feb From 8696f5d380209e6aba13ffc52eced9239510b275 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 12 Apr 2023 14:51:11 +0200 Subject: shuf: remove redundant code Signed-off-by: Denys Vlasenko --- coreutils/shuf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/coreutils/shuf.c b/coreutils/shuf.c index fe0358e07..3483a289b 100644 --- a/coreutils/shuf.c +++ b/coreutils/shuf.c @@ -140,8 +140,6 @@ int shuf_main(int argc, char **argv) } pfx_len = a - opt_i_str; /* can end up being 0 */ padding_width -= pfx_len; - lo = xatoull(a); - hi = xatoull(b); } else { /* Undo leading zero 'eating' (think "0-9") */ a = opt_i_str; -- cgit v1.2.3-55-g6feb From f7065aa9ae54ce0d1772fd2e6f0e0b6862a50b71 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 12 Apr 2023 14:56:05 +0200 Subject: shuf: fix pfx_len calculation Signed-off-by: Denys Vlasenko --- coreutils/shuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils/shuf.c b/coreutils/shuf.c index 3483a289b..107899a10 100644 --- a/coreutils/shuf.c +++ b/coreutils/shuf.c @@ -138,7 +138,7 @@ int shuf_main(int argc, char **argv) a--; b--; } - pfx_len = a - opt_i_str; /* can end up being 0 */ + pfx_len = a - pfx; /* can end up being 0 */ padding_width -= pfx_len; } else { /* Undo leading zero 'eating' (think "0-9") */ -- cgit v1.2.3-55-g6feb From 7c1f975cddccff1e9705e750eed8a54131d7a392 Mon Sep 17 00:00:00 2001 From: Tomas Paukrt Date: Sun, 9 Apr 2023 09:06:43 +0200 Subject: build system: clean more files on make clean Signed-off-by: Tomas Paukrt Signed-off-by: Bernhard Reutner-Fischer --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 7b4686fc8..e67553d5f 100644 --- a/Makefile +++ b/Makefile @@ -967,6 +967,7 @@ endif # CONFIG_MODULES # Directories & files removed with 'make clean' CLEAN_DIRS += $(MODVERDIR) _install 0_lib CLEAN_FILES += busybox busybox_unstripped* busybox.links \ + busybox*.suid busybox*.nosuid \ System.map .kernelrelease \ .tmp_kallsyms* .tmp_version .tmp_busybox* .tmp_System.map -- cgit v1.2.3-55-g6feb From 8b72877babb20be9bb46c4437f5e1870390c29cc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 13 Apr 2023 00:10:10 +0200 Subject: shuf: another tweak to COMMON_PREFIX_HACK code Signed-off-by: Denys Vlasenko --- coreutils/shuf.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/coreutils/shuf.c b/coreutils/shuf.c index 107899a10..466969745 100644 --- a/coreutils/shuf.c +++ b/coreutils/shuf.c @@ -67,7 +67,7 @@ static void shuffle_lines(char **lines, unsigned numlines, unsigned outlines) } /* We can handle insanity like this: - * shuf -i 3333333333333333333333333333333333333333333333333333333333333123456789001-3333333333333333333333333333333333333333333333333333333333333123456789019 + * shuf -i 333333333333333333333333333333001-333333333333333333333333333333019 * but do we want to have +200 bytes of code (~40% code growth)? */ #define COMMON_PREFIX_HACK 0 @@ -128,16 +128,12 @@ int shuf_main(int argc, char **argv) if (padding_width > 5 && padding_width == strlen(b)) { /* How long is it? */ pfx = a; - while (isdigit(*a) && *a == *b) { + while (isdigit(*a) && *a == *b + && a[1] /* "111111-111111" case: avoid xatoull("") */ + ) { a++; b++; } - if (*a == '\0') { - /* "123456-123456", and we 'ate' all of them */ - /* prevent trying to xatoull("") */ - a--; - b--; - } pfx_len = a - pfx; /* can end up being 0 */ padding_width -= pfx_len; } else { -- cgit v1.2.3-55-g6feb From 90b607d79a1377d6a5dda44ee112698c58432203 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 13 Apr 2023 09:20:24 +0200 Subject: hush: quote variable values printed by "set" (match ash behavior) function old new delta builtin_set 258 301 +43 Signed-off-by: Denys Vlasenko --- shell/hush.c | 19 +++++++++++++++++-- shell/hush_test/hush-misc/export-n.right | 4 ++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index a938cc790..202c0993a 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -11147,6 +11147,12 @@ static int FAST_FUNC builtin_umask(char **argv) #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_TRAP static void print_escaped(const char *s) { +//TODO? bash "set" does not quote variables which contain only alnums and "%+,-./:=@_~", +// (but "export" quotes all variables, even with only these chars). +// I think quoting strings with %+,=~ looks better +// (example: "set" printing var== instead of var='=' looks strange) +// IOW: do not quote "-./:@_": / is used in pathnames, : in PATH, -._ often in file names, @ in emails + if (*s == '\'') goto squote; do { @@ -11401,8 +11407,17 @@ static int FAST_FUNC builtin_set(char **argv) if (arg == NULL) { struct variable *e; - for (e = G.top_var; e; e = e->next) - puts(e->varstr); + for (e = G.top_var; e; e = e->next) { + const char *s = e->varstr; + const char *p = strchr(s, '='); + + if (!p) /* wtf? take next variable */ + continue; + /* var= */ + printf("%.*s", (int)(p - s) + 1, s); + print_escaped(p + 1); + putchar('\n'); + } return EXIT_SUCCESS; } diff --git a/shell/hush_test/hush-misc/export-n.right b/shell/hush_test/hush-misc/export-n.right index 3d55bf752..6079a0124 100644 --- a/shell/hush_test/hush-misc/export-n.right +++ b/shell/hush_test/hush-misc/export-n.right @@ -2,8 +2,8 @@ export aaa1="'''" export aaa2='' export aaa3="'''"'abc' export aaa8='8' -aaa9=9 -aaa10=10 +aaa9='9' +aaa10='10' Nothing: Nothing: Nothing: -- cgit v1.2.3-55-g6feb From acae889dd97280ee59b7e04c18005bb8875cb0d2 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 13 Apr 2023 12:56:14 +0100 Subject: ash,hush: tab completion of functions and aliases Since commit 9e2a5668f (ash,hush: allow builtins to be tab-completed, closes 7532) ash and hush have supported tab completion of builtins. Other shells, bash and ksh for example, also support tab completion of functions and aliases. Add such support to ash and hush. function old new delta ash_command_name - 92 +92 hush_command_name - 63 +63 ash_builtin_name 17 - -17 hush_builtin_name 38 - -38 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 0/0 up/down: 169/-55) Total: 100 bytes Signed-off-by: Ron Yorston Signed-off-by: Avi Halachmi Signed-off-by: Denys Vlasenko --- shell/ash.c | 32 ++++++++++++++++++++++++++++---- shell/hush.c | 14 ++++++++++++-- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index d4ee4c93e..d2c5c5d50 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -9732,7 +9732,7 @@ evalpipe(union node *n, int flags) /* setinteractive needs this forward reference */ #if ENABLE_FEATURE_TAB_COMPLETION -static const char *get_builtin_name(int i) FAST_FUNC; +static const char *ash_command_name(int i) FAST_FUNC; #endif /* @@ -9769,7 +9769,7 @@ setinteractive(int on) if (!line_input_state) { line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); # if ENABLE_FEATURE_TAB_COMPLETION - line_input_state->get_exe_name = get_builtin_name; + line_input_state->get_exe_name = ash_command_name; # endif # if EDITING_HAS_sh_get_var line_input_state->sh_get_var = lookupvar; @@ -10284,9 +10284,33 @@ find_builtin(const char *name) #if ENABLE_FEATURE_TAB_COMPLETION static const char * FAST_FUNC -get_builtin_name(int i) +ash_command_name(int i) { - return /*i >= 0 &&*/ i < ARRAY_SIZE(builtintab) ? builtintab[i].name + 1 : NULL; + int n; + + if (/*i >= 0 &&*/ i < ARRAY_SIZE(builtintab)) + return builtintab[i].name + 1; + i -= ARRAY_SIZE(builtintab); + + for (n = 0; n < CMDTABLESIZE; n++) { + struct tblentry *cmdp; + for (cmdp = cmdtable[n]; cmdp; cmdp = cmdp->next) { + if (cmdp->cmdtype == CMDFUNCTION && --i < 0) + return cmdp->cmdname; + } + } + +# if ENABLE_ASH_ALIAS + for (n = 0; n < ATABSIZE; n++) { + struct alias *ap; + for (ap = atab[n]; ap; ap = ap->next) { + if (--i < 0) + return ap->name; + } + } +#endif + + return NULL; } #endif diff --git a/shell/hush.c b/shell/hush.c index 202c0993a..f8951d084 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -8220,7 +8220,7 @@ static const struct built_in_command *find_builtin(const char *name) } #if ENABLE_HUSH_JOB && ENABLE_FEATURE_TAB_COMPLETION -static const char * FAST_FUNC get_builtin_name(int i) +static const char * FAST_FUNC hush_command_name(int i) { if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { return bltins1[i].b_cmd; @@ -8229,6 +8229,16 @@ static const char * FAST_FUNC get_builtin_name(int i) if (i < ARRAY_SIZE(bltins2)) { return bltins2[i].b_cmd; } +# if ENABLE_HUSH_FUNCTIONS + { + struct function *funcp; + i -= ARRAY_SIZE(bltins2); + for (funcp = G.top_func; funcp; funcp = funcp->next) { + if (--i < 0) + return funcp->name; + } + } +# endif return NULL; } #endif @@ -10716,7 +10726,7 @@ int hush_main(int argc, char **argv) # if ENABLE_FEATURE_EDITING G.line_input_state = new_line_input_t(FOR_SHELL); # if ENABLE_FEATURE_TAB_COMPLETION - G.line_input_state->get_exe_name = get_builtin_name; + G.line_input_state->get_exe_name = hush_command_name; # endif # if EDITING_HAS_sh_get_var G.line_input_state->sh_get_var = get_local_var_value; -- cgit v1.2.3-55-g6feb From 2ffd8986e21f1782c78e1a9d34f6042af53d876c Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 16 Apr 2023 08:23:58 +0100 Subject: tr: display usage for incorrect arguments tr must have one or two non-option arguments. Display the usage message if any other number is present. function old new delta .rodata 108389 108392 +3 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 3/0) Total: 3 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- coreutils/tr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils/tr.c b/coreutils/tr.c index 1e402dfdb..7fe7f89d5 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c @@ -299,7 +299,7 @@ int tr_main(int argc UNUSED_PARAM, char **argv) */ /* '+': stop at first non-option */ - opts = getopt32(argv, "^+" "Ccds" "\0" "-1"); + opts = getopt32(argv, "^+" "Ccds" "\0" "-1:?2"); argv += optind; str1_length = expand(*argv++, &str1); -- cgit v1.2.3-55-g6feb From d2b81b3dc2b31d32e1060d3ea8bd998d30a37d8a Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 24 Mar 2023 09:58:14 -0500 Subject: readlink: support --, -n always POSIX will be standardizing readlink (just the -n option) and realpath (just -E and -e options): https://www.austingroupbugs.net/view.php?id=1457 Change things for readlink so that the POSIX-mandated -n and -- work even when disabling the non-standard (and partially non-working) -f when FEATURE_READLINK_FOLLOW is clear. POSIX also wants readlink to be verbose by default (if the argument is not a symlink, readlink must output a diagnostic); I did NOT address that one, because I'm waiting to see what the GNU Coreutils folks do: https://lists.gnu.org/archive/html/bug-coreutils/2023-03/msg00035.html Partial fix for https://bugs.busybox.net/show_bug.cgi?id=15466 function old new delta packed_usage 34538 34557 +19 Signed-off-by: Eric Blake Signed-off-by: Denys Vlasenko --- coreutils/readlink.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/coreutils/readlink.c b/coreutils/readlink.c index b2e867883..0a9aa957e 100644 --- a/coreutils/readlink.c +++ b/coreutils/readlink.c @@ -25,12 +25,14 @@ //kbuild:lib-$(CONFIG_READLINK) += readlink.o //usage:#define readlink_trivial_usage -//usage: IF_FEATURE_READLINK_FOLLOW("[-fnv] ") "FILE" +//usage: IF_FEATURE_READLINK_FOLLOW("[-fnv] ") +//usage: IF_NOT_FEATURE_READLINK_FOLLOW("[-n] ") +//usage: "FILE" //usage:#define readlink_full_usage "\n\n" -//usage: "Display the value of a symlink" -//usage: IF_FEATURE_READLINK_FOLLOW( "\n" -//usage: "\n -f Canonicalize by following all symlinks" +//usage: "Display the value of a symlink" "\n" //usage: "\n -n Don't add newline" +//usage: IF_FEATURE_READLINK_FOLLOW( +//usage: "\n -f Canonicalize by following all symlinks" //usage: "\n -v Verbose" //usage: ) @@ -67,25 +69,18 @@ int readlink_main(int argc UNUSED_PARAM, char **argv) { char *buf; char *fname; + unsigned opt; - IF_FEATURE_READLINK_FOLLOW( - unsigned opt; - /* We need exactly one non-option argument. */ - opt = getopt32(argv, "^" "fnvsq" "\0" "=1"); - fname = argv[optind]; - ) - IF_NOT_FEATURE_READLINK_FOLLOW( - const unsigned opt = 0; - if (argc != 2) bb_show_usage(); - fname = argv[1]; - ) + opt = getopt32(argv, "^" "n" IF_FEATURE_READLINK_FOLLOW("fvsq") + "\0" "=1"); + fname = argv[optind]; /* compat: coreutils readlink reports errors silently via exit code */ if (!(opt & 4)) /* not -v */ logmode = LOGMODE_NONE; /* NOFORK: only one alloc is allowed; must free */ - if (opt & 1) { /* -f */ + if (opt & 2) { /* -f */ buf = xmalloc_realpath_coreutils(fname); } else { buf = xmalloc_readlink_or_warn(fname); @@ -93,7 +88,7 @@ int readlink_main(int argc UNUSED_PARAM, char **argv) if (!buf) return EXIT_FAILURE; - printf((opt & 2) ? "%s" : "%s\n", buf); + printf((opt & 1) ? "%s" : "%s\n", buf); free(buf); fflush_stdout_and_exit_SUCCESS(); -- cgit v1.2.3-55-g6feb