diff options
| author | Francesc Rocher | 2015-01-30 00:38:31 +0100 |
|---|---|---|
| committer | Francesc Rocher | 2015-01-30 00:38:31 +0100 |
| commit | 9242cdcda95e0fcb57233a8665d251e280eddec6 (patch) | |
| tree | 1b2f987150280c74b215873b852c1da99ca1ad71 /src | |
| parent | ca9456fbf4bc35b2b9fb6da33b6eea8dafb5c34b (diff) | |
| parent | 4ab6e74a1c76cd3a3c2e57aa48e853385365b423 (diff) | |
| download | emacs-9242cdcda95e0fcb57233a8665d251e280eddec6.tar.gz emacs-9242cdcda95e0fcb57233a8665d251e280eddec6.zip | |
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/dired.c | 84 |
2 files changed, 39 insertions, 55 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 96e6aa25d5e..029ac88a28f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2015-01-29 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Report readdir failures | ||
| 4 | Previously, on non-MS-Windows platforms the code treated most | ||
| 5 | readdir failures as EOF. This was incorrect, e.g., when readdir | ||
| 6 | fails with errno == EOVERFLOW. Signal an error instead. | ||
| 7 | * dired.c (read_dirent): | ||
| 8 | New function, which signals an error when readdir fails. | ||
| 9 | (directory_files_internal, file_name_completion): Use it. | ||
| 10 | |||
| 1 | 2015-01-29 Eli Zaretskii <eliz@gnu.org> | 11 | 2015-01-29 Eli Zaretskii <eliz@gnu.org> |
| 2 | 12 | ||
| 3 | * dired.c (directory_files_internal, file_name_completion) | 13 | * dired.c (directory_files_internal, file_name_completion) |
diff --git a/src/dired.c b/src/dired.c index f0e81b61278..23a867463f4 100644 --- a/src/dired.c +++ b/src/dired.c | |||
| @@ -120,6 +120,25 @@ directory_files_internal_unwind (void *dh) | |||
| 120 | unblock_input (); | 120 | unblock_input (); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | /* Return the next directory entry from DIR; DIR's name is DIRNAME. | ||
| 124 | If there are no more directory entries, return a null pointer. | ||
| 125 | Signal any unrecoverable errors. */ | ||
| 126 | |||
| 127 | static struct dirent * | ||
| 128 | read_dirent (DIR *dir, Lisp_Object dirname) | ||
| 129 | { | ||
| 130 | while (true) | ||
| 131 | { | ||
| 132 | errno = 0; | ||
| 133 | struct dirent *dp = readdir (dir); | ||
| 134 | if (dp || errno == 0) | ||
| 135 | return dp; | ||
| 136 | if (! (errno == EAGAIN || errno == EINTR)) | ||
| 137 | report_file_error ("Reading directory", dirname); | ||
| 138 | QUIT; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 123 | /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes. | 142 | /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes. |
| 124 | If not ATTRS, return a list of directory filenames; | 143 | If not ATTRS, return a list of directory filenames; |
| 125 | if ATTRS, return a list of directory filenames and their attributes. | 144 | if ATTRS, return a list of directory filenames and their attributes. |
| @@ -138,7 +157,6 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 138 | bool needsep = 0; | 157 | bool needsep = 0; |
| 139 | ptrdiff_t count = SPECPDL_INDEX (); | 158 | ptrdiff_t count = SPECPDL_INDEX (); |
| 140 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 159 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
| 141 | struct dirent *dp; | ||
| 142 | #ifdef WINDOWSNT | 160 | #ifdef WINDOWSNT |
| 143 | Lisp_Object w32_save = Qnil; | 161 | Lisp_Object w32_save = Qnil; |
| 144 | #endif | 162 | #endif |
| @@ -221,36 +239,13 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 221 | || !IS_ANY_SEP (SREF (directory, directory_nbytes - 1))) | 239 | || !IS_ANY_SEP (SREF (directory, directory_nbytes - 1))) |
| 222 | needsep = 1; | 240 | needsep = 1; |
| 223 | 241 | ||
| 224 | /* Loop reading blocks until EOF or error. */ | 242 | /* Loop reading directory entries. */ |
| 225 | for (;;) | 243 | for (struct dirent *dp; (dp = read_dirent (d, directory)); ) |
| 226 | { | 244 | { |
| 227 | ptrdiff_t len; | 245 | ptrdiff_t len = dirent_namelen (dp); |
| 228 | bool wanted = 0; | 246 | Lisp_Object name = make_unibyte_string (dp->d_name, len); |
| 229 | Lisp_Object name, finalname; | 247 | Lisp_Object finalname = name; |
| 230 | struct gcpro gcpro1, gcpro2; | 248 | struct gcpro gcpro1, gcpro2; |
| 231 | |||
| 232 | errno = 0; | ||
| 233 | dp = readdir (d); | ||
| 234 | if (!dp) | ||
| 235 | { | ||
| 236 | if (errno == EAGAIN || errno == EINTR) | ||
| 237 | { | ||
| 238 | QUIT; | ||
| 239 | continue; | ||
| 240 | } | ||
| 241 | #ifdef WINDOWSNT | ||
| 242 | /* The MS-Windows implementation of 'opendir' doesn't | ||
| 243 | actually open a directory until the first call to | ||
| 244 | 'readdir'. If 'readdir' fails to open the directory, it | ||
| 245 | sets errno to ENOENT or EACCES, see w32.c. */ | ||
| 246 | if (errno) | ||
| 247 | report_file_error ("Opening directory", directory); | ||
| 248 | #endif | ||
| 249 | break; | ||
| 250 | } | ||
| 251 | |||
| 252 | len = dirent_namelen (dp); | ||
| 253 | name = finalname = make_unibyte_string (dp->d_name, len); | ||
| 254 | GCPRO2 (finalname, name); | 249 | GCPRO2 (finalname, name); |
| 255 | 250 | ||
| 256 | /* Note: DECODE_FILE can GC; it should protect its argument, | 251 | /* Note: DECODE_FILE can GC; it should protect its argument, |
| @@ -263,9 +258,8 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 263 | immediate_quit = 1; | 258 | immediate_quit = 1; |
| 264 | QUIT; | 259 | QUIT; |
| 265 | 260 | ||
| 266 | if (NILP (match) | 261 | bool wanted = (NILP (match) |
| 267 | || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0) | 262 | || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0); |
| 268 | wanted = 1; | ||
| 269 | 263 | ||
| 270 | immediate_quit = 0; | 264 | immediate_quit = 0; |
| 271 | 265 | ||
| @@ -498,32 +492,12 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, | |||
| 498 | 492 | ||
| 499 | record_unwind_protect_ptr (directory_files_internal_unwind, d); | 493 | record_unwind_protect_ptr (directory_files_internal_unwind, d); |
| 500 | 494 | ||
| 501 | /* Loop reading blocks */ | 495 | /* Loop reading directory entries. */ |
| 502 | /* (att3b compiler bug requires do a null comparison this way) */ | 496 | for (struct dirent *dp; (dp = read_dirent (d, dirname)); ) |
| 503 | while (1) | ||
| 504 | { | 497 | { |
| 505 | struct dirent *dp; | 498 | ptrdiff_t len = dirent_namelen (dp); |
| 506 | ptrdiff_t len; | ||
| 507 | bool canexclude = 0; | 499 | bool canexclude = 0; |
| 508 | 500 | ||
| 509 | errno = 0; | ||
| 510 | dp = readdir (d); | ||
| 511 | if (!dp) | ||
| 512 | { | ||
| 513 | if (errno == EAGAIN || errno == EINTR) | ||
| 514 | { | ||
| 515 | QUIT; | ||
| 516 | continue; | ||
| 517 | } | ||
| 518 | #ifdef WINDOWSNT | ||
| 519 | if (errno) | ||
| 520 | report_file_error ("Opening directory", dirname); | ||
| 521 | #endif | ||
| 522 | break; | ||
| 523 | } | ||
| 524 | |||
| 525 | len = dirent_namelen (dp); | ||
| 526 | |||
| 527 | QUIT; | 501 | QUIT; |
| 528 | if (len < SCHARS (encoded_file) | 502 | if (len < SCHARS (encoded_file) |
| 529 | || (scmp (dp->d_name, SSDATA (encoded_file), | 503 | || (scmp (dp->d_name, SSDATA (encoded_file), |