From b9c2108b26ad1fe4634c250850a4abadff26c76e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 12 May 2022 11:07:12 +0200 Subject: examples/var_service/dhcp_if: make helper scripts more talkative Signed-off-by: Denys Vlasenko --- examples/var_service/dhcp_if/convert2ipconf | 16 ++++++++++++---- examples/var_service/dhcp_if/convert2ntpconf | 2 +- examples/var_service/dhcp_if/dhcp_handler | 6 ++---- examples/var_service/dhcp_if/finish | 2 +- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/examples/var_service/dhcp_if/convert2ipconf b/examples/var_service/dhcp_if/convert2ipconf index 31e3c7fde..98f6546bf 100755 --- a/examples/var_service/dhcp_if/convert2ipconf +++ b/examples/var_service/dhcp_if/convert2ipconf @@ -19,7 +19,7 @@ #let cfg=cfg+1 #if[$cfg]=...; ip[$cfg]=...; ipmask[$cfg]=.../...; gw[$cfg]=...; net[$cfg]=... dns[$cfg]=... -exec >/dev/null +#exec >/dev/null #exec >"$0.out" # debug exec 2>&1 @@ -31,23 +31,31 @@ test "$ip" || exit 1 if ! test "$mask"; then case "$ip" in 10.*) + echo "mask assumed 8 for ip=$ip" mask=8;; - 192.168.*) - mask=16;; #172.16-31.x.x 172.1[6789].*) + echo "mask assumed 12 for ip=$ip" mask=12;; 172.2[0123456789].*) + echo "mask assumed 12 for ip=$ip" mask=12;; 172.3[01].*) + echo "mask assumed 12 for ip=$ip" mask=12;; + 192.168.*) + echo "mask assumed 16 for ip=$ip" + mask=16;; esac fi # some servers do not return router option. # assume DHCP server is the router. if ! test "$router"; then - test "$serverid" && router="$serverid" + if test "$serverid"; then + router="$serverid" + echo "No 'router' from the server, assuming 'serverid' is the router: $serverid" + fi fi { diff --git a/examples/var_service/dhcp_if/convert2ntpconf b/examples/var_service/dhcp_if/convert2ntpconf index e9d829308..f51740ba0 100755 --- a/examples/var_service/dhcp_if/convert2ntpconf +++ b/examples/var_service/dhcp_if/convert2ntpconf @@ -19,7 +19,7 @@ #let cfg=cfg+1 #ntpip[$cfg]=... -exec >/dev/null +#exec >/dev/null #exec >"$0.out" # debug exec 2>&1 diff --git a/examples/var_service/dhcp_if/dhcp_handler b/examples/var_service/dhcp_if/dhcp_handler index 6a97e8543..3e652621d 100755 --- a/examples/var_service/dhcp_if/dhcp_handler +++ b/examples/var_service/dhcp_if/dhcp_handler @@ -38,12 +38,10 @@ file_ntpconf="$service.ntpconf" dir_ipconf="/var/run/service/fw" dir_ntpconf="/var/run/service/ntpd" -exec >/dev/null -#exec >>"$0.out" #debug +#exec >/dev/null +#exec >"$0.out" #debug exec 2>&1 -echo "`date`: Params: $*" - if test x"$1" != x"bound" && test x"$1" != x"renew" ; then # Reconfigure network with this interface disabled echo "Deconfiguring" diff --git a/examples/var_service/dhcp_if/finish b/examples/var_service/dhcp_if/finish index 8ce188336..50bfe67b5 100755 --- a/examples/var_service/dhcp_if/finish +++ b/examples/var_service/dhcp_if/finish @@ -1,5 +1,5 @@ #!/bin/sh -# executed when service is taken down ("sv d .") +# executed when service is taken down ("svc -d .") service=${PWD##*/} file_ipconf="$service.ipconf" -- cgit v1.2.3-55-g6feb From 8d67007a4dedef77dd0cf757bcc0e6fbee267ced Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 12 May 2022 11:44:47 +0200 Subject: top: improve large PID display in memory ('s') mode function old new delta display_topmem_process_list 530 564 +34 Signed-off-by: Denys Vlasenko --- procps/top.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/procps/top.c b/procps/top.c index 744f20e9b..ff775422c 100644 --- a/procps/top.c +++ b/procps/top.c @@ -879,8 +879,11 @@ static NOINLINE void display_topmem_process_list(int lines_rem, int scr_width) lines_rem = ntop - G_scroll_ofs; while (--lines_rem >= 0) { /* PID VSZ VSZRW RSS (SHR) DIRTY (SHR) COMMAND */ - ulltoa6_and_space(s->pid , &line_buf[0*6]); + int n = sprintf(line_buf, "%5u ", s->pid); ulltoa6_and_space(s->vsz , &line_buf[1*6]); + if (n > 7 || (n == 7 && line_buf[6] != ' ')) + /* PID and VSZ are clumped together, truncate PID */ + line_buf[5] = '.'; ulltoa6_and_space(s->vszrw , &line_buf[2*6]); ulltoa6_and_space(s->rss , &line_buf[3*6]); ulltoa6_and_space(s->rss_sh , &line_buf[4*6]); -- cgit v1.2.3-55-g6feb From 95fec31be601bfdced6bed7007a33b26e968e0db Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 21 Apr 2022 08:02:15 +0100 Subject: libbb: restore special handling of nomsg errors The functions bb_perror_nomsg() and bb_perror_nomsg_and_die() are used to print error messages where no specific information is available. For example: $ busybox mktemp -p / mktemp: (null): Permission denied mktemp(3) doesn't tell us the name of the file it tried to create. However, printing '(null)' is a regression introduced by commit 6937487be (libbb: reduce the overhead of single parameter bb_error_msg() calls). Restore the previous behaviour by reverting the changes to the two functions mentioned: $ busybox mktemp -p / mktemp: Permission denied function old new delta bb_perror_nomsg_and_die 7 14 +7 bb_perror_nomsg 7 14 +7 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 14/0) Total: 14 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- libbb/perror_nomsg.c | 4 ++-- libbb/perror_nomsg_and_die.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libbb/perror_nomsg.c b/libbb/perror_nomsg.c index d7d53de44..a2a11cc8e 100644 --- a/libbb/perror_nomsg.c +++ b/libbb/perror_nomsg.c @@ -12,11 +12,11 @@ * instead of including libbb.h */ //#include "libbb.h" #include "platform.h" -extern void bb_simple_perror_msg(const char *s) FAST_FUNC; +extern void bb_perror_msg(const char *s, ...) FAST_FUNC; /* suppress gcc "no previous prototype" warning */ void FAST_FUNC bb_perror_nomsg(void); void FAST_FUNC bb_perror_nomsg(void) { - bb_simple_perror_msg(0); + bb_perror_msg(0); } diff --git a/libbb/perror_nomsg_and_die.c b/libbb/perror_nomsg_and_die.c index bea5f25a5..543ff5178 100644 --- a/libbb/perror_nomsg_and_die.c +++ b/libbb/perror_nomsg_and_die.c @@ -12,11 +12,11 @@ * instead of including libbb.h */ //#include "libbb.h" #include "platform.h" -extern void bb_simple_perror_msg_and_die(const char *s) FAST_FUNC; +extern void bb_perror_msg_and_die(const char *s, ...) FAST_FUNC; /* suppress gcc "no previous prototype" warning */ void FAST_FUNC bb_perror_nomsg_and_die(void); void FAST_FUNC bb_perror_nomsg_and_die(void) { - bb_simple_perror_msg_and_die(0); + bb_perror_msg_and_die(0); } -- cgit v1.2.3-55-g6feb From 7d1c7d8337853ca99e6ec1150ac4b834cfed5cd3 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 24 Mar 2022 12:17:25 +0000 Subject: ash,hush: use HOME for tab completion and prompts ash and hush correctly use the value of HOME for tilde expansion. However the line editing code in libbb obtains the user's home directory by calling getpwuid(). Thus tildes in tab completion and prompts may be interpreted differently than in tilde expansion. When the line editing code is invoked from a shell make it use the shell's interpretation of tilde. This is similar to how GNU readline and bash collaborate. function old new delta get_homedir_or_NULL 29 72 +43 optschanged 119 126 +7 hush_main 1204 1211 +7 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 57/0) Total: 57 bytes v2: Always check for HOME before trying the password database: this is what GNU readline does. Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- include/libbb.h | 11 +++-------- libbb/lineedit.c | 12 +++++++++++- shell/ash.c | 7 +++---- shell/hush.c | 5 ++--- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 6aeec249d..abbc9ac59 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1924,6 +1924,7 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC; # define MAX_HISTORY 0 # endif typedef const char *get_exe_name_t(int i) FAST_FUNC; +typedef const char *sh_get_var_t(const char *name) FAST_FUNC; typedef struct line_input_t { int flags; int timeout; @@ -1937,9 +1938,8 @@ typedef struct line_input_t { # if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH /* function to fetch additional application-specific names to match */ get_exe_name_t *get_exe_name; -# define EDITING_HAS_get_exe_name 1 -# else -# define EDITING_HAS_get_exe_name 0 + /* function to fetch value of shell variable */ + sh_get_var_t *sh_get_var; # endif # endif # if MAX_HISTORY @@ -1993,11 +1993,6 @@ int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; read_line_input(prompt, command, maxsize) #endif -#ifndef EDITING_HAS_get_exe_name -# define EDITING_HAS_get_exe_name 0 -#endif - - #ifndef COMM_LEN # ifdef TASK_COMM_LEN enum { COMM_LEN = TASK_COMM_LEN }; diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 82624757e..b685399f9 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -259,6 +259,16 @@ static const char *get_username_str(void) 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"); +# else + home = getenv("HOME"); +# endif + if (home != NULL && home[0] != '\0') + return home; + if (!got_user_strings) get_user_strings(); return home_pwd_buf; @@ -861,7 +871,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) continue; } # endif -# if EDITING_HAS_get_exe_name +# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH if (state->get_exe_name) { i = 0; for (;;) { diff --git a/shell/ash.c b/shell/ash.c index ef4a47afe..d29de37b7 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -9720,7 +9720,7 @@ evalpipe(union node *n, int flags) } /* setinteractive needs this forward reference */ -#if EDITING_HAS_get_exe_name +#if ENABLE_FEATURE_EDITING static const char *get_builtin_name(int i) FAST_FUNC; #endif @@ -9757,9 +9757,8 @@ setinteractive(int on) #if ENABLE_FEATURE_EDITING if (!line_input_state) { line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); -# if EDITING_HAS_get_exe_name line_input_state->get_exe_name = get_builtin_name; -# endif + line_input_state->sh_get_var = lookupvar; } #endif } @@ -10262,7 +10261,7 @@ find_builtin(const char *name) return bp; } -#if EDITING_HAS_get_exe_name +#if ENABLE_FEATURE_EDITING static const char * FAST_FUNC get_builtin_name(int i) { diff --git a/shell/hush.c b/shell/hush.c index ae81f0da5..051b123e7 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -8188,7 +8188,7 @@ static const struct built_in_command *find_builtin(const char *name) return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]); } -#if ENABLE_HUSH_JOB && EDITING_HAS_get_exe_name +#if ENABLE_HUSH_JOB && ENABLE_FEATURE_EDITING static const char * FAST_FUNC get_builtin_name(int i) { if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { @@ -10668,9 +10668,8 @@ int hush_main(int argc, char **argv) # if ENABLE_FEATURE_EDITING G.line_input_state = new_line_input_t(FOR_SHELL); -# if EDITING_HAS_get_exe_name G.line_input_state->get_exe_name = get_builtin_name; -# endif + G.line_input_state->sh_get_var = get_local_var_value; # endif # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 { -- cgit v1.2.3-55-g6feb From af3b585815de5af367995d6064d994394b46c928 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 18 Mar 2022 11:29:53 +0000 Subject: vi: fix regression in autoindent handling Suppose autoindent is enabled and we have a line with an initial tab where we want to split the words onto separate lines: split the words One way to do this is with the sequence 'f r;r', but in BusyBox vi the result is: split he words This is a regression introduced by commit 9659a8db1 (vi: remove autoindent from otherwise empty lines). The amount of indentation is being recorded when the 'r' command inserts a newline but isn't subsequently reset. A fix is to only record the indent when in insert or replace mode. Proper handling of the 'o' and 'O' commands then requires them to switch to insert mode before calling char_insert() to insert a newline. function old new delta char_insert 884 891 +7 do_cmd 4243 4247 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 11/0) Total: 11 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- editors/vi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/editors/vi.c b/editors/vi.c index 6fa0a4e18..5b86b0516 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -2227,7 +2227,10 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' p--; // open above, indent before newly inserted NL if (len) { - indentcol = col; + // only record indent if in insert/replace mode or for + // the 'o'/'O' commands, which are switched to insert + // mode early. + indentcol = cmd_mode != 0 ? col : 0; if (expandtab) { ntab = 0; nspc = col; @@ -4265,6 +4268,9 @@ static void do_cmd(int c) case 'o': // o- open an empty line below dot_end(); dc3: +#if ENABLE_FEATURE_VI_SETOPTS + cmd_mode = 1; // switch to insert mode early +#endif dot = char_insert(dot, '\n', ALLOW_UNDO); if (c == 'O' && !autoindent) { // done in char_insert() for 'O'+autoindent -- cgit v1.2.3-55-g6feb From 2617a5e4c600b4577b2c18f794701276e55da43b Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 18 Mar 2022 11:30:38 +0000 Subject: vi: handle autoindent in 'cc' command When the 'cc' command is invoked with autoindent enabled it should use the indent of the first line being changed. The size of the indent has to be established before char_insert() is called as the lines being changed are deleted. Introduce a new global variable, newindent, to handle this. The indentcol global is now effectively a static variable in char_insert(). function old new delta do_cmd 4247 4308 +61 vi_main 416 422 +6 char_insert 891 875 -16 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 67/-16) Total: 51 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- editors/vi.c | 71 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/editors/vi.c b/editors/vi.c index 5b86b0516..d799a8170 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -380,7 +380,9 @@ struct globals { char *last_search_pattern; // last pattern from a '/' or '?' search #endif #if ENABLE_FEATURE_VI_SETOPTS - int indentcol; // column of recently autoindent, 0 or -1 + int char_insert__indentcol; // column of recent autoindent or 0 + int newindent; // autoindent value for 'O'/'cc' commands + // or -1 to use indent from previous line #endif smallint cmd_error; @@ -507,7 +509,8 @@ struct globals { #define ioq_start (G.ioq_start ) #define dotcnt (G.dotcnt ) #define last_search_pattern (G.last_search_pattern) -#define indentcol (G.indentcol ) +#define char_insert__indentcol (G.char_insert__indentcol) +#define newindent (G.newindent ) #define cmd_error (G.cmd_error ) #define edit_file__cur_line (G.edit_file__cur_line) @@ -540,10 +543,11 @@ struct globals { #define INIT_G() do { \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ - last_modified_count = -1; \ + last_modified_count--; \ /* "" but has space for 2 chars: */ \ IF_FEATURE_VI_SEARCH(last_search_pattern = xzalloc(2);) \ tabstop = 8; \ + IF_FEATURE_VI_SETOPTS(newindent--;) \ } while (0) #if ENABLE_FEATURE_VI_CRASHME @@ -2113,6 +2117,7 @@ static size_t indent_len(char *p) static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' { #if ENABLE_FEATURE_VI_SETOPTS +# define indentcol char_insert__indentcol size_t len; int col, ntab, nspc; #endif @@ -2141,7 +2146,8 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' #if ENABLE_FEATURE_VI_SETOPTS if (autoindent) { len = indent_len(bol); - if (len && get_column(bol + len) == indentcol && bol[len] == '\n') { + col = get_column(bol + len); + if (len && col == indentcol && bol[len] == '\n') { // remove autoindent from otherwise empty line text_hole_delete(bol, bol + len - 1, undo); p = bol; @@ -2210,26 +2216,30 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' showmatching(p - 1); } if (autoindent && c == '\n') { // auto indent the new line - // use indent of current/previous line - bol = indentcol < 0 ? p : prev_line(p); - len = indent_len(bol); - col = get_column(bol + len); - - if (len && col == indentcol) { - // previous line was empty except for autoindent - // move the indent to the current line - memmove(bol + 1, bol, len); - *bol = '\n'; - return p; + if (newindent < 0) { + // use indent of previous line + bol = prev_line(p); + len = indent_len(bol); + col = get_column(bol + len); + + if (len && col == indentcol) { + // previous line was empty except for autoindent + // move the indent to the current line + memmove(bol + 1, bol, len); + *bol = '\n'; + return p; + } + } else { + // for 'O'/'cc' commands add indent before newly inserted NL + if (p != end - 1) // but not for 'cc' at EOF + p--; + col = newindent; } - if (indentcol < 0) - p--; // open above, indent before newly inserted NL - - if (len) { + if (col) { // only record indent if in insert/replace mode or for - // the 'o'/'O' commands, which are switched to insert - // mode early. + // the 'o'/'O'/'cc' commands, which are switched to + // insert mode early. indentcol = cmd_mode != 0 ? col : 0; if (expandtab) { ntab = 0; @@ -2252,6 +2262,7 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' } #if ENABLE_FEATURE_VI_SETOPTS indentcol = 0; +# undef indentcol #endif return p; } @@ -4220,6 +4231,9 @@ static void do_cmd(int c) case 'i': // i- insert before current char case KEYCODE_INSERT: // Cursor Key Insert dc_i: +#if ENABLE_FEATURE_VI_SETOPTS + newindent = -1; +#endif cmd_mode = 1; // start inserting undo_queue_commit(); // commit queue when cmd_mode changes break; @@ -4262,7 +4276,8 @@ static void do_cmd(int c) case 'O': // O- open an empty line above dot_begin(); #if ENABLE_FEATURE_VI_SETOPTS - indentcol = -1; + // special case: use indent of current line + newindent = get_column(dot + indent_len(dot)); #endif goto dc3; case 'o': // o- open an empty line below @@ -4385,14 +4400,22 @@ static void do_cmd(int c) if (buftype == WHOLE) { save_dot = p; // final cursor position is start of range p = begin_line(p); +#if ENABLE_FEATURE_VI_SETOPTS + if (c == 'c') // special case: use indent of current line + newindent = get_column(p + indent_len(p)); +#endif q = end_line(q); } dot = yank_delete(p, q, buftype, yf, ALLOW_UNDO); // delete word if (buftype == WHOLE) { if (c == 'c') { +#if ENABLE_FEATURE_VI_SETOPTS + cmd_mode = 1; // switch to insert mode early +#endif dot = char_insert(dot, '\n', ALLOW_UNDO_CHAIN); - // on the last line of file don't move to prev line - if (dot != (end-1)) { + // on the last line of file don't move to prev line, + // handled in char_insert() if autoindent is enabled + if (dot != (end-1) && !autoindent) { dot_prev(); } } else if (c == 'd') { -- cgit v1.2.3-55-g6feb