diff options
-rw-r--r-- | src/ChangeLog | 13 | ||||
-rw-r--r-- | src/dired.c | 15 | ||||
-rw-r--r-- | src/w32.c | 41 |
3 files changed, 52 insertions, 17 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index a33e834e0ec..dc495089739 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -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 diff --git a/src/dired.c b/src/dired.c index f6c47a71400..43cb8373a6d 100644 --- a/src/dired.c +++ b/src/dired.c @@ -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; } diff --git a/src/w32.c b/src/w32.c index aedf64942e0..2faa742f9d7 100644 --- a/src/w32.c +++ b/src/w32.c @@ -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 * |