aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2016-10-21 13:04:02 -0700
committerPaul Eggert2016-10-21 13:06:03 -0700
commit897998291fd09c3b9825a07045fa05f17bf83875 (patch)
tree03ab8a82b587c32e32d94744195dba07e5ce71ca
parent76b08a35bb6b3b32e5e5fda53e374769ceae6ed8 (diff)
downloademacs-897998291fd09c3b9825a07045fa05f17bf83875.tar.gz
emacs-897998291fd09c3b9825a07045fa05f17bf83875.zip
New error file-missing
This fixes a recently-introduced bug in delete-directory, where the code assumes the C locale when determining whether a file-error corresponds to a missing file (Bug#24714). * doc/lispref/errors.texi (Standard Errors): * doc/lispref/files.texi (Changing Files): * etc/NEWS: Document this. * doc/lispref/loading.texi (How Programs Do Loading): Say "a file-error" rather than "the error file-error" since it might be a file-missing now. * lisp/emacs-lisp/bytecomp.el (byte-compile-file): * lisp/epa-file.el (epa-file--find-file-not-found-function): (epa-file-insert-file-contents, epa-file-write-region): * lisp/ffap.el (find-file-at-point, dired-at-point): * lisp/jka-compr.el (jka-compr-insert-file-contents) (jka-compr-insert-file-contents): * lisp/net/ange-ftp.el (ange-ftp-barf-if-not-directory) (ange-ftp-insert-file-contents, ange-ftp-copy-file-internal): * lisp/progmodes/etags.el (visit-tags-table): * lisp/url/url-handlers.el (url-copy-file): * src/fileio.c (report_file_errno): Signal file-missing if appropriate. * lisp/epa-file.el (epa-file-insert-file-contents): * lisp/jka-compr.el (jka-compr-insert-file-contents): Don't assume file-error is a leaf in the error hierarchy. * lisp/files.el (files--force): * lisp/gnus/nnmaildir.el (nnmaildir--enoent-p): * lisp/jka-compr.el (jka-compr-insert-file-contents): Use file-missing to detect whether the file is missing. * lisp/url/url-handlers.el (url-copy-file): Signal file-already-exists if appropriate. * src/fileio.c (syms_of_fileio): Define file-missing. 2016-10-18 Paul Eggert <eggert@cs.ucla.edu>
-rw-r--r--doc/lispref/errors.texi5
-rw-r--r--doc/lispref/files.texi9
-rw-r--r--doc/lispref/loading.texi4
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/emacs-lisp/bytecomp.el13
-rw-r--r--lisp/epa-file.el8
-rw-r--r--lisp/ffap.el11
-rw-r--r--lisp/files.el4
-rw-r--r--lisp/gnus/nnmaildir.el3
-rw-r--r--lisp/jka-compr.el9
-rw-r--r--lisp/net/ange-ftp.el16
-rw-r--r--lisp/progmodes/etags.el6
-rw-r--r--lisp/url/url-handlers.el5
-rw-r--r--src/fileio.c9
14 files changed, 64 insertions, 43 deletions
diff --git a/doc/lispref/errors.texi b/doc/lispref/errors.texi
index 03aea4ef445..4a0e38c782f 100644
--- a/doc/lispref/errors.texi
+++ b/doc/lispref/errors.texi
@@ -107,6 +107,11 @@ the error-strings are not very relevant. However, these error symbols
107do have @code{error-message} properties, and if no data is provided, 107do have @code{error-message} properties, and if no data is provided,
108the @code{error-message} property @emph{is} used. @xref{Files}. 108the @code{error-message} property @emph{is} used. @xref{Files}.
109 109
110@item file-missing
111This is a subcategory of @code{file-error}. It occurs when an
112operation attempts to act on a file that is missing. @xref{Changing
113Files}.
114
110@c jka-compr.el 115@c jka-compr.el
111@item compression-error 116@item compression-error
112This is a subcategory of @code{file-error}, which results from 117This is a subcategory of @code{file-error}, which results from
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 62e0199f1ff..ecc3e03967c 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -1501,10 +1501,11 @@ in @code{exec-path}, and tries all the file-name extensions in
1501@cindex setting modes of files 1501@cindex setting modes of files
1502 1502
1503 The functions in this section rename, copy, delete, link, and set 1503 The functions in this section rename, copy, delete, link, and set
1504the modes (permissions) of files. They all signal a @code{file-error} 1504the modes (permissions) of files. Typically, they signal a
1505error if they fail to perform their function, reporting the 1505@code{file-error} error if they fail to perform their function,
1506system-dependent error message that describes the reason for the 1506reporting the system-dependent error message that describes the reason
1507failure. 1507for the failure. If they fail because a file is missing, they signal
1508a @code{file-missing} error instead.
1508 1509
1509 For performance, the operating system may cache or alias changes 1510 For performance, the operating system may cache or alias changes
1510made by these functions instead of writing them immediately to 1511made by these functions instead of writing them immediately to
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index 81a1922d71c..a73ae596e0d 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -161,8 +161,8 @@ load was done for the sake of @code{autoload}, any function definitions
161made during the loading are undone. 161made during the loading are undone.
162 162
163@kindex file-error 163@kindex file-error
164If @code{load} can't find the file to load, then normally it signals the 164If @code{load} can't find the file to load, then normally it signals a
165error @code{file-error} (with @samp{Cannot open load file 165@code{file-error} (with @samp{Cannot open load file
166@var{filename}}). But if @var{missing-ok} is non-@code{nil}, then 166@var{filename}}). But if @var{missing-ok} is non-@code{nil}, then
167@code{load} just returns @code{nil}. 167@code{load} just returns @code{nil}.
168 168
diff --git a/etc/NEWS b/etc/NEWS
index 4e41dbb39a8..d9973c0fd48 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -625,6 +625,11 @@ collection).
625can be used for creation of temporary files of remote or mounted directories. 625can be used for creation of temporary files of remote or mounted directories.
626 626
627+++ 627+++
628** The new error 'file-missing', a subcategory of 'file-error', is now
629signaled instead of 'file-error' if a file operation acts on a file
630that does not exist.
631
632+++
628** The function 'delete-directory' no longer signals an error when 633** The function 'delete-directory' no longer signals an error when
629operating recursively and when some other process deletes the directory 634operating recursively and when some other process deletes the directory
630or its files before 'delete-directory' gets to them. 635or its files before 'delete-directory' gets to them.
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index c34ec5cae0d..428e21c7a39 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -1892,12 +1892,13 @@ The value is non-nil if there were no errors, nil if errors."
1892 (rename-file tempfile target-file t) 1892 (rename-file tempfile target-file t)
1893 (or noninteractive (message "Wrote %s" target-file))) 1893 (or noninteractive (message "Wrote %s" target-file)))
1894 ;; This is just to give a better error message than write-region 1894 ;; This is just to give a better error message than write-region
1895 (signal 'file-error 1895 (let ((exists (file-exists-p target-file)))
1896 (list "Opening output file" 1896 (signal (if exists 'file-error 'file-missing)
1897 (if (file-exists-p target-file) 1897 (list "Opening output file"
1898 "Cannot overwrite file" 1898 (if exists
1899 "Directory not writable or nonexistent") 1899 "Cannot overwrite file"
1900 target-file))) 1900 "Directory not writable or nonexistent")
1901 target-file))))
1901 (kill-buffer (current-buffer))) 1902 (kill-buffer (current-buffer)))
1902 (if (and byte-compile-generate-call-tree 1903 (if (and byte-compile-generate-call-tree
1903 (or (eq t byte-compile-generate-call-tree) 1904 (or (eq t byte-compile-generate-call-tree)
diff --git a/lisp/epa-file.el b/lisp/epa-file.el
index ee502ef64a3..2303a085909 100644
--- a/lisp/epa-file.el
+++ b/lisp/epa-file.el
@@ -120,7 +120,7 @@ encryption is used."
120 (let ((error epa-file-error)) 120 (let ((error epa-file-error))
121 (save-window-excursion 121 (save-window-excursion
122 (kill-buffer)) 122 (kill-buffer))
123 (signal 'file-error 123 (signal (car error)
124 (cons "Opening input file" (cdr error))))) 124 (cons "Opening input file" (cdr error)))))
125 125
126(defvar last-coding-system-used) 126(defvar last-coding-system-used)
@@ -161,7 +161,7 @@ encryption is used."
161 ;; signal that as a non-file error 161 ;; signal that as a non-file error
162 ;; so that find-file-noselect-1 won't handle it. 162 ;; so that find-file-noselect-1 won't handle it.
163 ;; Borrowed from jka-compr.el. 163 ;; Borrowed from jka-compr.el.
164 (if (and (eq (car error) 'file-error) 164 (if (and (memq 'file-error (get (car error) 'error-conditions))
165 (equal (cadr error) "Searching for program")) 165 (equal (cadr error) "Searching for program"))
166 (error "Decryption program `%s' not found" 166 (error "Decryption program `%s' not found"
167 (nth 3 error))) 167 (nth 3 error)))
@@ -175,7 +175,7 @@ encryption is used."
175 'epa-file--find-file-not-found-function 175 'epa-file--find-file-not-found-function
176 nil t) 176 nil t)
177 (epa-display-error context)) 177 (epa-display-error context))
178 (signal 'file-error 178 (signal (car error)
179 (cons "Opening input file" (cdr error))))) 179 (cons "Opening input file" (cdr error)))))
180 (set-buffer buf) ;In case timer/filter changed/killed it (bug#16029)! 180 (set-buffer buf) ;In case timer/filter changed/killed it (bug#16029)!
181 (setq-local epa-file-encrypt-to 181 (setq-local epa-file-encrypt-to
@@ -272,7 +272,7 @@ If no one is selected, symmetric encryption will be performed. "
272 (epa-display-error context) 272 (epa-display-error context)
273 (if (setq entry (assoc file epa-file-passphrase-alist)) 273 (if (setq entry (assoc file epa-file-passphrase-alist))
274 (setcdr entry nil)) 274 (setcdr entry nil))
275 (signal 'file-error (cons "Opening output file" (cdr error))))) 275 (signal (car error) (cons "Opening output file" (cdr error)))))
276 (epa-file-run-real-handler 276 (epa-file-run-real-handler
277 #'write-region 277 #'write-region
278 (list string nil file append visit lockname mustbenew)) 278 (list string nil file append visit lockname mustbenew))
diff --git a/lisp/ffap.el b/lisp/ffap.el
index 7013e6e8ba4..3d7cebadcf6 100644
--- a/lisp/ffap.el
+++ b/lisp/ffap.el
@@ -1510,9 +1510,9 @@ and the functions `ffap-file-at-point' and `ffap-url-at-point'."
1510 ;; expand-file-name fixes "~/~/.emacs" bug sent by CHUCKR. 1510 ;; expand-file-name fixes "~/~/.emacs" bug sent by CHUCKR.
1511 (expand-file-name filename))) 1511 (expand-file-name filename)))
1512 ;; User does not want to find a non-existent file: 1512 ;; User does not want to find a non-existent file:
1513 ((signal 'file-error (list "Opening file buffer" 1513 ((signal 'file-missing (list "Opening file buffer"
1514 "No such file or directory" 1514 "No such file or directory"
1515 filename))))))) 1515 filename)))))))
1516 1516
1517;; Shortcut: allow {M-x ffap} rather than {M-x find-file-at-point}. 1517;; Shortcut: allow {M-x ffap} rather than {M-x find-file-at-point}.
1518;;;###autoload 1518;;;###autoload
@@ -1888,7 +1888,10 @@ If `dired-at-point-require-prefix' is set, the prefix meaning is reversed."
1888 (y-or-n-p "Directory does not exist, create it? ")) 1888 (y-or-n-p "Directory does not exist, create it? "))
1889 (make-directory filename) 1889 (make-directory filename)
1890 (funcall ffap-directory-finder filename)) 1890 (funcall ffap-directory-finder filename))
1891 ((error "No such file or directory `%s'" filename)))))) 1891 (t
1892 (signal 'file-missing (list "Opening directory"
1893 "No such file or directory"
1894 filename)))))))
1892 1895
1893(defun dired-at-point-prompter (&optional guess) 1896(defun dired-at-point-prompter (&optional guess)
1894 ;; Does guess and prompt step for find-file-at-point. 1897 ;; Does guess and prompt step for find-file-at-point.
diff --git a/lisp/files.el b/lisp/files.el
index 12c6c14d534..8277877dee0 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5342,9 +5342,7 @@ This acts like (apply FN ARGS) except it returns NO-SUCH if it is
5342non-nil and if FN fails due to a missing file or directory." 5342non-nil and if FN fails due to a missing file or directory."
5343 (condition-case err 5343 (condition-case err
5344 (apply fn args) 5344 (apply fn args)
5345 (file-error 5345 (file-missing (or no-such (signal (car err) (cdr err))))))
5346 (or (pcase err (`(,_ ,_ "No such file or directory" . ,_) no-such))
5347 (signal (car err) (cdr err))))))
5348 5346
5349(defun delete-directory (directory &optional recursive trash) 5347(defun delete-directory (directory &optional recursive trash)
5350 "Delete the directory named DIRECTORY. Does not follow symlinks. 5348 "Delete the directory named DIRECTORY. Does not follow symlinks.
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el
index 21c83751e70..03cb445675c 100644
--- a/lisp/gnus/nnmaildir.el
+++ b/lisp/gnus/nnmaildir.el
@@ -371,8 +371,7 @@ This variable is set by `nnmaildir-request-article'.")
371 (string= (downcase (caddr err)) "too many links"))) 371 (string= (downcase (caddr err)) "too many links")))
372 372
373(defun nnmaildir--enoent-p (err) 373(defun nnmaildir--enoent-p (err)
374 (and (eq (car err) 'file-error) 374 (eq (car err) 'file-missing))
375 (string= (downcase (caddr err)) "no such file or directory")))
376 375
377(defun nnmaildir--eexist-p (err) 376(defun nnmaildir--eexist-p (err)
378 (eq (car err) 'file-already-exists)) 377 (eq (car err) 'file-already-exists))
diff --git a/lisp/jka-compr.el b/lisp/jka-compr.el
index a5556743eb3..d8137b10528 100644
--- a/lisp/jka-compr.el
+++ b/lisp/jka-compr.el
@@ -444,17 +444,18 @@ There should be no more than seven characters after the final `/'."
444 ;; If the file we wanted to uncompress does not exist, 444 ;; If the file we wanted to uncompress does not exist,
445 ;; handle that according to VISIT as `insert-file-contents' 445 ;; handle that according to VISIT as `insert-file-contents'
446 ;; would, maybe signaling the same error it normally would. 446 ;; would, maybe signaling the same error it normally would.
447 (if (and (eq (car error-code) 'file-error) 447 (if (and (eq (car error-code) 'file-missing)
448 (eq (nth 3 error-code) local-file)) 448 (eq (nth 3 error-code) local-file))
449 (if visit 449 (if visit
450 (setq notfound error-code) 450 (setq notfound error-code)
451 (signal 'file-error 451 (signal 'file-missing
452 (cons "Opening input file" 452 (cons "Opening input file"
453 (nthcdr 2 error-code)))) 453 (nthcdr 2 error-code))))
454 ;; If the uncompression program can't be found, 454 ;; If the uncompression program can't be found,
455 ;; signal that as a non-file error 455 ;; signal that as a non-file error
456 ;; so that find-file-noselect-1 won't handle it. 456 ;; so that find-file-noselect-1 won't handle it.
457 (if (and (eq (car error-code) 'file-error) 457 (if (and (memq 'file-error (get (car error-code)
458 'error-conditions))
458 (equal (cadr error-code) "Searching for program")) 459 (equal (cadr error-code) "Searching for program"))
459 (error "Uncompression program `%s' not found" 460 (error "Uncompression program `%s' not found"
460 (nth 3 error-code))) 461 (nth 3 error-code)))
@@ -487,7 +488,7 @@ There should be no more than seven characters after the final `/'."
487 (and 488 (and
488 visit 489 visit
489 notfound 490 notfound
490 (signal 'file-error 491 (signal 'file-missing
491 (cons "Opening input file" (nth 2 notfound)))) 492 (cons "Opening input file" (nth 2 notfound))))
492 493
493 ;; This is done in insert-file-contents after we return. 494 ;; This is done in insert-file-contents after we return.
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index d5c03e3f4ae..9ff9997e728 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -1533,12 +1533,11 @@ then kill the related FTP process."
1533 1533
1534(defun ange-ftp-barf-if-not-directory (directory) 1534(defun ange-ftp-barf-if-not-directory (directory)
1535 (or (file-directory-p directory) 1535 (or (file-directory-p directory)
1536 (signal 'file-error 1536 (let ((exists (file-exists-p directory)))
1537 (list "Opening directory" 1537 (signal (if exists 'file-error 'file-missing)
1538 (if (file-exists-p directory) 1538 (list "Opening directory"
1539 "Not a directory" 1539 (if exists "Not a directory" "No such file or directory")
1540 "No such file or directory") 1540 directory)))))
1541 directory))))
1542 1541
1543;;;; ------------------------------------------------------------ 1542;;;; ------------------------------------------------------------
1544;;;; FTP process filter support. 1543;;;; FTP process filter support.
@@ -3352,9 +3351,10 @@ system TYPE.")
3352 (setq buffer-file-name filename))) 3351 (setq buffer-file-name filename)))
3353 (setq last-coding-system-used coding-system-used) 3352 (setq last-coding-system-used coding-system-used)
3354 (list filename size)) 3353 (list filename size))
3355 (signal 'file-error 3354 (signal 'file-missing
3356 (list 3355 (list
3357 "Opening input file" 3356 "Opening input file"
3357 "No such file or directory"
3358 filename)))) 3358 filename))))
3359 (ange-ftp-real-insert-file-contents filename visit beg end replace)))) 3359 (ange-ftp-real-insert-file-contents filename visit beg end replace))))
3360 3360
@@ -3663,7 +3663,7 @@ so return the size on the remote host exactly. See RFC 3659."
3663 newname (expand-file-name newname)) 3663 newname (expand-file-name newname))
3664 3664
3665 (or (file-exists-p filename) 3665 (or (file-exists-p filename)
3666 (signal 'file-error 3666 (signal 'file-missing
3667 (list "Copy file" "No such file or directory" filename))) 3667 (list "Copy file" "No such file or directory" filename)))
3668 3668
3669 ;; canonicalize newname if a directory. 3669 ;; canonicalize newname if a directory.
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index d37ab8a9817..7d4521c148d 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -307,9 +307,9 @@ file the tag was in."
307 (let ((tags-file-name file)) 307 (let ((tags-file-name file))
308 (save-excursion 308 (save-excursion
309 (or (visit-tags-table-buffer file) 309 (or (visit-tags-table-buffer file)
310 (signal 'file-error (list "Visiting tags table" 310 (signal 'file-missing (list "Visiting tags table"
311 "No such file or directory" 311 "No such file or directory"
312 file))) 312 file)))
313 ;; Set FILE to the expanded name. 313 ;; Set FILE to the expanded name.
314 (setq file tags-file-name))) 314 (setq file tags-file-name)))
315 (if local 315 (if local
diff --git a/lisp/url/url-handlers.el b/lisp/url/url-handlers.el
index d3be880b382..0fada8d49d7 100644
--- a/lisp/url/url-handlers.el
+++ b/lisp/url/url-handlers.el
@@ -262,11 +262,12 @@ Fifth arg PRESERVE-UID-GID is ignored.
262A prefix arg makes KEEP-TIME non-nil." 262A prefix arg makes KEEP-TIME non-nil."
263 (if (and (file-exists-p newname) 263 (if (and (file-exists-p newname)
264 (not ok-if-already-exists)) 264 (not ok-if-already-exists))
265 (error "Opening output file: File already exists, %s" newname)) 265 (signal 'file-already-exists (list "File exists" newname)))
266 (let ((buffer (url-retrieve-synchronously url)) 266 (let ((buffer (url-retrieve-synchronously url))
267 (handle nil)) 267 (handle nil))
268 (if (not buffer) 268 (if (not buffer)
269 (error "Opening input file: No such file or directory, %s" url)) 269 (signal 'file-missing (list "Opening URL" "No such file or directory"
270 url)))
270 (with-current-buffer buffer 271 (with-current-buffer buffer
271 (setq handle (mm-dissect-buffer t))) 272 (setq handle (mm-dissect-buffer t)))
272 (let ((mm-attachment-file-modes (default-file-modes))) 273 (let ((mm-attachment-file-modes (default-file-modes)))
diff --git a/src/fileio.c b/src/fileio.c
index 6026d8ebad4..ea6e4aef9be 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -203,7 +203,8 @@ report_file_errno (char const *string, Lisp_Object name, int errorno)
203 if (errorno == EEXIST) 203 if (errorno == EEXIST)
204 xsignal (Qfile_already_exists, errdata); 204 xsignal (Qfile_already_exists, errdata);
205 else 205 else
206 xsignal (Qfile_error, Fcons (build_string (string), errdata)); 206 xsignal (errorno == ENOENT ? Qfile_missing : Qfile_error,
207 Fcons (build_string (string), errdata));
207} 208}
208 209
209/* Signal a file-access failure that set errno. STRING describes the 210/* Signal a file-access failure that set errno. STRING describes the
@@ -5874,6 +5875,7 @@ syms_of_fileio (void)
5874 DEFSYM (Qfile_error, "file-error"); 5875 DEFSYM (Qfile_error, "file-error");
5875 DEFSYM (Qfile_already_exists, "file-already-exists"); 5876 DEFSYM (Qfile_already_exists, "file-already-exists");
5876 DEFSYM (Qfile_date_error, "file-date-error"); 5877 DEFSYM (Qfile_date_error, "file-date-error");
5878 DEFSYM (Qfile_missing, "file-missing");
5877 DEFSYM (Qfile_notify_error, "file-notify-error"); 5879 DEFSYM (Qfile_notify_error, "file-notify-error");
5878 DEFSYM (Qexcl, "excl"); 5880 DEFSYM (Qexcl, "excl");
5879 5881
@@ -5926,6 +5928,11 @@ behaves as if file names were encoded in `utf-8'. */);
5926 Fput (Qfile_date_error, Qerror_message, 5928 Fput (Qfile_date_error, Qerror_message,
5927 build_pure_c_string ("Cannot set file date")); 5929 build_pure_c_string ("Cannot set file date"));
5928 5930
5931 Fput (Qfile_missing, Qerror_conditions,
5932 Fpurecopy (list3 (Qfile_missing, Qfile_error, Qerror)));
5933 Fput (Qfile_missing, Qerror_message,
5934 build_pure_c_string ("File is missing"));
5935
5929 Fput (Qfile_notify_error, Qerror_conditions, 5936 Fput (Qfile_notify_error, Qerror_conditions,
5930 Fpurecopy (list3 (Qfile_notify_error, Qfile_error, Qerror))); 5937 Fpurecopy (list3 (Qfile_notify_error, Qfile_error, Qerror)));
5931 Fput (Qfile_notify_error, Qerror_message, 5938 Fput (Qfile_notify_error, Qerror_message,