diff options
author | Ron Yorston <rmy@pobox.com> | 2023-09-20 10:06:19 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-09-20 10:06:19 +0100 |
commit | 1ff6eb52032bb52501ef3bd8b49010ac19efa268 (patch) | |
tree | 513deff2b4a6aebe37bb38d1bc5736da2246e183 /shell | |
parent | 1fcd57ab583a39f42b55f44d42472ea64e228c84 (diff) | |
download | busybox-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)
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 49 |
1 files changed, 41 insertions, 8 deletions
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 | ||
8688 | static int FAST_FUNC | ||
8689 | ash_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; |