diff options
| author | Andrew Innes | 2000-10-24 14:45:36 +0000 |
|---|---|---|
| committer | Andrew Innes | 2000-10-24 14:45:36 +0000 |
| commit | 2488aba5ed81e2f7cb006fbbfba94a87dccb65c3 (patch) | |
| tree | 46b4e5b12212345a0e35cebaf07f04c3156d3cd8 /src | |
| parent | 7ae2f10f738ad485fba621f4f2cb175e1c8d2794 (diff) | |
| download | emacs-2488aba5ed81e2f7cb006fbbfba94a87dccb65c3.tar.gz emacs-2488aba5ed81e2f7cb006fbbfba94a87dccb65c3.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/dired.c | 36 |
2 files changed, 44 insertions, 0 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 97995aca06b..0dc6d23e0ba 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2000-10-24 Andrew Innes <andrewi@gnu.org> | ||
| 2 | |||
| 3 | * dired.c (directory_files_internal_unwind): New function. | ||
| 4 | (directory_files_internal): Use it to ensure closedir is called | ||
| 5 | even if expand-file-name or file-attributes throw, eg. because of | ||
| 6 | a user interrupt. Also enable immediate_quit while calling | ||
| 7 | re_search, so that matching can be interrupted as well. | ||
| 8 | |||
| 1 | 2000-10-24 Gerd Moellmann <gerd@gnu.org> | 9 | 2000-10-24 Gerd Moellmann <gerd@gnu.org> |
| 2 | 10 | ||
| 3 | * window.c (size_window): Prevent setting window's width or | 11 | * window.c (size_window): Prevent setting window's width or |
diff --git a/src/dired.c b/src/dired.c index e0dce3ae46e..4c9383691a8 100644 --- a/src/dired.c +++ b/src/dired.c | |||
| @@ -118,6 +118,16 @@ Lisp_Object Qfile_name_all_completions; | |||
| 118 | Lisp_Object Qfile_attributes; | 118 | Lisp_Object Qfile_attributes; |
| 119 | Lisp_Object Qfile_attributes_lessp; | 119 | Lisp_Object Qfile_attributes_lessp; |
| 120 | 120 | ||
| 121 | |||
| 122 | Lisp_Object | ||
| 123 | directory_files_internal_unwind (dh) | ||
| 124 | Lisp_Object dh; | ||
| 125 | { | ||
| 126 | DIR *d = (DIR *) ((XINT (XCAR (dh)) << 16) + XINT (XCDR (dh))); | ||
| 127 | closedir (d); | ||
| 128 | return Qnil; | ||
| 129 | } | ||
| 130 | |||
| 121 | /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes. | 131 | /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes. |
| 122 | When ATTRS is zero, return a list of directory filenames; when | 132 | When ATTRS is zero, return a list of directory filenames; when |
| 123 | non-zero, return a list of directory filenames and their attributes. */ | 133 | non-zero, return a list of directory filenames and their attributes. */ |
| @@ -133,6 +143,7 @@ directory_files_internal (directory, full, match, nosort, attrs) | |||
| 133 | Lisp_Object handler; | 143 | Lisp_Object handler; |
| 134 | struct re_pattern_buffer *bufp = NULL; | 144 | struct re_pattern_buffer *bufp = NULL; |
| 135 | int needsep = 0; | 145 | int needsep = 0; |
| 146 | int count = specpdl_ptr - specpdl; | ||
| 136 | struct gcpro gcpro1, gcpro2; | 147 | struct gcpro gcpro1, gcpro2; |
| 137 | 148 | ||
| 138 | /* Because of file name handlers, these functions might call | 149 | /* Because of file name handlers, these functions might call |
| @@ -176,6 +187,13 @@ directory_files_internal (directory, full, match, nosort, attrs) | |||
| 176 | if (! d) | 187 | if (! d) |
| 177 | report_file_error ("Opening directory", Fcons (directory, Qnil)); | 188 | report_file_error ("Opening directory", Fcons (directory, Qnil)); |
| 178 | 189 | ||
| 190 | /* Unfortunately, we can now invoke expand-file-name and | ||
| 191 | file-attributes on filenames, both of which can throw, so we must | ||
| 192 | do a proper unwind-protect. */ | ||
| 193 | record_unwind_protect (directory_files_internal_unwind, | ||
| 194 | Fcons (make_number (((unsigned long) d) >> 16), | ||
| 195 | make_number (((unsigned long) d) & 0xffff))); | ||
| 196 | |||
| 179 | list = Qnil; | 197 | list = Qnil; |
| 180 | dirnamelen = STRING_BYTES (XSTRING (directory)); | 198 | dirnamelen = STRING_BYTES (XSTRING (directory)); |
| 181 | re_match_object = Qt; | 199 | re_match_object = Qt; |
| @@ -198,14 +216,27 @@ directory_files_internal (directory, full, match, nosort, attrs) | |||
| 198 | if (DIRENTRY_NONEMPTY (dp)) | 216 | if (DIRENTRY_NONEMPTY (dp)) |
| 199 | { | 217 | { |
| 200 | int len; | 218 | int len; |
| 219 | int wanted = 0; | ||
| 201 | 220 | ||
| 202 | len = NAMLEN (dp); | 221 | len = NAMLEN (dp); |
| 203 | name = DECODE_FILE (make_string (dp->d_name, len)); | 222 | name = DECODE_FILE (make_string (dp->d_name, len)); |
| 204 | len = STRING_BYTES (XSTRING (name)); | 223 | len = STRING_BYTES (XSTRING (name)); |
| 205 | 224 | ||
| 225 | /* Now that we have unwind_protect in place, we might as well | ||
| 226 | allow matching to be interrupted. */ | ||
| 227 | immediate_quit = 1; | ||
| 228 | QUIT; | ||
| 229 | |||
| 206 | if (NILP (match) | 230 | if (NILP (match) |
| 207 | || (0 <= re_search (bufp, XSTRING (name)->data, len, 0, len, 0))) | 231 | || (0 <= re_search (bufp, XSTRING (name)->data, len, 0, len, 0))) |
| 208 | { | 232 | { |
| 233 | wanted = 1; | ||
| 234 | } | ||
| 235 | |||
| 236 | immediate_quit = 0; | ||
| 237 | |||
| 238 | if (wanted) | ||
| 239 | { | ||
| 209 | Lisp_Object finalname; | 240 | Lisp_Object finalname; |
| 210 | 241 | ||
| 211 | finalname = name; | 242 | finalname = name; |
| @@ -251,7 +282,12 @@ directory_files_internal (directory, full, match, nosort, attrs) | |||
| 251 | } | 282 | } |
| 252 | } | 283 | } |
| 253 | } | 284 | } |
| 285 | |||
| 254 | closedir (d); | 286 | closedir (d); |
| 287 | |||
| 288 | /* Discard the unwind protect. */ | ||
| 289 | specpdl_ptr = specpdl + count; | ||
| 290 | |||
| 255 | UNGCPRO; | 291 | UNGCPRO; |
| 256 | if (!NILP (nosort)) | 292 | if (!NILP (nosort)) |
| 257 | return list; | 293 | return list; |