aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancesc Rocher2015-01-30 00:38:31 +0100
committerFrancesc Rocher2015-01-30 00:38:31 +0100
commit9242cdcda95e0fcb57233a8665d251e280eddec6 (patch)
tree1b2f987150280c74b215873b852c1da99ca1ad71
parentca9456fbf4bc35b2b9fb6da33b6eea8dafb5c34b (diff)
parent4ab6e74a1c76cd3a3c2e57aa48e853385365b423 (diff)
downloademacs-9242cdcda95e0fcb57233a8665d251e280eddec6.tar.gz
emacs-9242cdcda95e0fcb57233a8665d251e280eddec6.zip
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
-rw-r--r--src/ChangeLog10
-rw-r--r--src/dired.c84
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 @@
12015-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
12015-01-29 Eli Zaretskii <eliz@gnu.org> 112015-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
127static struct dirent *
128read_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),