Skip to content

Commit 731fe28

Browse files
committed
mingw: fail with errno == ENOTDIR when appropriate
POSIX semantics requires lstat() to fail with ENOTDIR when "[a] component of the path prefix names an existing file that is neither a directory nor a symbolic link to a directory". See http://pubs.opengroup.org/onlinepubs/9699919799/functions/lstat.html This behavior is expected by t1404-update-ref-df-conflicts now. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 04db96a commit 731fe28

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

compat/mingw.c

+39
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,39 @@ int mingw_chmod(const char *filename, int mode)
634634
return _wchmod(wfilename, mode);
635635
}
636636

637+
/**
638+
* Verifies that safe_create_leading_directories() would succeed.
639+
*/
640+
static int has_valid_directory_prefix(wchar_t *wfilename)
641+
{
642+
int n = wcslen(wfilename);
643+
644+
while (n > 0) {
645+
wchar_t c = wfilename[--n];
646+
DWORD attributes;
647+
648+
if (!is_dir_sep(c))
649+
continue;
650+
651+
wfilename[n] = L'\0';
652+
attributes = GetFileAttributesW(wfilename);
653+
wfilename[n] = c;
654+
if (attributes == FILE_ATTRIBUTE_DIRECTORY ||
655+
attributes == FILE_ATTRIBUTE_DEVICE)
656+
return 1;
657+
if (attributes == INVALID_FILE_ATTRIBUTES)
658+
switch (GetLastError()) {
659+
case ERROR_PATH_NOT_FOUND:
660+
continue;
661+
case ERROR_FILE_NOT_FOUND:
662+
/* This implies parent directory exists. */
663+
return 1;
664+
}
665+
return 0;
666+
}
667+
return 1;
668+
}
669+
637670
int mingw_lstat(const char *file_name, struct stat *buf)
638671
{
639672
WIN32_FILE_ATTRIBUTE_DATA fdata;
@@ -687,6 +720,12 @@ int mingw_lstat(const char *file_name, struct stat *buf)
687720
case ERROR_NOT_ENOUGH_MEMORY:
688721
errno = ENOMEM;
689722
break;
723+
case ERROR_PATH_NOT_FOUND:
724+
if (!has_valid_directory_prefix(wfilename)) {
725+
errno = ENOTDIR;
726+
break;
727+
}
728+
/* fallthru */
690729
default:
691730
errno = ENOENT;
692731
break;

0 commit comments

Comments
 (0)