aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-09-20 10:06:19 +0100
committerRon Yorston <rmy@pobox.com>2023-09-20 10:06:19 +0100
commit1ff6eb52032bb52501ef3bd8b49010ac19efa268 (patch)
tree513deff2b4a6aebe37bb38d1bc5736da2246e183
parent1fcd57ab583a39f42b55f44d42472ea64e228c84 (diff)
downloadbusybox-w32-1ff6eb52032bb52501ef3bd8b49010ac19efa268.tar.gz
busybox-w32-1ff6eb52032bb52501ef3bd8b49010ac19efa268.tar.bz2
busybox-w32-1ff6eb52032bb52501ef3bd8b49010ac19efa268.zip
ash: add options to control globbing of hidden files
Add shell options: - 'nohiddenglob' excludes files with the hidden attribute from globbing - 'nohidsysglob' excludes files with the hidden and system attributes from globbing If both options are enabled 'nohiddenglob' takes precedence. These options also affect tab completion. Files that are hidden because they start with a period aren't affected (unless they also have the hidden attribute). Costs 160-208 bytes. (GitHub issue #367)
-rw-r--r--configs/make32_defconfig4
-rw-r--r--configs/make64_defconfig4
-rw-r--r--configs/mingw32_defconfig4
-rw-r--r--configs/mingw64_defconfig4
-rw-r--r--configs/mingw64u_defconfig4
-rw-r--r--include/libbb.h4
-rw-r--r--libbb/lineedit.c4
-rw-r--r--shell/ash.c49
8 files changed, 59 insertions, 18 deletions
diff --git a/configs/make32_defconfig b/configs/make32_defconfig
index be793be52..428c16a4e 100644
--- a/configs/make32_defconfig
+++ b/configs/make32_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.37.0.git 3# Busybox version: 1.37.0.git
4# Fri Sep 15 08:35:20 2023 4# Wed Sep 20 08:30:38 2023
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7# CONFIG_PLATFORM_POSIX is not set 7# CONFIG_PLATFORM_POSIX is not set
@@ -1165,7 +1165,7 @@ CONFIG_ASH_HELP=y
1165CONFIG_ASH_GETOPTS=y 1165CONFIG_ASH_GETOPTS=y
1166CONFIG_ASH_CMDCMD=y 1166CONFIG_ASH_CMDCMD=y
1167CONFIG_ASH_NOCONSOLE=y 1167CONFIG_ASH_NOCONSOLE=y
1168CONFIG_ASH_NOCASEGLOB=y 1168CONFIG_ASH_GLOB_OPTIONS=y
1169# CONFIG_CTTYHACK is not set 1169# CONFIG_CTTYHACK is not set
1170# CONFIG_HUSH is not set 1170# CONFIG_HUSH is not set
1171# CONFIG_SHELL_HUSH is not set 1171# CONFIG_SHELL_HUSH is not set
diff --git a/configs/make64_defconfig b/configs/make64_defconfig
index 71f08c502..c69f1e5fb 100644
--- a/configs/make64_defconfig
+++ b/configs/make64_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.37.0.git 3# Busybox version: 1.37.0.git
4# Fri Sep 15 08:35:20 2023 4# Wed Sep 20 08:30:38 2023
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7# CONFIG_PLATFORM_POSIX is not set 7# CONFIG_PLATFORM_POSIX is not set
@@ -1165,7 +1165,7 @@ CONFIG_ASH_HELP=y
1165CONFIG_ASH_GETOPTS=y 1165CONFIG_ASH_GETOPTS=y
1166CONFIG_ASH_CMDCMD=y 1166CONFIG_ASH_CMDCMD=y
1167CONFIG_ASH_NOCONSOLE=y 1167CONFIG_ASH_NOCONSOLE=y
1168CONFIG_ASH_NOCASEGLOB=y 1168CONFIG_ASH_GLOB_OPTIONS=y
1169# CONFIG_CTTYHACK is not set 1169# CONFIG_CTTYHACK is not set
1170# CONFIG_HUSH is not set 1170# CONFIG_HUSH is not set
1171# CONFIG_SHELL_HUSH is not set 1171# CONFIG_SHELL_HUSH is not set
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig
index 12e432500..3a21dfae6 100644
--- a/configs/mingw32_defconfig
+++ b/configs/mingw32_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.37.0.git 3# Busybox version: 1.37.0.git
4# Fri Sep 15 08:35:20 2023 4# Wed Sep 20 08:30:38 2023
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7# CONFIG_PLATFORM_POSIX is not set 7# CONFIG_PLATFORM_POSIX is not set
@@ -1177,7 +1177,7 @@ CONFIG_ASH_HELP=y
1177CONFIG_ASH_GETOPTS=y 1177CONFIG_ASH_GETOPTS=y
1178CONFIG_ASH_CMDCMD=y 1178CONFIG_ASH_CMDCMD=y
1179CONFIG_ASH_NOCONSOLE=y 1179CONFIG_ASH_NOCONSOLE=y
1180CONFIG_ASH_NOCASEGLOB=y 1180CONFIG_ASH_GLOB_OPTIONS=y
1181# CONFIG_CTTYHACK is not set 1181# CONFIG_CTTYHACK is not set
1182# CONFIG_HUSH is not set 1182# CONFIG_HUSH is not set
1183# CONFIG_SHELL_HUSH is not set 1183# CONFIG_SHELL_HUSH is not set
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig
index dd5a9b068..8b993460f 100644
--- a/configs/mingw64_defconfig
+++ b/configs/mingw64_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.37.0.git 3# Busybox version: 1.37.0.git
4# Fri Sep 15 08:35:20 2023 4# Wed Sep 20 08:30:38 2023
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7# CONFIG_PLATFORM_POSIX is not set 7# CONFIG_PLATFORM_POSIX is not set
@@ -1177,7 +1177,7 @@ CONFIG_ASH_HELP=y
1177CONFIG_ASH_GETOPTS=y 1177CONFIG_ASH_GETOPTS=y
1178CONFIG_ASH_CMDCMD=y 1178CONFIG_ASH_CMDCMD=y
1179CONFIG_ASH_NOCONSOLE=y 1179CONFIG_ASH_NOCONSOLE=y
1180CONFIG_ASH_NOCASEGLOB=y 1180CONFIG_ASH_GLOB_OPTIONS=y
1181# CONFIG_CTTYHACK is not set 1181# CONFIG_CTTYHACK is not set
1182# CONFIG_HUSH is not set 1182# CONFIG_HUSH is not set
1183# CONFIG_SHELL_HUSH is not set 1183# CONFIG_SHELL_HUSH is not set
diff --git a/configs/mingw64u_defconfig b/configs/mingw64u_defconfig
index 159f409d9..a7428d1d2 100644
--- a/configs/mingw64u_defconfig
+++ b/configs/mingw64u_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.37.0.git 3# Busybox version: 1.37.0.git
4# Fri Sep 15 08:35:20 2023 4# Wed Sep 20 08:30:38 2023
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7# CONFIG_PLATFORM_POSIX is not set 7# CONFIG_PLATFORM_POSIX is not set
@@ -1177,7 +1177,7 @@ CONFIG_ASH_HELP=y
1177CONFIG_ASH_GETOPTS=y 1177CONFIG_ASH_GETOPTS=y
1178CONFIG_ASH_CMDCMD=y 1178CONFIG_ASH_CMDCMD=y
1179CONFIG_ASH_NOCONSOLE=y 1179CONFIG_ASH_NOCONSOLE=y
1180CONFIG_ASH_NOCASEGLOB=y 1180CONFIG_ASH_GLOB_OPTIONS=y
1181# CONFIG_CTTYHACK is not set 1181# CONFIG_CTTYHACK is not set
1182# CONFIG_HUSH is not set 1182# CONFIG_HUSH is not set
1183# CONFIG_SHELL_HUSH is not set 1183# CONFIG_SHELL_HUSH is not set
diff --git a/include/libbb.h b/include/libbb.h
index 2cdfac639..bbb3108a9 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2011,6 +2011,7 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC;
2011# endif 2011# endif
2012typedef const char *get_exe_name_t(int i) FAST_FUNC; 2012typedef const char *get_exe_name_t(int i) FAST_FUNC;
2013typedef const char *sh_get_var_t(const char *name) FAST_FUNC; 2013typedef const char *sh_get_var_t(const char *name) FAST_FUNC;
2014typedef int sh_accept_glob_t(const char *name) FAST_FUNC;
2014typedef struct line_input_t { 2015typedef struct line_input_t {
2015 int flags; 2016 int flags;
2016 int timeout; 2017 int timeout;
@@ -2024,6 +2025,9 @@ typedef struct line_input_t {
2024# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH 2025# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH
2025 /* function to fetch additional application-specific names to match */ 2026 /* function to fetch additional application-specific names to match */
2026 get_exe_name_t *get_exe_name; 2027 get_exe_name_t *get_exe_name;
2028# if ENABLE_ASH_GLOB_OPTIONS
2029 sh_accept_glob_t *sh_accept_glob;
2030# endif
2027# endif 2031# endif
2028# endif 2032# endif
2029# if (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) \ 2033# if (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) \
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 316c53f64..e7729996f 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -1032,6 +1032,10 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
1032 goto cont; /* hmm, remove in progress? */ 1032 goto cont; /* hmm, remove in progress? */
1033 1033
1034# if ENABLE_PLATFORM_MINGW32 1034# if ENABLE_PLATFORM_MINGW32
1035# if ENABLE_ASH_GLOB_OPTIONS
1036 if (state->sh_accept_glob && !state->sh_accept_glob(found))
1037 goto cont;
1038# endif
1035 if (type == FIND_EXE_ONLY && S_ISREG(st.st_mode) && 1039 if (type == FIND_EXE_ONLY && S_ISREG(st.st_mode) &&
1036 !(st.st_mode & S_IXUSR)) 1040 !(st.st_mode & S_IXUSR))
1037 goto cont; 1041 goto cont;
diff --git a/shell/ash.c b/shell/ash.c
index f0480f723..95bf81db3 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -196,13 +196,15 @@
196//config: application. This may be useful when running a shell script 196//config: application. This may be useful when running a shell script
197//config: from a GUI application. 197//config: from a GUI application.
198//config: 198//config:
199//config:config ASH_NOCASEGLOB 199//config:config ASH_GLOB_OPTIONS
200//config: bool "'nocaseglob' option" 200//config: bool "Globbing options"
201//config: default y 201//config: default y
202//config: depends on (ASH || SH_IS_ASH || BASH_IS_ASH) && PLATFORM_MINGW32 202//config: depends on (ASH || SH_IS_ASH || BASH_IS_ASH) && PLATFORM_MINGW32
203//config: help 203//config: help
204//config: Enable support for the 'nocaseglob' option, which allows 204//config: Enable support for options to control globbing:
205//config: case-insensitive filename globbing. 205//config: - 'nocaseglob' allows case-insensitive filename globbing
206//config: - 'nohiddenglob' allows hidden files to be omitted from globbing
207//config: - 'nohidsysglob' allows hidden system files to be omitted
206//config: 208//config:
207//config:endif # ash options 209//config:endif # ash options
208 210
@@ -545,8 +547,10 @@ static const char *const optletters_optnames[] ALIGN_PTR = {
545#if ENABLE_ASH_NOCONSOLE 547#if ENABLE_ASH_NOCONSOLE
546 ,"\0" "noconsole" 548 ,"\0" "noconsole"
547#endif 549#endif
548#if ENABLE_ASH_NOCASEGLOB 550#if ENABLE_ASH_GLOB_OPTIONS
549 ,"\0" "nocaseglob" 551 ,"\0" "nocaseglob"
552 ,"\0" "nohiddenglob"
553 ,"\0" "nohidsysglob"
550#endif 554#endif
551}; 555};
552//bash 4.4.23 also has these opts (with these defaults): 556//bash 4.4.23 also has these opts (with these defaults):
@@ -673,8 +677,10 @@ struct globals_misc {
673# if ENABLE_ASH_NOCONSOLE 677# if ENABLE_ASH_NOCONSOLE
674# define noconsole optlist[17 + BASH_PIPEFAIL + 2*(DEBUG != 0)] 678# define noconsole optlist[17 + BASH_PIPEFAIL + 2*(DEBUG != 0)]
675# endif 679# endif
676# if ENABLE_ASH_NOCASEGLOB 680# if ENABLE_ASH_GLOB_OPTIONS
677# define nocaseglob optlist[17 + BASH_PIPEFAIL + 2*(DEBUG != 0) + ENABLE_ASH_NOCONSOLE] 681# define nocaseglob optlist[17 + BASH_PIPEFAIL + 2*(DEBUG != 0) + ENABLE_ASH_NOCONSOLE]
682# define nohiddenglob optlist[18 + BASH_PIPEFAIL + 2*(DEBUG != 0) + ENABLE_ASH_NOCONSOLE]
683# define nohidsysglob optlist[19 + BASH_PIPEFAIL + 2*(DEBUG != 0) + ENABLE_ASH_NOCONSOLE]
678# endif 684# endif
679#endif 685#endif
680 686
@@ -8678,6 +8684,26 @@ expandmeta(struct strlist *str /*, int flag*/)
8678#else 8684#else
8679/* ENABLE_ASH_INTERNAL_GLOB: Homegrown globbing code. (dash also has both, uses homegrown one.) */ 8685/* ENABLE_ASH_INTERNAL_GLOB: Homegrown globbing code. (dash also has both, uses homegrown one.) */
8680 8686
8687#if ENABLE_ASH_GLOB_OPTIONS
8688static int FAST_FUNC
8689ash_accept_glob(const char *name)
8690{
8691 struct stat st;
8692
8693 if (nohiddenglob || nohidsysglob) {
8694 if (!lstat(name, &st)) {
8695 if ((st.st_attr & FILE_ATTRIBUTE_HIDDEN)) {
8696 if (nohiddenglob ||
8697 (st.st_attr & FILE_ATTRIBUTE_SYSTEM)) {
8698 return FALSE;
8699 }
8700 }
8701 }
8702 }
8703 return TRUE;
8704}
8705#endif
8706
8681/* 8707/*
8682 * Do metacharacter (i.e. *, ?, [...]) expansion. 8708 * Do metacharacter (i.e. *, ?, [...]) expansion.
8683 */ 8709 */
@@ -8783,12 +8809,16 @@ expmeta(exp_t *exp, char *name, unsigned name_len, unsigned expdir_len)
8783 while (!pending_int && (dp = readdir(dirp)) != NULL) { 8809 while (!pending_int && (dp = readdir(dirp)) != NULL) {
8784 if (dp->d_name[0] == '.' && !matchdot) 8810 if (dp->d_name[0] == '.' && !matchdot)
8785 continue; 8811 continue;
8786#if ENABLE_ASH_NOCASEGLOB 8812#if ENABLE_ASH_GLOB_OPTIONS
8787# undef pmatch 8813# undef pmatch
8788# define pmatch(a, b) !fnmatch((a), (b), nocaseglob ? FNM_CASEFOLD : 0) 8814# define pmatch(a, b) !fnmatch((a), (b), nocaseglob ? FNM_CASEFOLD : 0)
8789#endif 8815#endif
8790 if (pmatch(start, dp->d_name)) { 8816 if (pmatch(start, dp->d_name)) {
8791 if (atend) { 8817 if (atend) {
8818#if ENABLE_ASH_GLOB_OPTIONS
8819 if (!ash_accept_glob(dp->d_name))
8820 continue;
8821#endif
8792 strcpy(enddir, dp->d_name); 8822 strcpy(enddir, dp->d_name);
8793 addfname(expdir); 8823 addfname(expdir);
8794 } else { 8824 } else {
@@ -8816,7 +8846,7 @@ expmeta(exp_t *exp, char *name, unsigned name_len, unsigned expdir_len)
8816 endname[-esc - 1] = esc ? '\\' : '/'; 8846 endname[-esc - 1] = esc ? '\\' : '/';
8817#undef expdir 8847#undef expdir
8818#undef expdir_max 8848#undef expdir_max
8819#if ENABLE_ASH_NOCASEGLOB 8849#if ENABLE_ASH_GLOB_OPTIONS
8820# undef pmatch 8850# undef pmatch
8821# define pmatch(a, b) !fnmatch((a), (b), 0) 8851# define pmatch(a, b) !fnmatch((a), (b), 0)
8822#endif 8852#endif
@@ -10865,6 +10895,9 @@ setinteractive(int on)
10865 line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); 10895 line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
10866# if ENABLE_FEATURE_TAB_COMPLETION 10896# if ENABLE_FEATURE_TAB_COMPLETION
10867 line_input_state->get_exe_name = ash_command_name; 10897 line_input_state->get_exe_name = ash_command_name;
10898# if ENABLE_ASH_GLOB_OPTIONS
10899 line_input_state->sh_accept_glob = ash_accept_glob;
10900# endif
10868# endif 10901# endif
10869# if EDITING_HAS_sh_get_var 10902# if EDITING_HAS_sh_get_var
10870 line_input_state->sh_get_var = lookupvar; 10903 line_input_state->sh_get_var = lookupvar;