aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2015-01-28 19:42:28 +0200
committerEli Zaretskii2015-01-28 19:42:28 +0200
commitad588afdaa166bcdacbf9f746bd4d39b2c649768 (patch)
treec3562982b7a711957cc43a87163e8ca791aa9dab
parentba10f4b56081d0f5069720c9ce0871e819b904f5 (diff)
downloademacs-ad588afdaa166bcdacbf9f746bd4d39b2c649768.tar.gz
emacs-ad588afdaa166bcdacbf9f746bd4d39b2c649768.zip
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.
-rw-r--r--src/ChangeLog13
-rw-r--r--src/dired.c15
-rw-r--r--src/w32.c41
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 @@
12015-01-28 Eli Zaretskii <eliz@gnu.org>
2
3 * dired.c (directory_files_internal, file_name_completion)
4 [WINDOWSNT]: Signal an error when errno is set non-zero by
5 'readdir', regardless of its value.
6
7 * w32.c (sys_readdir): Set errno to ENOENT when the directory
8 doesn't exist and to EACCES when it's not accessible to the
9 current user. Set errno to zero when FindNextFile exhausts the
10 directory, so that callers don't interpret that as an error and
11 don't signal a file-error.
12 (open_unc_volume): Set errno to ENOENT if WNetOpenEnum fails.
13
12015-01-27 Eli Zaretskii <eliz@gnu.org> 142015-01-27 Eli Zaretskii <eliz@gnu.org>
2 15
3 * dired.c (directory_files_internal) [WINDOWSNT]: If readdir 16 * 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,
251 /* The MS-Windows implementation of 'opendir' doesn't 251 /* The MS-Windows implementation of 'opendir' doesn't
252 actually open a directory until the first call to 252 actually open a directory until the first call to
253 'readdir'. If 'readdir' fails to open the directory, it 253 'readdir'. If 'readdir' fails to open the directory, it
254 sets errno to ENOTDIR; we convert it here to ENOENT so 254 sets errno to ENOENT or EACCES, see w32.c. */
255 that the error message is similar to what happens on 255 if (errno)
256 Posix hosts in such cases. */ 256 report_file_error ("Opening directory", directory);
257 if (errno == ENOTDIR)
258 {
259 errno = ENOENT;
260 report_file_error ("Opening directory", directory);
261 }
262#endif 257#endif
263 break; 258 break;
264 } 259 }
@@ -530,6 +525,10 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
530 QUIT; 525 QUIT;
531 continue; 526 continue;
532 } 527 }
528#ifdef WINDOWSNT
529 if (errno)
530 report_file_error ("Opening directory", dirname);
531#endif
533 break; 532 break;
534 } 533 }
535 534
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)
3433 3433
3434 if (dir_find_handle == INVALID_HANDLE_VALUE) 3434 if (dir_find_handle == INVALID_HANDLE_VALUE)
3435 { 3435 {
3436 /* Any changes in the value of errno here should be in sync
3437 with what directory_files_internal does when it calls
3438 readdir. */
3436 switch (GetLastError ()) 3439 switch (GetLastError ())
3437 { 3440 {
3438 case ERROR_PATH_NOT_FOUND: 3441 /* Windows uses this value when FindFirstFile finds no
3442 files that match the wildcard. This is not supposed
3443 to happen, since our wildcard is "*", but just in
3444 case, if there's some weird empty directory with not
3445 even "." and ".." entries... */
3446 case ERROR_FILE_NOT_FOUND:
3447 errno = 0;
3448 /* FALLTHRU */
3449 default:
3450 break;
3439 case ERROR_ACCESS_DENIED: 3451 case ERROR_ACCESS_DENIED:
3452 case ERROR_NETWORK_ACCESS_DENIED:
3453 errno = EACCES;
3454 break;
3455 case ERROR_PATH_NOT_FOUND:
3440 case ERROR_INVALID_DRIVE: 3456 case ERROR_INVALID_DRIVE:
3441 case ERROR_BAD_NETPATH: 3457 case ERROR_BAD_NETPATH:
3442 /* This special value will be noticed by 3458 case ERROR_BAD_NET_NAME:
3443 directory_files_internal, which see. */ 3459 errno = ENOENT;
3444 errno = ENOTDIR;
3445 break;
3446 default:
3447 break; 3460 break;
3448 } 3461 }
3449 return NULL; 3462 return NULL;
@@ -3452,12 +3465,18 @@ sys_readdir (DIR *dirp)
3452 else if (w32_unicode_filenames) 3465 else if (w32_unicode_filenames)
3453 { 3466 {
3454 if (!FindNextFileW (dir_find_handle, &dir_find_data_w)) 3467 if (!FindNextFileW (dir_find_handle, &dir_find_data_w))
3455 return NULL; 3468 {
3469 errno = 0;
3470 return NULL;
3471 }
3456 } 3472 }
3457 else 3473 else
3458 { 3474 {
3459 if (!FindNextFileA (dir_find_handle, &dir_find_data_a)) 3475 if (!FindNextFileA (dir_find_handle, &dir_find_data_a))
3460 return NULL; 3476 {
3477 errno = 0;
3478 return NULL;
3479 }
3461 } 3480 }
3462 3481
3463 /* Emacs never uses this value, so don't bother making it match 3482 /* Emacs never uses this value, so don't bother making it match
@@ -3559,7 +3578,11 @@ open_unc_volume (const char *path)
3559 if (result == NO_ERROR) 3578 if (result == NO_ERROR)
3560 return henum; 3579 return henum;
3561 else 3580 else
3562 return INVALID_HANDLE_VALUE; 3581 {
3582 /* Make sure directory_files_internal reports a sensible error. */
3583 errno = ENOENT;
3584 return INVALID_HANDLE_VALUE;
3585 }
3563} 3586}
3564 3587
3565static void * 3588static void *