Merge with BusyBox 1.26.0 development version prior to significant hush changes.

This commit is contained in:
Stephen Heumann 2018-01-01 12:59:30 -06:00
commit 31f1b35500
5 changed files with 110 additions and 41 deletions

View File

@ -5,7 +5,7 @@
#ifndef BUSYBOX_H
#define BUSYBOX_H 1
#define BB_VER "1.25.0 (GNO hush 1.2-dev)"
#define BB_VER "1.26.0.git (GNO hush 1.2-dev)"
#include "libbb.h"
/* BB_DIR_foo and BB_SUID_bar constants: */
@ -13,7 +13,17 @@
PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
#if ENABLE_FEATURE_PREFER_APPLETS
/* Defined in appletlib.c (by including generated applet_tables.h) */
/* Keep in sync with applets/applet_tables.c! */
extern const char applet_names[] ALIGN1;
extern int (*const applet_main[])(int argc, char **argv);
extern const uint8_t applet_flags[] ALIGN1;
extern const uint8_t applet_suid[] ALIGN1;
extern const uint8_t applet_install_loc[] ALIGN1;
#if ENABLE_FEATURE_PREFER_APPLETS \
|| ENABLE_FEATURE_SH_STANDALONE \
|| ENABLE_FEATURE_SH_NOFORK
# define APPLET_IS_NOFORK(i) (applet_flags[(i)/4] & (1 << (2 * ((i)%4))))
# define APPLET_IS_NOEXEC(i) (applet_flags[(i)/4] & (1 << ((2 * ((i)%4))+1)))
#else
@ -25,6 +35,14 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
# define APPLET_SUID(i) ((applet_suid[(i)/4] >> (2 * ((i)%4)) & 3))
#endif
#if ENABLE_FEATURE_INSTALLER
#define APPLET_INSTALL_LOC(i) ({ \
unsigned v = (i); \
if (v & 1) v = applet_install_loc[v/2] >> 4; \
else v = applet_install_loc[v/2] & 0xf; \
v; })
#endif
/* Length of these names has effect on size of libbusybox
* and "individual" binaries. Keep them short.

View File

@ -27,23 +27,20 @@ extern int optreset; /* exists on GNO, but isn't in the header files */
uint32_t
getopt32(char **argv, const char *applet_opts, ...)
The command line options must be declared in const char
*applet_opts as a string of chars, for example:
flags = getopt32(argv, "rnug");
The command line options are passed as the applet_opts string.
If one of the given options is found, a flag value is added to
the return value (an unsigned long).
the return value.
The flag value is determined by the position of the char in
applet_opts string. For example, in the above case:
applet_opts string. For example:
flags = getopt32(argv, "rnug");
"r" will add 1 (bit 0)
"n" will add 2 (bit 1)
"u" will add 4 (bit 2)
"g" will add 8 (bit 3)
"r" will set 1 (bit 0)
"n" will set 2 (bit 1)
"u" will set 4 (bit 2)
"g" will set 8 (bit 3)
and so on. You can also look at the return value as a bit
field and each option sets one bit.
@ -55,7 +52,7 @@ getopt32(char **argv, const char *applet_opts, ...)
(options and their parameters will be moved into argv[]
positions prior to argv[optind]).
":" If one of the options requires an argument, then add a ":"
"o:" If one of the options requires an argument, then add a ":"
after the char in applet_opts and provide a pointer to store
the argument. For example:
@ -68,15 +65,39 @@ getopt32(char **argv, const char *applet_opts, ...)
&pointer_to_arg_for_a, &pointer_to_arg_for_b,
&pointer_to_arg_for_c, &pointer_to_arg_for_d);
The type of the pointer (char* or llist_t*) may be controlled
by the "::" special separator that is set in the external string
opt_complementary (see below for more info).
The type of the pointer may be controlled by "o::" or "o+" in
the external string opt_complementary (see below for more info).
"::" If option can have an *optional* argument, then add a "::"
"o::" If option can have an *optional* argument, then add a "::"
after its char in applet_opts and provide a pointer to store
the argument. Note that optional arguments _must_
immediately follow the option: -oparam, not -o param.
"o:+" This means that the parameter for this option is a nonnegative integer.
It will be processed with xatoi_positive() - allowed range
is 0..INT_MAX.
int param; // "unsigned param;" will also work
getopt32(argv, "p:+", &param);
"o:*" This means that the option can occur multiple times. Each occurrence
will be saved as a llist_t element instead of char*.
For example:
The grep applet can have one or more "-e pattern" arguments.
In this case you should use getopt32() as follows:
llist_t *patterns = NULL;
(this pointer must be initializated to NULL if the list is empty
as required by llist_add_to_end(llist_t **old_head, char *new_item).)
getopt32(argv, "e:*", &patterns);
$ grep -e user -e root /etc/passwd
root:x:0:0:root:/root:/bin/bash
user:x:500:500::/home/user:/bin/bash
"+" If the first character in the applet_opts string is a plus,
then option processing will stop as soon as a non-option is
encountered in the argv array. Useful for applets like env
@ -92,7 +113,7 @@ const char *applet_long_options
This struct allows you to define long options:
static const char applet_longopts[] ALIGN1 =
//"name\0" has_arg val
//"name\0" has_arg val
"verbose\0" No_argument "v"
;
applet_long_options = applet_longopts;
@ -100,7 +121,7 @@ const char *applet_long_options
The last member of struct option (val) typically is set to
matching short option from applet_opts. If there is no matching
char in applet_opts, then:
- return bit have next position after short options
- return bit has next position after short options
- if has_arg is not "No_argument", use ptr for arg also
- opt_complementary affects it too
@ -149,8 +170,8 @@ const char *opt_complementary
llist_t *my_b = NULL;
int verbose_level = 0;
opt_complementary = "vv:b::b-c:c-b";
f = getopt32(argv, "vb:c", &my_b, &verbose_level);
opt_complementary = "vv:b-c:c-b";
f = getopt32(argv, "vb:*c", &my_b, &verbose_level);
if (f & 2) // -c after -b unsets -b flag
while (my_b) dosomething_with(llist_pop(&my_b));
if (my_b) // but llist is stored if -b is specified
@ -243,7 +264,7 @@ Special characters:
"x--x" Variation of the above, it means that -x option should occur
at most once.
"a+" A plus after a char in opt_complementary means that the parameter
"o+" A plus after a char in opt_complementary means that the parameter
for this option is a nonnegative integer. It will be processed
with xatoi_positive() - allowed range is 0..INT_MAX.
@ -251,7 +272,7 @@ Special characters:
opt_complementary = "p+";
getopt32(argv, "p:", &param);
"a::" A double colon after a char in opt_complementary means that the
"o::" A double colon after a char in opt_complementary means that the
option can occur multiple times. Each occurrence will be saved as
a llist_t element instead of char*.
@ -265,12 +286,17 @@ Special characters:
as required by llist_add_to_end(llist_t **old_head, char *new_item).)
opt_complementary = "e::";
getopt32(argv, "e:", &patterns);
$ grep -e user -e root /etc/passwd
root:x:0:0:root:/root:/bin/bash
user:x:500:500::/home/user:/bin/bash
"o+" and "o::" can be handled by "o:+" and "o:*" specifiers
in option string (and it is preferred), but this does not work
for "long options only" cases, such as tar --exclude=PATTERN,
wget --header=HDR cases.
"a?b" A "?" between an option and a group of options means that
at least one of them is required to occur if the first option
occurs in preceding command line arguments.
@ -356,6 +382,7 @@ getopt32(char **argv, const char *applet_opts, ...)
char **pargv;
int min_arg = 0;
int max_arg = -1;
char *applet_opts_copy = NULL;
#define SHOW_USAGE_IF_ERROR 1
#define ALL_ARGV_IS_OPTS 2
@ -370,21 +397,26 @@ getopt32(char **argv, const char *applet_opts, ...)
va_start(p, applet_opts);
complementary = calloc(33, sizeof(*complementary));
if (complementary == NULL)
goto error2;
on_off = complementary;
applet_opts_copy = malloc(strlen(applet_opts) + 1);
if (applet_opts_copy == NULL)
goto error2;
applet_opts = strcpy(applet_opts_copy, applet_opts);
/* skip bbox extension */
first_char = applet_opts[0];
if (first_char == '!')
applet_opts++;
c = 0;
complementary = calloc(33, sizeof(*complementary));
if (complementary == NULL)
goto error;
on_off = complementary;
/* skip GNU extension */
s = (const unsigned char *)applet_opts;
if (*s == '+' || *s == '-')
s++;
c = 0;
while (*s) {
if (c >= 32)
break;
@ -392,6 +424,13 @@ getopt32(char **argv, const char *applet_opts, ...)
on_off->switch_on = (1 << c);
if (*++s == ':') {
on_off->optarg = va_arg(p, void **);
if (s[1] == '+' || s[1] == '*') {
/* 'o:+' or 'o:*' */
on_off->param_type = (s[1] == '+') ?
PARAM_INT : PARAM_LIST;
overlapping_strcpy((char*)s + 1, (char*)s + 2);
}
/* skip possible 'o::' (or 'o:+:' !) */
while (*++s == ':')
continue;
}
@ -444,6 +483,7 @@ getopt32(char **argv, const char *applet_opts, ...)
applet_long_options = NULL;
}
#endif /* ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG */
for (s = (const unsigned char *)opt_complementary; s && *s; s++) {
t_complementary *pair;
unsigned *pair_switch;
@ -622,11 +662,14 @@ getopt32(char **argv, const char *applet_opts, ...)
option_mask32 = flags;
free(complementary);
free(applet_opts_copy);
return flags;
error:
if (first_char != '!')
bb_show_usage();
error2:
free(complementary);
free(applet_opts_copy);
return (int32_t)-1;
}

View File

@ -83,7 +83,9 @@
# define CHAR_T wchar_t
static bool BB_isspace(CHAR_T c) { return ((unsigned)c < 256 && isspace(c)); }
# if ENABLE_FEATURE_EDITING_VI
static bool BB_isalnum(CHAR_T c) { return ((unsigned)c < 256 && isalnum(c)); }
static bool BB_isalnum_or_underscore(CHAR_T c) {
return ((unsigned)c < 256 && isalnum(c)) || c == '_';
}
# endif
static bool BB_ispunct(CHAR_T c) { return ((unsigned)c < 256 && ispunct(c)); }
# undef isspace
@ -98,7 +100,11 @@ static bool BB_ispunct(CHAR_T c) { return ((unsigned)c < 256 && ispunct(c)); }
# define BB_NUL '\0'
# define CHAR_T char
# define BB_isspace(c) isspace(c)
# define BB_isalnum(c) isalnum(c)
# if ENABLE_FEATURE_EDITING_VI
static bool BB_isalnum_or_underscore(CHAR_T c) {
return ((unsigned)c < 256 && isalnum(c)) || c == '_';
}
# endif
# define BB_ispunct(c) ispunct(c)
#endif
#if ENABLE_UNICODE_PRESERVE_BROKEN
@ -1762,9 +1768,9 @@ vi_word_motion(int eat)
{
CHAR_T *command = command_ps;
if (BB_isalnum(command[cursor]) || command[cursor] == '_') {
if (BB_isalnum_or_underscore(command[cursor])) {
while (cursor < command_len
&& (BB_isalnum(command[cursor+1]) || command[cursor+1] == '_')
&& (BB_isalnum_or_underscore(command[cursor+1]))
) {
input_forward();
}
@ -1806,9 +1812,9 @@ vi_end_motion(void)
input_forward();
if (cursor >= command_len-1)
return;
if (BB_isalnum(command[cursor]) || command[cursor] == '_') {
if (BB_isalnum_or_underscore(command[cursor])) {
while (cursor < command_len-1
&& (BB_isalnum(command[cursor+1]) || command[cursor+1] == '_')
&& (BB_isalnum_or_underscore(command[cursor+1]))
) {
input_forward();
}
@ -1841,9 +1847,9 @@ vi_back_motion(void)
input_backward(1);
if (cursor <= 0)
return;
if (BB_isalnum(command[cursor]) || command[cursor] == '_') {
if (BB_isalnum_or_underscore(command[cursor])) {
while (cursor > 0
&& (BB_isalnum(command[cursor-1]) || command[cursor-1] == '_')
&& (BB_isalnum_or_underscore(command[cursor-1]))
) {
input_backward(1);
}

View File

@ -88,7 +88,7 @@ config FEATURE_SH_EXTRA_QUIET
config FEATURE_SH_STANDALONE
bool "Standalone shell"
default n
depends on (HUSH || ASH) && FEATURE_PREFER_APPLETS
depends on (HUSH || ASH)
help
This option causes busybox shells to use busybox applets
in preference to executables in the PATH whenever possible. For
@ -121,7 +121,7 @@ config FEATURE_SH_STANDALONE
config FEATURE_SH_NOFORK
bool "Run 'nofork' applets directly"
default n
depends on (HUSH || ASH) && FEATURE_PREFER_APPLETS
depends on (HUSH || ASH)
help
This option causes busybox shells to not execute typical
fork/exec/wait sequence, but call <applet>_main directly,

View File

@ -9982,9 +9982,11 @@ static int FAST_FUNC builtin_break(char **argv)
unsigned depth;
if (G.depth_of_loop == 0) {
bb_error_msg("%s: only meaningful in a loop", argv[0]);
/* if we came from builtin_continue(), need to undo "= 1" */
G.flag_break_continue = 0;
return EXIT_SUCCESS; /* bash compat */
}
G.flag_break_continue++; /* BC_BREAK = 1 */
G.flag_break_continue++; /* BC_BREAK = 1, or BC_CONTINUE = 2 */
G.depth_break_continue = depth = parse_numeric_argv1(argv, 1, 1);
if (depth == UINT_MAX)