diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 9 | ||||
| -rw-r--r-- | src/dired.c | 25 |
2 files changed, 29 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 67b6fa01b59..fc4258c9bfb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,12 @@ | |||
| 1 | 2015-01-30 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * dired.c (read_dirent): Accept an additional argument | ||
| 4 | FIRST_ENTRY. If readdir fails with ENOENT or EACCES the first | ||
| 5 | time it is called, report the error as if it happened in | ||
| 6 | open_directory. | ||
| 7 | (directory_files_internal, file_name_completion): Adjust callers | ||
| 8 | or read_dirent. | ||
| 9 | |||
| 1 | 2015-01-30 Paul Eggert <eggert@cs.ucla.edu> | 10 | 2015-01-30 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 11 | ||
| 3 | Refactor calls to opendir for simplicity | 12 | Refactor calls to opendir for simplicity |
diff --git a/src/dired.c b/src/dired.c index 7982c1fb8eb..56d6de2d352 100644 --- a/src/dired.c +++ b/src/dired.c | |||
| @@ -124,10 +124,11 @@ directory_files_internal_unwind (void *dh) | |||
| 124 | 124 | ||
| 125 | /* Return the next directory entry from DIR; DIR's name is DIRNAME. | 125 | /* Return the next directory entry from DIR; DIR's name is DIRNAME. |
| 126 | If there are no more directory entries, return a null pointer. | 126 | If there are no more directory entries, return a null pointer. |
| 127 | Signal any unrecoverable errors. */ | 127 | Signal any unrecoverable errors. FIRST_ENTRY true means this is |
| 128 | the first call after open_directory. */ | ||
| 128 | 129 | ||
| 129 | static struct dirent * | 130 | static struct dirent * |
| 130 | read_dirent (DIR *dir, Lisp_Object dirname) | 131 | read_dirent (DIR *dir, Lisp_Object dirname, bool first_entry) |
| 131 | { | 132 | { |
| 132 | while (true) | 133 | while (true) |
| 133 | { | 134 | { |
| @@ -136,7 +137,16 @@ read_dirent (DIR *dir, Lisp_Object dirname) | |||
| 136 | if (dp || errno == 0) | 137 | if (dp || errno == 0) |
| 137 | return dp; | 138 | return dp; |
| 138 | if (! (errno == EAGAIN || errno == EINTR)) | 139 | if (! (errno == EAGAIN || errno == EINTR)) |
| 139 | report_file_error ("Reading directory", dirname); | 140 | { |
| 141 | /* The MS-Windows implementation of 'opendir' doesn't | ||
| 142 | actually open a directory until the first call to | ||
| 143 | 'readdir'. If 'readdir' fails to open the directory, it | ||
| 144 | sets errno to ENOENT or EACCES, see w32.c. */ | ||
| 145 | if (first_entry && (errno == ENOENT || errno == EACCES)) | ||
| 146 | report_file_error ("Opening directory", dirname); | ||
| 147 | else | ||
| 148 | report_file_error ("Reading directory", dirname); | ||
| 149 | } | ||
| 140 | QUIT; | 150 | QUIT; |
| 141 | } | 151 | } |
| 142 | } | 152 | } |
| @@ -239,7 +249,8 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 239 | needsep = 1; | 249 | needsep = 1; |
| 240 | 250 | ||
| 241 | /* Loop reading directory entries. */ | 251 | /* Loop reading directory entries. */ |
| 242 | for (struct dirent *dp; (dp = read_dirent (d, directory)); ) | 252 | bool first_entry = true; |
| 253 | for (struct dirent *dp; (dp = read_dirent (d, directory, first_entry)); ) | ||
| 243 | { | 254 | { |
| 244 | ptrdiff_t len = dirent_namelen (dp); | 255 | ptrdiff_t len = dirent_namelen (dp); |
| 245 | Lisp_Object name = make_unibyte_string (dp->d_name, len); | 256 | Lisp_Object name = make_unibyte_string (dp->d_name, len); |
| @@ -247,6 +258,8 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 247 | struct gcpro gcpro1, gcpro2; | 258 | struct gcpro gcpro1, gcpro2; |
| 248 | GCPRO2 (finalname, name); | 259 | GCPRO2 (finalname, name); |
| 249 | 260 | ||
| 261 | first_entry = false; | ||
| 262 | |||
| 250 | /* Note: DECODE_FILE can GC; it should protect its argument, | 263 | /* Note: DECODE_FILE can GC; it should protect its argument, |
| 251 | though. */ | 264 | though. */ |
| 252 | name = DECODE_FILE (name); | 265 | name = DECODE_FILE (name); |
| @@ -486,11 +499,13 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, | |||
| 486 | record_unwind_protect_ptr (directory_files_internal_unwind, d); | 499 | record_unwind_protect_ptr (directory_files_internal_unwind, d); |
| 487 | 500 | ||
| 488 | /* Loop reading directory entries. */ | 501 | /* Loop reading directory entries. */ |
| 489 | for (struct dirent *dp; (dp = read_dirent (d, dirname)); ) | 502 | bool first_entry = true; |
| 503 | for (struct dirent *dp; (dp = read_dirent (d, dirname, first_entry)); ) | ||
| 490 | { | 504 | { |
| 491 | ptrdiff_t len = dirent_namelen (dp); | 505 | ptrdiff_t len = dirent_namelen (dp); |
| 492 | bool canexclude = 0; | 506 | bool canexclude = 0; |
| 493 | 507 | ||
| 508 | first_entry = false; | ||
| 494 | QUIT; | 509 | QUIT; |
| 495 | if (len < SCHARS (encoded_file) | 510 | if (len < SCHARS (encoded_file) |
| 496 | || (scmp (dp->d_name, SSDATA (encoded_file), | 511 | || (scmp (dp->d_name, SSDATA (encoded_file), |