changeset 32826:233d9eb5dff0

(directory_files_internal_unwind): New function. (directory_files_internal): Use it to ensure closedir is called even if expand-file-name or file-attributes throw, eg. because of a user interrupt. Also enable immediate_quit while calling re_search, so that matching can be interrupted as well.
author Andrew Innes <andrewi@gnu.org>
date Tue, 24 Oct 2000 14:45:19 +0000
parents 3e1d004030c5
children 130ac4062989
files src/dired.c
diffstat 1 files changed, 36 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/dired.c	Tue Oct 24 14:05:50 2000 +0000
+++ b/src/dired.c	Tue Oct 24 14:45:19 2000 +0000
@@ -118,6 +118,16 @@
 Lisp_Object Qfile_attributes;
 Lisp_Object Qfile_attributes_lessp;
 
+
+Lisp_Object
+directory_files_internal_unwind (dh)
+     Lisp_Object dh;
+{
+  DIR *d = (DIR *) ((XINT (XCAR (dh)) << 16) + XINT (XCDR (dh)));
+  closedir (d);
+  return Qnil;
+}
+
 /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.  
    When ATTRS is zero, return a list of directory filenames; when
    non-zero, return a list of directory filenames and their attributes.  */
@@ -133,6 +143,7 @@
   Lisp_Object handler;
   struct re_pattern_buffer *bufp = NULL;
   int needsep = 0;
+  int count = specpdl_ptr - specpdl;
   struct gcpro gcpro1, gcpro2;
 
   /* Because of file name handlers, these functions might call
@@ -176,6 +187,13 @@
   if (! d)
     report_file_error ("Opening directory", Fcons (directory, Qnil));
 
+  /* Unfortunately, we can now invoke expand-file-name and
+     file-attributes on filenames, both of which can throw, so we must
+     do a proper unwind-protect.  */
+  record_unwind_protect (directory_files_internal_unwind,
+			 Fcons (make_number (((unsigned long) d) >> 16),
+				make_number (((unsigned long) d) & 0xffff)));
+
   list = Qnil;
   dirnamelen = STRING_BYTES (XSTRING (directory));
   re_match_object = Qt;
@@ -198,14 +216,27 @@
       if (DIRENTRY_NONEMPTY (dp))
 	{
 	  int len;
+	  int wanted = 0;
 
 	  len = NAMLEN (dp);
 	  name = DECODE_FILE (make_string (dp->d_name, len));
 	  len = STRING_BYTES (XSTRING (name));
 
+	  /* Now that we have unwind_protect in place, we might as well
+             allow matching to be interrupted.  */
+	  immediate_quit = 1;
+	  QUIT;
+
 	  if (NILP (match)
 	      || (0 <= re_search (bufp, XSTRING (name)->data, len, 0, len, 0)))
 	    {
+	      wanted = 1;
+	    }
+
+	  immediate_quit = 0;
+
+	  if (wanted)
+	    {
 	      Lisp_Object finalname;
 
 	      finalname = name;
@@ -251,7 +282,12 @@
 	    }
 	}
     }
+
   closedir (d);
+
+  /* Discard the unwind protect.  */
+  specpdl_ptr = specpdl + count;
+
   UNGCPRO;
   if (!NILP (nosort))
     return list;