diff options
author | Ron Yorston <rmy@pobox.com> | 2024-01-04 07:59:49 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2024-01-04 07:59:49 +0000 |
commit | 0bbb4f442b862190fbddc4603f786787ba5a09f0 (patch) | |
tree | 6f20a55154a41005fc43ba49fc1c074eb6651d2b | |
parent | 9197a9ef026e3d57d291f05ea6f91956d152d116 (diff) | |
download | busybox-w32-0bbb4f442b862190fbddc4603f786787ba5a09f0.tar.gz busybox-w32-0bbb4f442b862190fbddc4603f786787ba5a09f0.tar.bz2 busybox-w32-0bbb4f442b862190fbddc4603f786787ba5a09f0.zip |
win32: fix detection of directories in stat(2)
The implementation of stat(2) detected whether a pathname ending
with a directory separator was valid by checking for the error
code ERROR_INVALID_NAME when GetFileAttributesExA() failed.
This works if the path refers to an actual disk but not if it's on
a share. In the latter case the glob '*/' incorrectly returned files
that weren't directories.
Add code to handle this case.
Costs 16-32 bytes.
(GitHub issue #381)
-rw-r--r-- | win32/mingw.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/win32/mingw.c b/win32/mingw.c index 977848a2a..093e795ac 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -357,7 +357,7 @@ static inline mode_t file_attr_to_st_mode(DWORD attr) | |||
357 | 357 | ||
358 | static int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fdata) | 358 | static int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fdata) |
359 | { | 359 | { |
360 | size_t len; | 360 | char *want_dir; |
361 | 361 | ||
362 | if (get_dev_type(fname) != NOT_DEVICE || get_dev_fd(fname) >= 0) { | 362 | if (get_dev_type(fname) != NOT_DEVICE || get_dev_fd(fname) >= 0) { |
363 | /* Fake attributes for special devices */ | 363 | /* Fake attributes for special devices */ |
@@ -369,7 +369,10 @@ static int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fdata) | |||
369 | return 0; | 369 | return 0; |
370 | } | 370 | } |
371 | 371 | ||
372 | want_dir = last_char_is_dir_sep(fname); | ||
372 | if (GetFileAttributesExA(fname, GetFileExInfoStandard, fdata)) { | 373 | if (GetFileAttributesExA(fname, GetFileExInfoStandard, fdata)) { |
374 | if (!(fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && want_dir) | ||
375 | return ENOTDIR; | ||
373 | fdata->dwFileAttributes &= ~FILE_ATTRIBUTE_DEVICE; | 376 | fdata->dwFileAttributes &= ~FILE_ATTRIBUTE_DEVICE; |
374 | return 0; | 377 | return 0; |
375 | } | 378 | } |
@@ -402,8 +405,7 @@ static int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fdata) | |||
402 | case ERROR_NOT_ENOUGH_MEMORY: | 405 | case ERROR_NOT_ENOUGH_MEMORY: |
403 | return ENOMEM; | 406 | return ENOMEM; |
404 | case ERROR_INVALID_NAME: | 407 | case ERROR_INVALID_NAME: |
405 | len = strlen(fname); | 408 | if (want_dir) |
406 | if (len > 1 && (fname[len-1] == '/' || fname[len-1] == '\\')) | ||
407 | return ENOTDIR; | 409 | return ENOTDIR; |
408 | default: | 410 | default: |
409 | return ENOENT; | 411 | return ENOENT; |