summaryrefslogtreecommitdiff
path: root/src/lread.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2019-09-17 19:18:14 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2019-09-17 19:24:38 -0700
commit9dc306b1db08196684d05a474148e16305adbad0 (patch)
tree78a401e0156a34ef1d2ae99acad31fb3ad9cb806 /src/lread.c
parentae3edf0ac3f1e893338917497b55859d6aca7d42 (diff)
downloademacs-9dc306b1db08196684d05a474148e16305adbad0.tar.gz
emacs-9dc306b1db08196684d05a474148e16305adbad0.tar.bz2
emacs-9dc306b1db08196684d05a474148e16305adbad0.zip
Improve reporting of I/O, access errors
Signal an error for file-oriented errors that are not tame errors like ENOENT and ENOTDIR (Bug#37389). Do this for primitives exposed to Lisp; the lower level internal C API merely makes errno values available to higher-level C code. * doc/lispref/files.texi (Testing Accessibility) (File Attributes, Extended Attributes): Do not say that the functions return nil when the return value cannot be determined. * etc/NEWS: Mention the change. * src/dired.c (Ffile_attributes): Fix doc string confusion about opening a file vs getting its attributes. (file_attributes): Signal serious errors. * src/fileio.c (check_existing, check_executable) (check_writable): Remove. All callers changed to use check_file_access or file_access_p. (file_access_p, file_metadata_errno, file_attribute_errno) (file_test_errno, check_file_access, check_emacs_readlinkat): New functions. * src/fileio.c (Ffile_executable_p, Ffile_readable_p) (Ffile_name_case_insensitive_p, Frename_file, Ffile_exists_p): (Ffile_symlink_p, Ffile_directory_p) (Ffile_accessible_directory_p, Ffile_regular_p) (Ffile_selinux_context, Ffile_acl, Ffile_modes) (Ffile_newer_than_file_p, Fset_visited_file_modtime) (Ffile_system_info): * src/filelock.c (unlock_file, Ffile_locked_p): * src/lread.c (Fload): Signal serious errors. * src/fileio.c (Ffile_writable_p): Remove unnecessary CHECK_STRING. (emacs_readlinkat): Now static. * src/filelock.c (current_lock_owner, lock_if_free): Return a positive errno on error, and the negative of the old old value on success. All callers changed. * src/lread.c (openp): Propagate serious errno values to caller.
Diffstat (limited to 'src/lread.c')
-rw-r--r--src/lread.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/lread.c b/src/lread.c
index 6ae7a0d8ba0..d8883db46c1 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1346,15 +1346,22 @@ Return t if the file exists and loads successfully. */)
if (!load_prefer_newer && is_elc)
{
result = stat (SSDATA (efound), &s1);
+ int err = errno;
if (result == 0)
{
SSET (efound, SBYTES (efound) - 1, 0);
result = stat (SSDATA (efound), &s2);
+ err = errno;
SSET (efound, SBYTES (efound) - 1, 'c');
+ if (result != 0)
+ found = Fsubstring (found, make_fixnum (0),
+ make_fixnum (-1));
}
-
- if (result == 0
- && timespec_cmp (get_stat_mtime (&s1), get_stat_mtime (&s2)) < 0)
+ if (result != 0)
+ file_attribute_errno (found, err);
+ else if (timespec_cmp (get_stat_mtime (&s1),
+ get_stat_mtime (&s2))
+ < 0)
{
/* Make the progress messages mention that source is newer. */
newer = 1;
@@ -1748,16 +1755,20 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
{
if (file_directory_p (encoded_fn))
last_errno = EISDIR;
- else
+ else if (errno == ENOENT || errno == ENOTDIR)
fd = 1;
+ else
+ last_errno = errno;
}
+ else if (! (errno == ENOENT || errno == ENOTDIR))
+ last_errno = errno;
}
else
{
fd = emacs_open (pfn, O_RDONLY, 0);
if (fd < 0)
{
- if (errno != ENOENT)
+ if (! (errno == ENOENT || errno == ENOTDIR))
last_errno = errno;
}
else