mirror of
https://github.com/sheumann/hush.git
synced 2025-02-06 13:30:24 +00:00
Merge with BusyBox 1.26.0 development version prior to significant hush changes.
This commit is contained in:
commit
31f1b35500
@ -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.
|
||||
|
@ -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:+", ¶m);
|
||||
|
||||
"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:", ¶m);
|
||||
|
||||
"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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user