diff options
author | Ron Yorston <rmy@pobox.com> | 2021-07-26 15:05:57 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-07-26 15:26:30 +0100 |
commit | 5c2241c4b32607f138824c3454b7b32b2916fd02 (patch) | |
tree | 49667c5bf5f9b99c534c8da30bd2e574b1975de0 | |
parent | c79f1302589885a6b5500c38c20f1cc5d00e006f (diff) | |
download | busybox-w32-5c2241c4b32607f138824c3454b7b32b2916fd02.tar.gz busybox-w32-5c2241c4b32607f138824c3454b7b32b2916fd02.tar.bz2 busybox-w32-5c2241c4b32607f138824c3454b7b32b2916fd02.zip |
win32: more efficient tests for executables
file_is_executable() calls access(2) and stat(2); in this case our
WIN32 implementation also calls stat(2). Avoid this unnecessary
duplication by copying the required test from the WIN32 access(2).
In find_executable() it's possible to avoid calling file_is_executable()
if add_win32_extension() returns TRUE as the latter will already have
verified that the file is executable.
Replace a call to file_is_executable() in the tab completion code
with the equivalent tests, avoiding (up to) two calls to stat(2).
These changes don't affect the size of the binary and should be
faster.
-rw-r--r-- | libbb/executable.c | 10 | ||||
-rw-r--r-- | libbb/lineedit.c | 4 |
2 files changed, 10 insertions, 4 deletions
diff --git a/libbb/executable.c b/libbb/executable.c index e20bf89e4..32b37f29d 100644 --- a/libbb/executable.c +++ b/libbb/executable.c | |||
@@ -15,7 +15,12 @@ | |||
15 | int FAST_FUNC file_is_executable(const char *name) | 15 | int FAST_FUNC file_is_executable(const char *name) |
16 | { | 16 | { |
17 | struct stat s; | 17 | struct stat s; |
18 | #if !ENABLE_PLATFORM_MINGW32 | ||
18 | return (!access(name, X_OK) && !stat(name, &s) && S_ISREG(s.st_mode)); | 19 | return (!access(name, X_OK) && !stat(name, &s) && S_ISREG(s.st_mode)); |
20 | #else | ||
21 | /* expand WIN32 implementation of access(2) */ | ||
22 | return (!stat(name, &s) && S_ISREG(s.st_mode) && (s.st_mode & S_IXUSR)); | ||
23 | #endif | ||
19 | } | 24 | } |
20 | 25 | ||
21 | /* search (*PATHp) for an executable file; | 26 | /* search (*PATHp) for an executable file; |
@@ -53,12 +58,13 @@ char* FAST_FUNC find_executable(const char *filename, char **PATHp) | |||
53 | #if ENABLE_PLATFORM_MINGW32 | 58 | #if ENABLE_PLATFORM_MINGW32 |
54 | { | 59 | { |
55 | char *w = alloc_system_drive(p); | 60 | char *w = alloc_system_drive(p); |
56 | add_win32_extension(w); | 61 | ex = add_win32_extension(w) || file_is_executable(w); |
57 | free(p); | 62 | free(p); |
58 | p = w; | 63 | p = w; |
59 | } | 64 | } |
60 | #endif | 65 | #else |
61 | ex = file_is_executable(p); | 66 | ex = file_is_executable(p); |
67 | #endif | ||
62 | if (n) *n++ = PATH_SEP; | 68 | if (n) *n++ = PATH_SEP; |
63 | if (ex) { | 69 | if (ex) { |
64 | *PATHp = n; | 70 | *PATHp = n; |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index e7de32250..f17c9a215 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -958,8 +958,8 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
958 | goto cont; /* hmm, remove in progress? */ | 958 | goto cont; /* hmm, remove in progress? */ |
959 | 959 | ||
960 | # if ENABLE_PLATFORM_MINGW32 | 960 | # if ENABLE_PLATFORM_MINGW32 |
961 | if (type == FIND_EXE_ONLY && !S_ISDIR(st.st_mode) && | 961 | if (type == FIND_EXE_ONLY && S_ISREG(st.st_mode) && |
962 | !file_is_executable(found)) | 962 | !(st.st_mode & S_IXUSR)) |
963 | goto cont; | 963 | goto cont; |
964 | # endif | 964 | # endif |
965 | 965 | ||