aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-04-17 07:32:52 +0100
committerRon Yorston <rmy@pobox.com>2023-04-17 07:32:52 +0100
commit8cdeb571cfbf3bb6edc44779e46537b072b8cd08 (patch)
tree9f3ad1d205418197bc53348b61f702602229a90d
parent41827dd448c001b52b4f0e591ea605cb5de1d230 (diff)
parentd2b81b3dc2b31d32e1060d3ea8bd998d30a37d8a (diff)
downloadbusybox-w32-8cdeb571cfbf3bb6edc44779e46537b072b8cd08.tar.gz
busybox-w32-8cdeb571cfbf3bb6edc44779e46537b072b8cd08.tar.bz2
busybox-w32-8cdeb571cfbf3bb6edc44779e46537b072b8cd08.zip
Merge branch 'busybox' into merge
-rw-r--r--Makefile1
-rw-r--r--coreutils/readlink.c29
-rw-r--r--coreutils/seq.c27
-rw-r--r--coreutils/shuf.c58
-rw-r--r--coreutils/sleep.c3
-rw-r--r--coreutils/tr.c2
-rw-r--r--libbb/appletlib.c2
-rw-r--r--libbb/duration.c16
-rw-r--r--libbb/lineedit.c4
-rw-r--r--miscutils/seedrng.c24
-rw-r--r--shell/ash.c32
-rw-r--r--shell/hush.c33
-rw-r--r--shell/hush_test/hush-misc/export-n.right4
-rwxr-xr-xtestsuite/seq.tests4
-rw-r--r--util-linux/mkfs_vfat.c5
15 files changed, 191 insertions, 53 deletions
diff --git a/Makefile b/Makefile
index 3857dbc95..f1d6b20b4 100644
--- a/Makefile
+++ b/Makefile
@@ -984,6 +984,7 @@ endif # CONFIG_MODULES
984# Directories & files removed with 'make clean' 984# Directories & files removed with 'make clean'
985CLEAN_DIRS += $(MODVERDIR) _install 0_lib 985CLEAN_DIRS += $(MODVERDIR) _install 0_lib
986CLEAN_FILES += busybox$(EXEEXT) busybox_unstripped* busybox.links \ 986CLEAN_FILES += busybox$(EXEEXT) busybox_unstripped* busybox.links \
987 busybox*.suid busybox*.nosuid \
987 System.map .kernelrelease \ 988 System.map .kernelrelease \
988 .tmp_kallsyms* .tmp_version .tmp_busybox* .tmp_System.map 989 .tmp_kallsyms* .tmp_version .tmp_busybox* .tmp_System.map
989 990
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 @@
25//kbuild:lib-$(CONFIG_READLINK) += readlink.o 25//kbuild:lib-$(CONFIG_READLINK) += readlink.o
26 26
27//usage:#define readlink_trivial_usage 27//usage:#define readlink_trivial_usage
28//usage: IF_FEATURE_READLINK_FOLLOW("[-fnv] ") "FILE" 28//usage: IF_FEATURE_READLINK_FOLLOW("[-fnv] ")
29//usage: IF_NOT_FEATURE_READLINK_FOLLOW("[-n] ")
30//usage: "FILE"
29//usage:#define readlink_full_usage "\n\n" 31//usage:#define readlink_full_usage "\n\n"
30//usage: "Display the value of a symlink" 32//usage: "Display the value of a symlink" "\n"
31//usage: IF_FEATURE_READLINK_FOLLOW( "\n"
32//usage: "\n -f Canonicalize by following all symlinks"
33//usage: "\n -n Don't add newline" 33//usage: "\n -n Don't add newline"
34//usage: IF_FEATURE_READLINK_FOLLOW(
35//usage: "\n -f Canonicalize by following all symlinks"
34//usage: "\n -v Verbose" 36//usage: "\n -v Verbose"
35//usage: ) 37//usage: )
36 38
@@ -67,25 +69,18 @@ int readlink_main(int argc UNUSED_PARAM, char **argv)
67{ 69{
68 char *buf; 70 char *buf;
69 char *fname; 71 char *fname;
72 unsigned opt;
70 73
71 IF_FEATURE_READLINK_FOLLOW( 74 opt = getopt32(argv, "^" "n" IF_FEATURE_READLINK_FOLLOW("fvsq")
72 unsigned opt; 75 "\0" "=1");
73 /* We need exactly one non-option argument. */ 76 fname = argv[optind];
74 opt = getopt32(argv, "^" "fnvsq" "\0" "=1");
75 fname = argv[optind];
76 )
77 IF_NOT_FEATURE_READLINK_FOLLOW(
78 const unsigned opt = 0;
79 if (argc != 2) bb_show_usage();
80 fname = argv[1];
81 )
82 77
83 /* compat: coreutils readlink reports errors silently via exit code */ 78 /* compat: coreutils readlink reports errors silently via exit code */
84 if (!(opt & 4)) /* not -v */ 79 if (!(opt & 4)) /* not -v */
85 logmode = LOGMODE_NONE; 80 logmode = LOGMODE_NONE;
86 81
87 /* NOFORK: only one alloc is allowed; must free */ 82 /* NOFORK: only one alloc is allowed; must free */
88 if (opt & 1) { /* -f */ 83 if (opt & 2) { /* -f */
89 buf = xmalloc_realpath_coreutils(fname); 84 buf = xmalloc_realpath_coreutils(fname);
90 } else { 85 } else {
91 buf = xmalloc_readlink_or_warn(fname); 86 buf = xmalloc_readlink_or_warn(fname);
@@ -93,7 +88,7 @@ int readlink_main(int argc UNUSED_PARAM, char **argv)
93 88
94 if (!buf) 89 if (!buf)
95 return EXIT_FAILURE; 90 return EXIT_FAILURE;
96 printf((opt & 2) ? "%s" : "%s\n", buf); 91 printf((opt & 1) ? "%s" : "%s\n", buf);
97 free(buf); 92 free(buf);
98 93
99 fflush_stdout_and_exit_SUCCESS(); 94 fflush_stdout_and_exit_SUCCESS();
diff --git a/coreutils/seq.c b/coreutils/seq.c
index beb339d1e..77a8aba8a 100644
--- a/coreutils/seq.c
+++ b/coreutils/seq.c
@@ -22,7 +22,7 @@
22//usage:#define seq_full_usage "\n\n" 22//usage:#define seq_full_usage "\n\n"
23//usage: "Print numbers from FIRST to LAST, in steps of INC.\n" 23//usage: "Print numbers from FIRST to LAST, in steps of INC.\n"
24//usage: "FIRST, INC default to 1.\n" 24//usage: "FIRST, INC default to 1.\n"
25//usage: "\n -w Pad to last with leading zeros" 25//usage: "\n -w Pad with leading zeros"
26//usage: "\n -s SEP String separator" 26//usage: "\n -s SEP String separator"
27 27
28#include "libbb.h" 28#include "libbb.h"
@@ -41,6 +41,7 @@ int seq_main(int argc, char **argv)
41 unsigned width; 41 unsigned width;
42 unsigned frac_part; 42 unsigned frac_part;
43 const char *sep, *opt_s = "\n"; 43 const char *sep, *opt_s = "\n";
44 char *saved;
44 unsigned opt; 45 unsigned opt;
45 46
46#if ENABLE_LOCALE_SUPPORT 47#if ENABLE_LOCALE_SUPPORT
@@ -49,7 +50,29 @@ int seq_main(int argc, char **argv)
49 setlocale(LC_NUMERIC, "C"); 50 setlocale(LC_NUMERIC, "C");
50#endif 51#endif
51 52
52 opt = getopt32(argv, "+ws:", &opt_s); 53 /* Cater for negative arguments: if we see one, truncate argv[] on it */
54 n = 0;
55 for (;;) {
56 char c;
57 saved = argv[++n];
58 if (!saved)
59 break;
60 if (saved[0] != '-') {
61 // break; // "seq -s : -1 1" won't be treated correctly
62 continue;
63 }
64// "seq -s -1 1 9" is not treated correctly, but such usage
65// (delimiter string which looks like negative number) is very unlikely
66 c = saved[1];
67 if (c == '.' || (c >= '0' && c <= '9')) {
68 argv[n] = NULL;
69 break;
70 }
71 }
72 opt = getopt32(argv, "+ws:", &opt_s); /* "+": stop at first non-option */
73 /* Restore possibly truncated argv[] */
74 argv[n] = saved;
75
53 argc -= optind; 76 argc -= optind;
54 argv += optind; 77 argv += optind;
55 first = increment = 1; 78 first = increment = 1;
diff --git a/coreutils/shuf.c b/coreutils/shuf.c
index 56ba03aad..466969745 100644
--- a/coreutils/shuf.c
+++ b/coreutils/shuf.c
@@ -66,6 +66,12 @@ static void shuffle_lines(char **lines, unsigned numlines, unsigned outlines)
66 } 66 }
67} 67}
68 68
69/* We can handle insanity like this:
70 * shuf -i 333333333333333333333333333333001-333333333333333333333333333333019
71 * but do we want to have +200 bytes of code (~40% code growth)?
72 */
73#define COMMON_PREFIX_HACK 0
74
69int shuf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 75int shuf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
70int shuf_main(int argc, char **argv) 76int shuf_main(int argc, char **argv)
71{ 77{
@@ -76,6 +82,11 @@ int shuf_main(int argc, char **argv)
76 unsigned numlines, outlines; 82 unsigned numlines, outlines;
77 unsigned i; 83 unsigned i;
78 char eol; 84 char eol;
85#if COMMON_PREFIX_HACK
86 unsigned pfx_len = 0;
87 unsigned padding_width = padding_width;
88 const char *pfx = pfx;
89#endif
79 90
80 opts = getopt32(argv, "^" 91 opts = getopt32(argv, "^"
81 OPT_STR 92 OPT_STR
@@ -104,10 +115,40 @@ int shuf_main(int argc, char **argv)
104 if (!dash) { 115 if (!dash) {
105 bb_error_msg_and_die("bad range '%s'", opt_i_str); 116 bb_error_msg_and_die("bad range '%s'", opt_i_str);
106 } 117 }
107 *dash = '\0'; 118 *dash++ = '\0';
119#if COMMON_PREFIX_HACK
120 {
121 const char *a = opt_i_str;
122 const char *b = dash;
123 /* Skip leading zeros (they may mask that common prefix does exist) */
124 while (*a == '0') a++;
125 while (*b == '0') b++;
126 /* Do we have a common prefix (long enough to bother)? */
127 padding_width = strlen(a);
128 if (padding_width > 5 && padding_width == strlen(b)) {
129 /* How long is it? */
130 pfx = a;
131 while (isdigit(*a) && *a == *b
132 && a[1] /* "111111-111111" case: avoid xatoull("") */
133 ) {
134 a++;
135 b++;
136 }
137 pfx_len = a - pfx; /* can end up being 0 */
138 padding_width -= pfx_len;
139 } else {
140 /* Undo leading zero 'eating' (think "0-9") */
141 a = opt_i_str;
142 b = dash;
143 }
144 lo = xatoull(a);
145 hi = xatoull(b);
146 }
147#else
108 lo = xatoull(opt_i_str); 148 lo = xatoull(opt_i_str);
109 hi = xatoull(dash + 1); 149 hi = xatoull(dash);
110 *dash = '-'; 150#endif
151 dash[-1] = '-';
111 if (hi < lo) 152 if (hi < lo)
112 bb_error_msg_and_die("bad range '%s'", opt_i_str); 153 bb_error_msg_and_die("bad range '%s'", opt_i_str);
113 hi -= lo; 154 hi -= lo;
@@ -165,9 +206,14 @@ int shuf_main(int argc, char **argv)
165 eol = '\0'; 206 eol = '\0';
166 207
167 for (i = numlines - outlines; i < numlines; i++) { 208 for (i = numlines - outlines; i < numlines; i++) {
168 if (opts & OPT_i) 209 if (opts & OPT_i) {
169 printf("%"LL_FMT"u%c", lo + (uintptr_t)lines[i], eol); 210#if COMMON_PREFIX_HACK
170 else 211 if (pfx_len != 0)
212 printf("%.*s%0*llu%c", pfx_len, pfx, padding_width, lo + (uintptr_t)lines[i], eol);
213 else
214#endif
215 printf("%llu%c", lo + (uintptr_t)lines[i], eol);
216 } else
171 printf("%s%c", lines[i], eol); 217 printf("%s%c", lines[i], eol);
172 } 218 }
173 219
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)
74 ++argv; 74 ++argv;
75 if (!*argv) { 75 if (!*argv) {
76 /* Without this, bare "sleep" in ash shows _ash_ --help */ 76 /* Without this, bare "sleep" in ash shows _ash_ --help */
77 if (ENABLE_ASH_SLEEP && applet_name[0] != 's') { 77 /* (ash can be the "sh" applet as well, so check 2nd char) */
78 if (ENABLE_ASH_SLEEP && applet_name[1] != 'l') {
78 bb_simple_error_msg("sleep: missing operand"); 79 bb_simple_error_msg("sleep: missing operand");
79 return EXIT_FAILURE; 80 return EXIT_FAILURE;
80 } 81 }
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)
299 */ 299 */
300 300
301 /* '+': stop at first non-option */ 301 /* '+': stop at first non-option */
302 opts = getopt32(argv, "^+" "Ccds" "\0" "-1"); 302 opts = getopt32(argv, "^+" "Ccds" "\0" "-1:?2");
303 argv += optind; 303 argv += optind;
304 304
305 str1_length = expand(*argv++, &str1); 305 str1_length = expand(*argv++, &str1);
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index dacfbdd22..379d6af2f 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -1094,7 +1094,7 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
1094# endif 1094# endif
1095 1095
1096# if NUM_APPLETS > 0 1096# if NUM_APPLETS > 0
1097void FAST_FUNC show_usage_if_dash_dash_help(int applet_no, char **argv) 1097void FAST_FUNC show_usage_if_dash_dash_help(int applet_no UNUSED_PARAM, char **argv)
1098{ 1098{
1099 /* Special case. POSIX says "test --help" 1099 /* Special case. POSIX says "test --help"
1100 * should be no different from e.g. "test --foo". 1100 * should be no different from e.g. "test --foo".
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)
76 ts.tv_sec = duration; 76 ts.tv_sec = duration;
77 ts.tv_nsec = (duration - ts.tv_sec) * 1000000000; 77 ts.tv_nsec = (duration - ts.tv_sec) * 1000000000;
78 } 78 }
79 /* NB: if ENABLE_ASH_SLEEP, we end up here if "sleep N" 79 /* NB: ENABLE_ASH_SLEEP requires that we do NOT loop on EINTR here:
80 * is run in ash. ^C will still work, because ash's signal handler 80 * otherwise, traps won't execute until we finish looping.
81 * does not return (it longjumps), the below loop
82 * will not continue looping.
83 * (This wouldn't work in hush)
84 */ 81 */
85 do { 82 //do {
86 errno = 0; 83 // errno = 0;
87 nanosleep(&ts, &ts); 84 // nanosleep(&ts, &ts);
88 } while (errno == EINTR); 85 //} while (errno == EINTR);
86 nanosleep(&ts, &ts);
89} 87}
90#else 88#else
91duration_t FAST_FUNC parse_duration_str(char *str) 89duration_t FAST_FUNC parse_duration_str(char *str)
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 45d4c33f5..3abc97503 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -254,7 +254,7 @@ static NOINLINE const char *get_homedir_or_NULL(void)
254 const char *home; 254 const char *home;
255 255
256# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH 256# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH
257 home = state->sh_get_var ? state->sh_get_var("HOME") : getenv("HOME"); 257 home = state && state->sh_get_var ? state->sh_get_var("HOME") : getenv("HOME");
258# else 258# else
259 home = getenv("HOME"); 259 home = getenv("HOME");
260# endif 260# endif
@@ -2159,7 +2159,7 @@ static void parse_and_put_prompt(const char *prmt_ptr)
2159 if (!cwd_buf) { 2159 if (!cwd_buf) {
2160 const char *home; 2160 const char *home;
2161# if EDITING_HAS_sh_get_var 2161# if EDITING_HAS_sh_get_var
2162 cwd_buf = state->sh_get_var 2162 cwd_buf = state && state->sh_get_var
2163 ? xstrdup(state->sh_get_var("PWD")) 2163 ? xstrdup(state->sh_get_var("PWD"))
2164 : xrealloc_getcwd_or_warn(NULL); 2164 : xrealloc_getcwd_or_warn(NULL);
2165# else 2165# else
diff --git a/miscutils/seedrng.c b/miscutils/seedrng.c
index 967741dc7..3bf6e2ea7 100644
--- a/miscutils/seedrng.c
+++ b/miscutils/seedrng.c
@@ -42,11 +42,31 @@
42#include "libbb.h" 42#include "libbb.h"
43 43
44#include <linux/random.h> 44#include <linux/random.h>
45#include <sys/random.h>
46#include <sys/file.h> 45#include <sys/file.h>
47 46
47/* Fix up glibc <= 2.24 not having getrandom() */
48#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 24
49#include <sys/syscall.h>
50static ssize_t getrandom(void *buffer, size_t length, unsigned flags)
51{
52# if defined(__NR_getrandom)
53 return syscall(__NR_getrandom, buffer, length, flags);
54# else
55 errno = ENOSYS;
56 return -1;
57# endif
58}
59#else
60#include <sys/random.h>
61#endif
62
63/* Apparently some headers don't ship with this yet. */
64#ifndef GRND_NONBLOCK
65#define GRND_NONBLOCK 0x0001
66#endif
67
48#ifndef GRND_INSECURE 68#ifndef GRND_INSECURE
49#define GRND_INSECURE 0x0004 /* Apparently some headers don't ship with this yet. */ 69#define GRND_INSECURE 0x0004
50#endif 70#endif
51 71
52#define DEFAULT_SEED_DIR "/var/lib/seedrng" 72#define DEFAULT_SEED_DIR "/var/lib/seedrng"
diff --git a/shell/ash.c b/shell/ash.c
index 3eb9d5852..28f4ec47d 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -10696,7 +10696,7 @@ evalpipe(union node *n, int flags)
10696 10696
10697/* setinteractive needs this forward reference */ 10697/* setinteractive needs this forward reference */
10698#if ENABLE_FEATURE_TAB_COMPLETION 10698#if ENABLE_FEATURE_TAB_COMPLETION
10699static const char *get_builtin_name(int i) FAST_FUNC; 10699static const char *ash_command_name(int i) FAST_FUNC;
10700#endif 10700#endif
10701 10701
10702/* 10702/*
@@ -10733,7 +10733,7 @@ setinteractive(int on)
10733 if (!line_input_state) { 10733 if (!line_input_state) {
10734 line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); 10734 line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
10735# if ENABLE_FEATURE_TAB_COMPLETION 10735# if ENABLE_FEATURE_TAB_COMPLETION
10736 line_input_state->get_exe_name = get_builtin_name; 10736 line_input_state->get_exe_name = ash_command_name;
10737# endif 10737# endif
10738# if EDITING_HAS_sh_get_var 10738# if EDITING_HAS_sh_get_var
10739 line_input_state->sh_get_var = lookupvar; 10739 line_input_state->sh_get_var = lookupvar;
@@ -11252,9 +11252,33 @@ find_builtin(const char *name)
11252 11252
11253#if ENABLE_FEATURE_TAB_COMPLETION 11253#if ENABLE_FEATURE_TAB_COMPLETION
11254static const char * FAST_FUNC 11254static const char * FAST_FUNC
11255get_builtin_name(int i) 11255ash_command_name(int i)
11256{ 11256{
11257 return /*i >= 0 &&*/ i < ARRAY_SIZE(builtintab) ? builtintab[i].name + 1 : NULL; 11257 int n;
11258
11259 if (/*i >= 0 &&*/ i < ARRAY_SIZE(builtintab))
11260 return builtintab[i].name + 1;
11261 i -= ARRAY_SIZE(builtintab);
11262
11263 for (n = 0; n < CMDTABLESIZE; n++) {
11264 struct tblentry *cmdp;
11265 for (cmdp = cmdtable[n]; cmdp; cmdp = cmdp->next) {
11266 if (cmdp->cmdtype == CMDFUNCTION && --i < 0)
11267 return cmdp->cmdname;
11268 }
11269 }
11270
11271# if ENABLE_ASH_ALIAS
11272 for (n = 0; n < ATABSIZE; n++) {
11273 struct alias *ap;
11274 for (ap = atab[n]; ap; ap = ap->next) {
11275 if (--i < 0)
11276 return ap->name;
11277 }
11278 }
11279#endif
11280
11281 return NULL;
11258} 11282}
11259#endif 11283#endif
11260 11284
diff --git a/shell/hush.c b/shell/hush.c
index a938cc790..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)
8220} 8220}
8221 8221
8222#if ENABLE_HUSH_JOB && ENABLE_FEATURE_TAB_COMPLETION 8222#if ENABLE_HUSH_JOB && ENABLE_FEATURE_TAB_COMPLETION
8223static const char * FAST_FUNC get_builtin_name(int i) 8223static const char * FAST_FUNC hush_command_name(int i)
8224{ 8224{
8225 if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { 8225 if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) {
8226 return bltins1[i].b_cmd; 8226 return bltins1[i].b_cmd;
@@ -8229,6 +8229,16 @@ static const char * FAST_FUNC get_builtin_name(int i)
8229 if (i < ARRAY_SIZE(bltins2)) { 8229 if (i < ARRAY_SIZE(bltins2)) {
8230 return bltins2[i].b_cmd; 8230 return bltins2[i].b_cmd;
8231 } 8231 }
8232# if ENABLE_HUSH_FUNCTIONS
8233 {
8234 struct function *funcp;
8235 i -= ARRAY_SIZE(bltins2);
8236 for (funcp = G.top_func; funcp; funcp = funcp->next) {
8237 if (--i < 0)
8238 return funcp->name;
8239 }
8240 }
8241# endif
8232 return NULL; 8242 return NULL;
8233} 8243}
8234#endif 8244#endif
@@ -10716,7 +10726,7 @@ int hush_main(int argc, char **argv)
10716# if ENABLE_FEATURE_EDITING 10726# if ENABLE_FEATURE_EDITING
10717 G.line_input_state = new_line_input_t(FOR_SHELL); 10727 G.line_input_state = new_line_input_t(FOR_SHELL);
10718# if ENABLE_FEATURE_TAB_COMPLETION 10728# if ENABLE_FEATURE_TAB_COMPLETION
10719 G.line_input_state->get_exe_name = get_builtin_name; 10729 G.line_input_state->get_exe_name = hush_command_name;
10720# endif 10730# endif
10721# if EDITING_HAS_sh_get_var 10731# if EDITING_HAS_sh_get_var
10722 G.line_input_state->sh_get_var = get_local_var_value; 10732 G.line_input_state->sh_get_var = get_local_var_value;
@@ -11147,6 +11157,12 @@ static int FAST_FUNC builtin_umask(char **argv)
11147#if ENABLE_HUSH_EXPORT || ENABLE_HUSH_TRAP 11157#if ENABLE_HUSH_EXPORT || ENABLE_HUSH_TRAP
11148static void print_escaped(const char *s) 11158static void print_escaped(const char *s)
11149{ 11159{
11160//TODO? bash "set" does not quote variables which contain only alnums and "%+,-./:=@_~",
11161// (but "export" quotes all variables, even with only these chars).
11162// I think quoting strings with %+,=~ looks better
11163// (example: "set" printing var== instead of var='=' looks strange)
11164// IOW: do not quote "-./:@_": / is used in pathnames, : in PATH, -._ often in file names, @ in emails
11165
11150 if (*s == '\'') 11166 if (*s == '\'')
11151 goto squote; 11167 goto squote;
11152 do { 11168 do {
@@ -11401,8 +11417,17 @@ static int FAST_FUNC builtin_set(char **argv)
11401 11417
11402 if (arg == NULL) { 11418 if (arg == NULL) {
11403 struct variable *e; 11419 struct variable *e;
11404 for (e = G.top_var; e; e = e->next) 11420 for (e = G.top_var; e; e = e->next) {
11405 puts(e->varstr); 11421 const char *s = e->varstr;
11422 const char *p = strchr(s, '=');
11423
11424 if (!p) /* wtf? take next variable */
11425 continue;
11426 /* var= */
11427 printf("%.*s", (int)(p - s) + 1, s);
11428 print_escaped(p + 1);
11429 putchar('\n');
11430 }
11406 return EXIT_SUCCESS; 11431 return EXIT_SUCCESS;
11407 } 11432 }
11408 11433
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="'''"
2export aaa2='' 2export aaa2=''
3export aaa3="'''"'abc' 3export aaa3="'''"'abc'
4export aaa8='8' 4export aaa8='8'
5aaa9=9 5aaa9='9'
6aaa10=10 6aaa10='10'
7Nothing: 7Nothing:
8Nothing: 8Nothing:
9Nothing: 9Nothing:
diff --git a/testsuite/seq.tests b/testsuite/seq.tests
index 1e1116c7d..d0da8c119 100755
--- a/testsuite/seq.tests
+++ b/testsuite/seq.tests
@@ -43,4 +43,8 @@ testing "seq count down by 3 with padding" "seq -w 8 -3 04" "08\n05\n" "" ""
43testing "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" "" "" 43testing "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" "" ""
44testing "seq count by .3 with padding 2" "seq -w 03 .3 0004" "0003.0\n0003.3\n0003.6\n0003.9\n" "" "" 44testing "seq count by .3 with padding 2" "seq -w 03 .3 0004" "0003.0\n0003.3\n0003.6\n0003.9\n" "" ""
45 45
46testing "seq from -4 count down by 2" "seq -4 -2 -8" "-4\n-6\n-8\n" "" ""
47testing "seq from -.0 count down by .25" "seq -.0 -.25 -.9" "-0.00\n-0.25\n-0.50\n-0.75\n" "" ""
48testing "seq -s : with negative start" "seq -s : -1 1" "-1:0:1\n" "" ""
49
46exit $FAILCOUNT 50exit $FAILCOUNT
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)
267 267
268 // cache device name 268 // cache device name
269 device_name = argv[0]; 269 device_name = argv[0];
270 // default volume ID = creation time 270 // default volume ID: somewhat random (not crypto-strong)
271 volume_id = time(NULL); 271 // (mix in pid to avoid same IDs when run in rapid succession)
272 volume_id = time(NULL) ^ getpid();
272 // truncate to exactly 11 chars, pad with spaces 273 // truncate to exactly 11 chars, pad with spaces
273 sprintf(volume_label11, "%-11.11s", arg_volume_label); 274 sprintf(volume_label11, "%-11.11s", arg_volume_label);
274 275