Improve the fix for bug #19701

src/dired.c (directory_files_internal, file_name_completion)
 [WINDOWSNT]: Signal an error when errno is set non-zero by
 'readdir', regardless of its value.
 src/w32.c (sys_readdir): Set errno to ENOENT when the directory
 doesn't exist and to EACCES when it's not accessible to the
 current user.  Set errno to zero when FindNextFile exhausts the
 directory, so that callers don't interpret that as an error and
 don't signal a file-error.
 (open_unc_volume): Set errno to ENOENT if WNetOpenEnum fails.
This commit is contained in:
Eli Zaretskii 2015-01-28 19:42:28 +02:00
parent ba10f4b560
commit ad588afdaa
3 changed files with 52 additions and 17 deletions

View file

@ -1,3 +1,16 @@
2015-01-28 Eli Zaretskii <eliz@gnu.org>
* dired.c (directory_files_internal, file_name_completion)
[WINDOWSNT]: Signal an error when errno is set non-zero by
'readdir', regardless of its value.
* w32.c (sys_readdir): Set errno to ENOENT when the directory
doesn't exist and to EACCES when it's not accessible to the
current user. Set errno to zero when FindNextFile exhausts the
directory, so that callers don't interpret that as an error and
don't signal a file-error.
(open_unc_volume): Set errno to ENOENT if WNetOpenEnum fails.
2015-01-27 Eli Zaretskii <eliz@gnu.org>
* dired.c (directory_files_internal) [WINDOWSNT]: If readdir

View file

@ -251,14 +251,9 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
/* The MS-Windows implementation of 'opendir' doesn't
actually open a directory until the first call to
'readdir'. If 'readdir' fails to open the directory, it
sets errno to ENOTDIR; we convert it here to ENOENT so
that the error message is similar to what happens on
Posix hosts in such cases. */
if (errno == ENOTDIR)
{
errno = ENOENT;
report_file_error ("Opening directory", directory);
}
sets errno to ENOENT or EACCES, see w32.c. */
if (errno)
report_file_error ("Opening directory", directory);
#endif
break;
}
@ -530,6 +525,10 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
QUIT;
continue;
}
#ifdef WINDOWSNT
if (errno)
report_file_error ("Opening directory", dirname);
#endif
break;
}

View file

@ -3433,17 +3433,30 @@ sys_readdir (DIR *dirp)
if (dir_find_handle == INVALID_HANDLE_VALUE)
{
/* Any changes in the value of errno here should be in sync
with what directory_files_internal does when it calls
readdir. */
switch (GetLastError ())
{
case ERROR_PATH_NOT_FOUND:
/* Windows uses this value when FindFirstFile finds no
files that match the wildcard. This is not supposed
to happen, since our wildcard is "*", but just in
case, if there's some weird empty directory with not
even "." and ".." entries... */
case ERROR_FILE_NOT_FOUND:
errno = 0;
/* FALLTHRU */
default:
break;
case ERROR_ACCESS_DENIED:
case ERROR_NETWORK_ACCESS_DENIED:
errno = EACCES;
break;
case ERROR_PATH_NOT_FOUND:
case ERROR_INVALID_DRIVE:
case ERROR_BAD_NETPATH:
/* This special value will be noticed by
directory_files_internal, which see. */
errno = ENOTDIR;
break;
default:
case ERROR_BAD_NET_NAME:
errno = ENOENT;
break;
}
return NULL;
@ -3452,12 +3465,18 @@ sys_readdir (DIR *dirp)
else if (w32_unicode_filenames)
{
if (!FindNextFileW (dir_find_handle, &dir_find_data_w))
return NULL;
{
errno = 0;
return NULL;
}
}
else
{
if (!FindNextFileA (dir_find_handle, &dir_find_data_a))
return NULL;
{
errno = 0;
return NULL;
}
}
/* Emacs never uses this value, so don't bother making it match
@ -3559,7 +3578,11 @@ open_unc_volume (const char *path)
if (result == NO_ERROR)
return henum;
else
return INVALID_HANDLE_VALUE;
{
/* Make sure directory_files_internal reports a sensible error. */
errno = ENOENT;
return INVALID_HANDLE_VALUE;
}
}
static void *