diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2016-10-21 13:04:02 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2016-10-21 13:06:03 -0700 |
commit | 897998291fd09c3b9825a07045fa05f17bf83875 (patch) | |
tree | 03ab8a82b587c32e32d94744195dba07e5ce71ca | |
parent | 76b08a35bb6b3b32e5e5fda53e374769ceae6ed8 (diff) | |
download | emacs-897998291fd09c3b9825a07045fa05f17bf83875.tar.gz emacs-897998291fd09c3b9825a07045fa05f17bf83875.tar.bz2 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.texi | 5 | ||||
-rw-r--r-- | doc/lispref/files.texi | 9 | ||||
-rw-r--r-- | doc/lispref/loading.texi | 4 | ||||
-rw-r--r-- | etc/NEWS | 5 | ||||
-rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 13 | ||||
-rw-r--r-- | lisp/epa-file.el | 8 | ||||
-rw-r--r-- | lisp/ffap.el | 11 | ||||
-rw-r--r-- | lisp/files.el | 4 | ||||
-rw-r--r-- | lisp/gnus/nnmaildir.el | 3 | ||||
-rw-r--r-- | lisp/jka-compr.el | 9 | ||||
-rw-r--r-- | lisp/net/ange-ftp.el | 16 | ||||
-rw-r--r-- | lisp/progmodes/etags.el | 6 | ||||
-rw-r--r-- | lisp/url/url-handlers.el | 5 | ||||
-rw-r--r-- | src/fileio.c | 9 |
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 do have @code{error-message} properties, and if no data is provided, the @code{error-message} property @emph{is} used. @xref{Files}. +@item file-missing +This is a subcategory of @code{file-error}. It occurs when an +operation attempts to act on a file that is missing. @xref{Changing +Files}. + @c jka-compr.el @item compression-error This 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 @cindex setting modes of files The functions in this section rename, copy, delete, link, and set -the modes (permissions) of files. They all signal a @code{file-error} -error if they fail to perform their function, reporting the -system-dependent error message that describes the reason for the -failure. +the modes (permissions) of files. Typically, they signal a +@code{file-error} error if they fail to perform their function, +reporting the system-dependent error message that describes the reason +for the failure. If they fail because a file is missing, they signal +a @code{file-missing} error instead. For performance, the operating system may cache or alias changes made 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 made during the loading are undone. @kindex file-error -If @code{load} can't find the file to load, then normally it signals the -error @code{file-error} (with @samp{Cannot open load file +If @code{load} can't find the file to load, then normally it signals a +@code{file-error} (with @samp{Cannot open load file @var{filename}}). But if @var{missing-ok} is non-@code{nil}, then @code{load} just returns @code{nil}. @@ -625,6 +625,11 @@ collection). can be used for creation of temporary files of remote or mounted directories. +++ +** The new error 'file-missing', a subcategory of 'file-error', is now +signaled instead of 'file-error' if a file operation acts on a file +that does not exist. + ++++ ** The function 'delete-directory' no longer signals an error when operating recursively and when some other process deletes the directory or 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." (rename-file tempfile target-file t) (or noninteractive (message "Wrote %s" target-file))) ;; This is just to give a better error message than write-region - (signal 'file-error - (list "Opening output file" - (if (file-exists-p target-file) - "Cannot overwrite file" - "Directory not writable or nonexistent") - target-file))) + (let ((exists (file-exists-p target-file))) + (signal (if exists 'file-error 'file-missing) + (list "Opening output file" + (if exists + "Cannot overwrite file" + "Directory not writable or nonexistent") + target-file)))) (kill-buffer (current-buffer))) (if (and byte-compile-generate-call-tree (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." (let ((error epa-file-error)) (save-window-excursion (kill-buffer)) - (signal 'file-error + (signal (car error) (cons "Opening input file" (cdr error))))) (defvar last-coding-system-used) @@ -161,7 +161,7 @@ encryption is used." ;; signal that as a non-file error ;; so that find-file-noselect-1 won't handle it. ;; Borrowed from jka-compr.el. - (if (and (eq (car error) 'file-error) + (if (and (memq 'file-error (get (car error) 'error-conditions)) (equal (cadr error) "Searching for program")) (error "Decryption program `%s' not found" (nth 3 error))) @@ -175,7 +175,7 @@ encryption is used." 'epa-file--find-file-not-found-function nil t) (epa-display-error context)) - (signal 'file-error + (signal (car error) (cons "Opening input file" (cdr error))))) (set-buffer buf) ;In case timer/filter changed/killed it (bug#16029)! (setq-local epa-file-encrypt-to @@ -272,7 +272,7 @@ If no one is selected, symmetric encryption will be performed. " (epa-display-error context) (if (setq entry (assoc file epa-file-passphrase-alist)) (setcdr entry nil)) - (signal 'file-error (cons "Opening output file" (cdr error))))) + (signal (car error) (cons "Opening output file" (cdr error))))) (epa-file-run-real-handler #'write-region (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'." ;; expand-file-name fixes "~/~/.emacs" bug sent by CHUCKR. (expand-file-name filename))) ;; User does not want to find a non-existent file: - ((signal 'file-error (list "Opening file buffer" - "No such file or directory" - filename))))))) + ((signal 'file-missing (list "Opening file buffer" + "No such file or directory" + filename))))))) ;; Shortcut: allow {M-x ffap} rather than {M-x find-file-at-point}. ;;;###autoload @@ -1888,7 +1888,10 @@ If `dired-at-point-require-prefix' is set, the prefix meaning is reversed." (y-or-n-p "Directory does not exist, create it? ")) (make-directory filename) (funcall ffap-directory-finder filename)) - ((error "No such file or directory `%s'" filename)))))) + (t + (signal 'file-missing (list "Opening directory" + "No such file or directory" + filename))))))) (defun dired-at-point-prompter (&optional guess) ;; 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 non-nil and if FN fails due to a missing file or directory." (condition-case err (apply fn args) - (file-error - (or (pcase err (`(,_ ,_ "No such file or directory" . ,_) no-such)) - (signal (car err) (cdr err)))))) + (file-missing (or no-such (signal (car err) (cdr err)))))) (defun delete-directory (directory &optional recursive trash) "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'.") (string= (downcase (caddr err)) "too many links"))) (defun nnmaildir--enoent-p (err) - (and (eq (car err) 'file-error) - (string= (downcase (caddr err)) "no such file or directory"))) + (eq (car err) 'file-missing)) (defun nnmaildir--eexist-p (err) (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 `/'." ;; If the file we wanted to uncompress does not exist, ;; handle that according to VISIT as `insert-file-contents' ;; would, maybe signaling the same error it normally would. - (if (and (eq (car error-code) 'file-error) + (if (and (eq (car error-code) 'file-missing) (eq (nth 3 error-code) local-file)) (if visit (setq notfound error-code) - (signal 'file-error + (signal 'file-missing (cons "Opening input file" (nthcdr 2 error-code)))) ;; If the uncompression program can't be found, ;; signal that as a non-file error ;; so that find-file-noselect-1 won't handle it. - (if (and (eq (car error-code) 'file-error) + (if (and (memq 'file-error (get (car error-code) + 'error-conditions)) (equal (cadr error-code) "Searching for program")) (error "Uncompression program `%s' not found" (nth 3 error-code))) @@ -487,7 +488,7 @@ There should be no more than seven characters after the final `/'." (and visit notfound - (signal 'file-error + (signal 'file-missing (cons "Opening input file" (nth 2 notfound)))) ;; 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." (defun ange-ftp-barf-if-not-directory (directory) (or (file-directory-p directory) - (signal 'file-error - (list "Opening directory" - (if (file-exists-p directory) - "Not a directory" - "No such file or directory") - directory)))) + (let ((exists (file-exists-p directory))) + (signal (if exists 'file-error 'file-missing) + (list "Opening directory" + (if exists "Not a directory" "No such file or directory") + directory))))) ;;;; ------------------------------------------------------------ ;;;; FTP process filter support. @@ -3352,9 +3351,10 @@ system TYPE.") (setq buffer-file-name filename))) (setq last-coding-system-used coding-system-used) (list filename size)) - (signal 'file-error + (signal 'file-missing (list "Opening input file" + "No such file or directory" filename)))) (ange-ftp-real-insert-file-contents filename visit beg end replace)))) @@ -3663,7 +3663,7 @@ so return the size on the remote host exactly. See RFC 3659." newname (expand-file-name newname)) (or (file-exists-p filename) - (signal 'file-error + (signal 'file-missing (list "Copy file" "No such file or directory" filename))) ;; 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." (let ((tags-file-name file)) (save-excursion (or (visit-tags-table-buffer file) - (signal 'file-error (list "Visiting tags table" - "No such file or directory" - file))) + (signal 'file-missing (list "Visiting tags table" + "No such file or directory" + file))) ;; Set FILE to the expanded name. (setq file tags-file-name))) (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. A prefix arg makes KEEP-TIME non-nil." (if (and (file-exists-p newname) (not ok-if-already-exists)) - (error "Opening output file: File already exists, %s" newname)) + (signal 'file-already-exists (list "File exists" newname))) (let ((buffer (url-retrieve-synchronously url)) (handle nil)) (if (not buffer) - (error "Opening input file: No such file or directory, %s" url)) + (signal 'file-missing (list "Opening URL" "No such file or directory" + url))) (with-current-buffer buffer (setq handle (mm-dissect-buffer t))) (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) if (errorno == EEXIST) xsignal (Qfile_already_exists, errdata); else - xsignal (Qfile_error, Fcons (build_string (string), errdata)); + xsignal (errorno == ENOENT ? Qfile_missing : Qfile_error, + Fcons (build_string (string), errdata)); } /* Signal a file-access failure that set errno. STRING describes the @@ -5874,6 +5875,7 @@ syms_of_fileio (void) DEFSYM (Qfile_error, "file-error"); DEFSYM (Qfile_already_exists, "file-already-exists"); DEFSYM (Qfile_date_error, "file-date-error"); + DEFSYM (Qfile_missing, "file-missing"); DEFSYM (Qfile_notify_error, "file-notify-error"); DEFSYM (Qexcl, "excl"); @@ -5926,6 +5928,11 @@ behaves as if file names were encoded in `utf-8'. */); Fput (Qfile_date_error, Qerror_message, build_pure_c_string ("Cannot set file date")); + Fput (Qfile_missing, Qerror_conditions, + Fpurecopy (list3 (Qfile_missing, Qfile_error, Qerror))); + Fput (Qfile_missing, Qerror_message, + build_pure_c_string ("File is missing")); + Fput (Qfile_notify_error, Qerror_conditions, Fpurecopy (list3 (Qfile_notify_error, Qfile_error, Qerror))); Fput (Qfile_notify_error, Qerror_message, |