diff options
| author | Paul Eggert | 2019-09-21 11:27:46 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-09-21 11:38:36 -0700 |
| commit | d49d6ea9677eea1d30aae4244934b1c7336e35a3 (patch) | |
| tree | c671f33693f458a7ba992a2a97250f620aec861d | |
| parent | 56213b15e65a350f3f8cd9426a97691d8ff217ee (diff) | |
| download | emacs-d49d6ea9677eea1d30aae4244934b1c7336e35a3.tar.gz emacs-d49d6ea9677eea1d30aae4244934b1c7336e35a3.zip | |
Revert too-picky file-access tests
Problem reported by Andreas Schwab (Bug#37475).
* doc/lispref/files.texi (Writing to Files)
(Testing Accessibility, Kinds of Files):
Document that accessibility and file-type predicates return nil
if there is trouble determining accessibility or type.
* etc/NEWS: Adjust, and list the affected primitives.
* src/callproc.c (init_callproc): Go back to Ffile_exists_p.
* src/fileio.c (PICKY_EACCES, file_test_errno):
Remove. All uses removed.
(Ffile_name_case_insensitive_p, Ffile_exists_p, Ffile_symlink_p)
(Ffile_directory_p, Ffile_regular_p): Document that these
functions return nil if there is trouble.
(Ffile_name_case_insensitive_p, check_file_access)
(Ffile_writable_p, Ffile_symlink_p, Ffile_directory_p)
(Ffile_accessible_directory_p, Ffile_regular_p)
* src/lread.c (Fload):
Go back to treating trouble in determining the answer as if the
file were missing.
* src/fileio.c (Ffile_newer_than_file_p): Use file_attribute_errno
not file_test_errno, since returning nil is not appropriate when
there are two files to test; e.g., in the rare cases where both
file timestamps have overflowed then neither t nor nil is correct.
| -rw-r--r-- | doc/lispref/files.texi | 23 | ||||
| -rw-r--r-- | etc/NEWS | 13 | ||||
| -rw-r--r-- | src/callproc.c | 4 | ||||
| -rw-r--r-- | src/fileio.c | 108 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/lread.c | 14 |
6 files changed, 54 insertions, 109 deletions
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index fba9622fecf..3746c6d2c95 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi | |||
| @@ -607,8 +607,7 @@ This function appends the contents of the region delimited by | |||
| 607 | @var{filename}. If that file does not exist, it is created. This | 607 | @var{filename}. If that file does not exist, it is created. This |
| 608 | function returns @code{nil}. | 608 | function returns @code{nil}. |
| 609 | 609 | ||
| 610 | An error is signaled if @var{filename} specifies a nonwritable file, | 610 | An error is signaled if you cannot write or create @var{filename}. |
| 611 | or a nonexistent file in a directory where files cannot be created. | ||
| 612 | 611 | ||
| 613 | When called from Lisp, this function is completely equivalent to: | 612 | When called from Lisp, this function is completely equivalent to: |
| 614 | 613 | ||
| @@ -851,12 +850,13 @@ permissions. | |||
| 851 | @defun file-exists-p filename | 850 | @defun file-exists-p filename |
| 852 | This function returns @code{t} if a file named @var{filename} appears | 851 | This function returns @code{t} if a file named @var{filename} appears |
| 853 | to exist. This does not mean you can necessarily read the file, only | 852 | to exist. This does not mean you can necessarily read the file, only |
| 854 | that you can find out its attributes. (On GNU and other POSIX-like | 853 | that you can probably find out its attributes. (On GNU and other POSIX-like |
| 855 | systems, this is true if the file exists and you have execute | 854 | systems, this is true if the file exists and you have execute |
| 856 | permission on the containing directories, regardless of the | 855 | permission on the containing directories, regardless of the |
| 857 | permissions of the file itself.) | 856 | permissions of the file itself.) |
| 858 | 857 | ||
| 859 | If the file does not exist, this function returns @code{nil}. | 858 | If the file does not exist, or if there was trouble determining |
| 859 | whether the file exists, this function returns @code{nil}. | ||
| 860 | 860 | ||
| 861 | Directories are files, so @code{file-exists-p} can return @code{t} when | 861 | Directories are files, so @code{file-exists-p} can return @code{t} when |
| 862 | given a directory. However, because @code{file-exists-p} follows | 862 | given a directory. However, because @code{file-exists-p} follows |
| @@ -881,7 +881,7 @@ inside the directory, and open those files if their modes permit. | |||
| 881 | This function returns @code{t} if the file @var{filename} can be written | 881 | This function returns @code{t} if the file @var{filename} can be written |
| 882 | or created by you, and @code{nil} otherwise. A file is writable if the | 882 | or created by you, and @code{nil} otherwise. A file is writable if the |
| 883 | file exists and you can write it. It is creatable if it does not exist, | 883 | file exists and you can write it. It is creatable if it does not exist, |
| 884 | but the specified directory does exist and you can write in that | 884 | but its parent directory does exist and you can write in that |
| 885 | directory. | 885 | directory. |
| 886 | 886 | ||
| 887 | In the example below, @file{foo} is not writable because the parent | 887 | In the example below, @file{foo} is not writable because the parent |
| @@ -899,7 +899,7 @@ directory. | |||
| 899 | @defun file-accessible-directory-p dirname | 899 | @defun file-accessible-directory-p dirname |
| 900 | This function returns @code{t} if you have permission to open existing | 900 | This function returns @code{t} if you have permission to open existing |
| 901 | files in the directory whose name as a file is @var{dirname}; | 901 | files in the directory whose name as a file is @var{dirname}; |
| 902 | otherwise (or if there is no such directory), it returns @code{nil}. | 902 | otherwise (e.g., if there is no such directory), it returns @code{nil}. |
| 903 | The value of @var{dirname} may be either a directory name (such as | 903 | The value of @var{dirname} may be either a directory name (such as |
| 904 | @file{/foo/}) or the file name of a file which is a directory | 904 | @file{/foo/}) or the file name of a file which is a directory |
| 905 | (such as @file{/foo}, without the final slash). | 905 | (such as @file{/foo}, without the final slash). |
| @@ -914,8 +914,8 @@ file in @file{/foo/} will give an error: | |||
| 914 | @end defun | 914 | @end defun |
| 915 | 915 | ||
| 916 | @defun access-file filename string | 916 | @defun access-file filename string |
| 917 | This function opens file @var{filename} for reading, then closes it and | 917 | If you can read @var{filename} this function returns @code{nil}; |
| 918 | returns @code{nil}. However, if the open fails, it signals an error | 918 | otherwise it signals an error |
| 919 | using @var{string} as the error message text. | 919 | using @var{string} as the error message text. |
| 920 | @end defun | 920 | @end defun |
| 921 | 921 | ||
| @@ -1011,6 +1011,7 @@ absolute file name of the target; determining the full file name that | |||
| 1011 | the link points to is nontrivial, see below.) | 1011 | the link points to is nontrivial, see below.) |
| 1012 | 1012 | ||
| 1013 | If the file @var{filename} is not a symbolic link, or does not exist, | 1013 | If the file @var{filename} is not a symbolic link, or does not exist, |
| 1014 | or if there is trouble determining whether it is a symbolic link, | ||
| 1014 | @code{file-symlink-p} returns @code{nil}. | 1015 | @code{file-symlink-p} returns @code{nil}. |
| 1015 | 1016 | ||
| 1016 | Here are a few examples of using this function: | 1017 | Here are a few examples of using this function: |
| @@ -1071,7 +1072,9 @@ link. If you actually need the file name of the link target, use | |||
| 1071 | 1072 | ||
| 1072 | @defun file-directory-p filename | 1073 | @defun file-directory-p filename |
| 1073 | This function returns @code{t} if @var{filename} is the name of an | 1074 | This function returns @code{t} if @var{filename} is the name of an |
| 1074 | existing directory, @code{nil} otherwise. | 1075 | existing directory. It returns @code{nil} if @var{filename} does |
| 1076 | not name a directory, or if there is trouble determining whether | ||
| 1077 | it is a directory. | ||
| 1075 | This function follows symbolic links. | 1078 | This function follows symbolic links. |
| 1076 | 1079 | ||
| 1077 | @example | 1080 | @example |
| @@ -1103,6 +1106,8 @@ This function follows symbolic links. | |||
| 1103 | This function returns @code{t} if the file @var{filename} exists and is | 1106 | This function returns @code{t} if the file @var{filename} exists and is |
| 1104 | a regular file (not a directory, named pipe, terminal, or | 1107 | a regular file (not a directory, named pipe, terminal, or |
| 1105 | other I/O device). | 1108 | other I/O device). |
| 1109 | It returns @code{nil} if @var{filename} does not exist or is not a regular | ||
| 1110 | file, or if there is trouble determining whether it is a regular file. | ||
| 1106 | This function follows symbolic links. | 1111 | This function follows symbolic links. |
| 1107 | @end defun | 1112 | @end defun |
| 1108 | 1113 | ||
| @@ -2029,11 +2029,14 @@ longer defaults to 'buffer-file-name'. | |||
| 2029 | ** File metadata primitives now signal an error if I/O, access, or | 2029 | ** File metadata primitives now signal an error if I/O, access, or |
| 2030 | other serious errors prevent them from determining the result. | 2030 | other serious errors prevent them from determining the result. |
| 2031 | Formerly, these functions often (though not always) returned nil. | 2031 | Formerly, these functions often (though not always) returned nil. |
| 2032 | For example, if searching /etc/firewalld results in an I/O error, | 2032 | For example, if there is an access error, I/O error or low-level |
| 2033 | (file-symlink-p "/etc/firewalld/firewalld.conf") now signals an error | 2033 | integer overflow when getting the attributes of a file F, |
| 2034 | instead of returning nil, because file-symlink-p cannot determine | 2034 | (file-attributes F) now signals an error instead of returning nil. |
| 2035 | whether a symbolic link exists there. These functions still behave as | 2035 | These functions still behave as before if the only problem is that the |
| 2036 | before if the only problem is that the file does not exist. | 2036 | file does not exist. The affected primitives are |
| 2037 | directory-files-and-attributes, file-acl, file-attributes, file-modes, | ||
| 2038 | file-newer-than-file-p, file-selinux-context, file-system-info, and | ||
| 2039 | set-visited-file-modtime. | ||
| 2037 | 2040 | ||
| 2038 | --- | 2041 | --- |
| 2039 | ** The function 'eldoc-message' now accepts a single argument. | 2042 | ** The function 'eldoc-message' now accepts a single argument. |
diff --git a/src/callproc.c b/src/callproc.c index dbbf15c792a..007465cd405 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -1567,12 +1567,12 @@ init_callproc (void) | |||
| 1567 | 1567 | ||
| 1568 | tem = Fexpand_file_name (build_string ("NEWS"), Vdata_directory); | 1568 | tem = Fexpand_file_name (build_string ("NEWS"), Vdata_directory); |
| 1569 | if (!NILP (Fequal (srcdir, Vinvocation_directory)) | 1569 | if (!NILP (Fequal (srcdir, Vinvocation_directory)) |
| 1570 | || !file_access_p (SSDATA (tem), F_OK)) | 1570 | || NILP (Ffile_exists_p (tem))) |
| 1571 | { | 1571 | { |
| 1572 | Lisp_Object newdir; | 1572 | Lisp_Object newdir; |
| 1573 | newdir = Fexpand_file_name (build_string ("../etc/"), lispdir); | 1573 | newdir = Fexpand_file_name (build_string ("../etc/"), lispdir); |
| 1574 | tem = Fexpand_file_name (build_string ("NEWS"), newdir); | 1574 | tem = Fexpand_file_name (build_string ("NEWS"), newdir); |
| 1575 | if (file_access_p (SSDATA (tem), F_OK)) | 1575 | if (!NILP (Ffile_exists_p (tem))) |
| 1576 | Vdata_directory = newdir; | 1576 | Vdata_directory = newdir; |
| 1577 | } | 1577 | } |
| 1578 | } | 1578 | } |
diff --git a/src/fileio.c b/src/fileio.c index b2896c1fe1e..b510d48dbaa 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -253,30 +253,6 @@ file_attribute_errno (Lisp_Object file, int err) | |||
| 253 | return file_metadata_errno ("Getting attributes", file, err); | 253 | return file_metadata_errno ("Getting attributes", file, err); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | /* In theory, EACCES errors for predicates like file-readable-p should | ||
| 257 | be checked further because they may be problems with an ancestor | ||
| 258 | directory instead of with the file itself, which means that we | ||
| 259 | don't have reliable info about the requested file. In practice, | ||
| 260 | though, DOS_NT platforms set errno to EACCES for missing files like | ||
| 261 | "/var/mail", so signaling EACCES errors would be a mistake there. | ||
| 262 | So return nil for EACCES unless PICKY_EACCES, which is false by | ||
| 263 | default on DOS_NT. */ | ||
| 264 | #ifndef PICKY_EACCES | ||
| 265 | # ifdef DOS_NT | ||
| 266 | enum { PICKY_EACCES = false }; | ||
| 267 | # else | ||
| 268 | enum { PICKY_EACCES = true }; | ||
| 269 | # endif | ||
| 270 | #endif | ||
| 271 | |||
| 272 | Lisp_Object | ||
| 273 | file_test_errno (Lisp_Object file, int err) | ||
| 274 | { | ||
| 275 | if (!PICKY_EACCES && err == EACCES) | ||
| 276 | return Qnil; | ||
| 277 | return file_metadata_errno ("Testing file", file, err); | ||
| 278 | } | ||
| 279 | |||
| 280 | void | 256 | void |
| 281 | close_file_unwind (int fd) | 257 | close_file_unwind (int fd) |
| 282 | { | 258 | { |
| @@ -2453,7 +2429,9 @@ file_name_case_insensitive_err (Lisp_Object file) | |||
| 2453 | DEFUN ("file-name-case-insensitive-p", Ffile_name_case_insensitive_p, | 2429 | DEFUN ("file-name-case-insensitive-p", Ffile_name_case_insensitive_p, |
| 2454 | Sfile_name_case_insensitive_p, 1, 1, 0, | 2430 | Sfile_name_case_insensitive_p, 1, 1, 0, |
| 2455 | doc: /* Return t if file FILENAME is on a case-insensitive filesystem. | 2431 | doc: /* Return t if file FILENAME is on a case-insensitive filesystem. |
| 2456 | The arg must be a string. */) | 2432 | Return nil if FILENAME does not exist or is not on a case-insensitive |
| 2433 | filesystem, or if there was trouble determining whether the filesystem | ||
| 2434 | is case-insensitive. */) | ||
| 2457 | (Lisp_Object filename) | 2435 | (Lisp_Object filename) |
| 2458 | { | 2436 | { |
| 2459 | Lisp_Object handler; | 2437 | Lisp_Object handler; |
| @@ -2467,19 +2445,16 @@ The arg must be a string. */) | |||
| 2467 | if (!NILP (handler)) | 2445 | if (!NILP (handler)) |
| 2468 | return call2 (handler, Qfile_name_case_insensitive_p, filename); | 2446 | return call2 (handler, Qfile_name_case_insensitive_p, filename); |
| 2469 | 2447 | ||
| 2470 | /* If the file doesn't exist, move up the filesystem tree until we | 2448 | /* If the file doesn't exist or there is trouble checking its |
| 2471 | reach an existing directory or the root. */ | 2449 | filesystem, move up the filesystem tree until we reach an |
| 2450 | existing, trouble-free directory or the root. */ | ||
| 2472 | while (true) | 2451 | while (true) |
| 2473 | { | 2452 | { |
| 2474 | int err = file_name_case_insensitive_err (filename); | 2453 | int err = file_name_case_insensitive_err (filename); |
| 2475 | switch (err) | 2454 | if (err <= 0) |
| 2476 | { | 2455 | return err < 0 ? Qt : Qnil; |
| 2477 | case -1: return Qt; | ||
| 2478 | default: return file_test_errno (filename, err); | ||
| 2479 | case ENOENT: case ENOTDIR: break; | ||
| 2480 | } | ||
| 2481 | Lisp_Object parent = file_name_directory (filename); | 2456 | Lisp_Object parent = file_name_directory (filename); |
| 2482 | /* Avoid infinite loop if the root is reported as non-existing | 2457 | /* Avoid infinite loop if the root has trouble |
| 2483 | (impossible?). */ | 2458 | (impossible?). */ |
| 2484 | if (!NILP (Fstring_equal (parent, filename))) | 2459 | if (!NILP (Fstring_equal (parent, filename))) |
| 2485 | return Qnil; | 2460 | return Qnil; |
| @@ -2739,8 +2714,7 @@ file_name_absolute_p (char const *filename) | |||
| 2739 | } | 2714 | } |
| 2740 | 2715 | ||
| 2741 | /* Return t if FILE exists and is accessible via OPERATION and AMODE, | 2716 | /* Return t if FILE exists and is accessible via OPERATION and AMODE, |
| 2742 | nil (setting errno) if not. Signal an error if the result cannot | 2717 | nil (setting errno) if not. */ |
| 2743 | be determined. */ | ||
| 2744 | 2718 | ||
| 2745 | static Lisp_Object | 2719 | static Lisp_Object |
| 2746 | check_file_access (Lisp_Object file, Lisp_Object operation, int amode) | 2720 | check_file_access (Lisp_Object file, Lisp_Object operation, int amode) |
| @@ -2758,22 +2732,13 @@ check_file_access (Lisp_Object file, Lisp_Object operation, int amode) | |||
| 2758 | } | 2732 | } |
| 2759 | 2733 | ||
| 2760 | char *encoded_file = SSDATA (ENCODE_FILE (file)); | 2734 | char *encoded_file = SSDATA (ENCODE_FILE (file)); |
| 2761 | bool ok = file_access_p (encoded_file, amode); | 2735 | return file_access_p (encoded_file, amode) ? Qt : Qnil; |
| 2762 | if (ok) | ||
| 2763 | return Qt; | ||
| 2764 | int err = errno; | ||
| 2765 | if (err == EROFS || err == ETXTBSY | ||
| 2766 | || (PICKY_EACCES && err == EACCES && amode != F_OK | ||
| 2767 | && file_access_p (encoded_file, F_OK))) | ||
| 2768 | { | ||
| 2769 | errno = err; | ||
| 2770 | return Qnil; | ||
| 2771 | } | ||
| 2772 | return file_test_errno (file, err); | ||
| 2773 | } | 2736 | } |
| 2774 | 2737 | ||
| 2775 | DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0, | 2738 | DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0, |
| 2776 | doc: /* Return t if file FILENAME exists (whether or not you can read it). | 2739 | doc: /* Return t if file FILENAME exists (whether or not you can read it). |
| 2740 | Return nil if FILENAME does not exist, or if there was trouble | ||
| 2741 | determining whether the file exists. | ||
| 2777 | See also `file-readable-p' and `file-attributes'. | 2742 | See also `file-readable-p' and `file-attributes'. |
| 2778 | This returns nil for a symlink to a nonexistent file. | 2743 | This returns nil for a symlink to a nonexistent file. |
| 2779 | Use `file-symlink-p' to test for such links. */) | 2744 | Use `file-symlink-p' to test for such links. */) |
| @@ -2834,16 +2799,7 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, | |||
| 2834 | should check ACLs though, which do affect this. */ | 2799 | should check ACLs though, which do affect this. */ |
| 2835 | return file_directory_p (encoded) ? Qt : Qnil; | 2800 | return file_directory_p (encoded) ? Qt : Qnil; |
| 2836 | #else | 2801 | #else |
| 2837 | if (file_access_p (SSDATA (encoded), W_OK | X_OK)) | 2802 | return file_access_p (SSDATA (encoded), W_OK | X_OK) ? Qt : Qnil; |
| 2838 | return Qt; | ||
| 2839 | int err = errno; | ||
| 2840 | if (err == EROFS | ||
| 2841 | || (err == EACCES && file_access_p (SSDATA (encoded), F_OK))) | ||
| 2842 | { | ||
| 2843 | errno = err; | ||
| 2844 | return Qnil; | ||
| 2845 | } | ||
| 2846 | return file_test_errno (absname, err); | ||
| 2847 | #endif | 2803 | #endif |
| 2848 | } | 2804 | } |
| 2849 | 2805 | ||
| @@ -2919,7 +2875,8 @@ check_emacs_readlinkat (int fd, Lisp_Object file, char const *encoded_file) | |||
| 2919 | DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0, | 2875 | DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0, |
| 2920 | doc: /* Return non-nil if file FILENAME is the name of a symbolic link. | 2876 | doc: /* Return non-nil if file FILENAME is the name of a symbolic link. |
| 2921 | The value is the link target, as a string. | 2877 | The value is the link target, as a string. |
| 2922 | Otherwise it returns nil. | 2878 | Return nil if FILENAME does not exist or is not a symbolic link, |
| 2879 | of there was trouble determining whether the file is a symbolic link. | ||
| 2923 | 2880 | ||
| 2924 | This function does not check whether the link target exists. */) | 2881 | This function does not check whether the link target exists. */) |
| 2925 | (Lisp_Object filename) | 2882 | (Lisp_Object filename) |
| @@ -2935,12 +2892,13 @@ This function does not check whether the link target exists. */) | |||
| 2935 | if (!NILP (handler)) | 2892 | if (!NILP (handler)) |
| 2936 | return call2 (handler, Qfile_symlink_p, filename); | 2893 | return call2 (handler, Qfile_symlink_p, filename); |
| 2937 | 2894 | ||
| 2938 | return check_emacs_readlinkat (AT_FDCWD, filename, | 2895 | return emacs_readlinkat (AT_FDCWD, SSDATA (ENCODE_FILE (filename))); |
| 2939 | SSDATA (ENCODE_FILE (filename))); | ||
| 2940 | } | 2896 | } |
| 2941 | 2897 | ||
| 2942 | DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0, | 2898 | DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0, |
| 2943 | doc: /* Return t if FILENAME names an existing directory. | 2899 | doc: /* Return t if FILENAME names an existing directory. |
| 2900 | Return nil if FILENAME does not name a directory, or if there | ||
| 2901 | was trouble determining whether FILENAME is a directory. | ||
| 2944 | Symbolic links to directories count as directories. | 2902 | Symbolic links to directories count as directories. |
| 2945 | See `file-symlink-p' to distinguish symlinks. */) | 2903 | See `file-symlink-p' to distinguish symlinks. */) |
| 2946 | (Lisp_Object filename) | 2904 | (Lisp_Object filename) |
| @@ -2953,9 +2911,7 @@ See `file-symlink-p' to distinguish symlinks. */) | |||
| 2953 | if (!NILP (handler)) | 2911 | if (!NILP (handler)) |
| 2954 | return call2 (handler, Qfile_directory_p, absname); | 2912 | return call2 (handler, Qfile_directory_p, absname); |
| 2955 | 2913 | ||
| 2956 | if (file_directory_p (absname)) | 2914 | return file_directory_p (absname) ? Qt : Qnil; |
| 2957 | return Qt; | ||
| 2958 | return file_test_errno (absname, errno); | ||
| 2959 | } | 2915 | } |
| 2960 | 2916 | ||
| 2961 | /* Return true if FILE is a directory or a symlink to a directory. | 2917 | /* Return true if FILE is a directory or a symlink to a directory. |
| @@ -3040,12 +2996,7 @@ really is a readable and searchable directory. */) | |||
| 3040 | } | 2996 | } |
| 3041 | 2997 | ||
| 3042 | Lisp_Object encoded_absname = ENCODE_FILE (absname); | 2998 | Lisp_Object encoded_absname = ENCODE_FILE (absname); |
| 3043 | if (file_accessible_directory_p (encoded_absname)) | 2999 | return file_accessible_directory_p (encoded_absname) ? Qt : Qnil; |
| 3044 | return Qt; | ||
| 3045 | int err = errno; | ||
| 3046 | if (err == EACCES && file_access_p (SSDATA (encoded_absname), F_OK)) | ||
| 3047 | return Qnil; | ||
| 3048 | return file_test_errno (absname, err); | ||
| 3049 | } | 3000 | } |
| 3050 | 3001 | ||
| 3051 | /* If FILE is a searchable directory or a symlink to a | 3002 | /* If FILE is a searchable directory or a symlink to a |
| @@ -3108,6 +3059,8 @@ file_accessible_directory_p (Lisp_Object file) | |||
| 3108 | DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0, | 3059 | DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0, |
| 3109 | doc: /* Return t if FILENAME names a regular file. | 3060 | doc: /* Return t if FILENAME names a regular file. |
| 3110 | This is the sort of file that holds an ordinary stream of data bytes. | 3061 | This is the sort of file that holds an ordinary stream of data bytes. |
| 3062 | Return nil if FILENAME does not exist or is not a regular file, | ||
| 3063 | or there was trouble determining whether FILENAME is a regular file. | ||
| 3111 | Symbolic links to regular files count as regular files. | 3064 | Symbolic links to regular files count as regular files. |
| 3112 | See `file-symlink-p' to distinguish symlinks. */) | 3065 | See `file-symlink-p' to distinguish symlinks. */) |
| 3113 | (Lisp_Object filename) | 3066 | (Lisp_Object filename) |
| @@ -3133,9 +3086,7 @@ See `file-symlink-p' to distinguish symlinks. */) | |||
| 3133 | Vw32_get_true_file_attributes = true_attributes; | 3086 | Vw32_get_true_file_attributes = true_attributes; |
| 3134 | #endif | 3087 | #endif |
| 3135 | 3088 | ||
| 3136 | if (stat_result == 0) | 3089 | return stat_result == 0 && S_ISREG (st.st_mode) ? Qt : Qnil; |
| 3137 | return S_ISREG (st.st_mode) ? Qt : Qnil; | ||
| 3138 | return file_test_errno (absname, errno); | ||
| 3139 | } | 3090 | } |
| 3140 | 3091 | ||
| 3141 | DEFUN ("file-selinux-context", Ffile_selinux_context, | 3092 | DEFUN ("file-selinux-context", Ffile_selinux_context, |
| @@ -3541,20 +3492,15 @@ otherwise, if FILE2 does not exist, the answer is t. */) | |||
| 3541 | { | 3492 | { |
| 3542 | err1 = errno; | 3493 | err1 = errno; |
| 3543 | if (err1 != EOVERFLOW) | 3494 | if (err1 != EOVERFLOW) |
| 3544 | return file_test_errno (absname1, err1); | 3495 | return file_attribute_errno (absname1, err1); |
| 3545 | } | 3496 | } |
| 3546 | |||
| 3547 | if (stat (SSDATA (ENCODE_FILE (absname2)), &st2) != 0) | 3497 | if (stat (SSDATA (ENCODE_FILE (absname2)), &st2) != 0) |
| 3548 | { | 3498 | { |
| 3549 | file_test_errno (absname2, errno); | 3499 | file_attribute_errno (absname2, errno); |
| 3550 | return Qt; | 3500 | return Qt; |
| 3551 | } | 3501 | } |
| 3552 | |||
| 3553 | if (err1) | 3502 | if (err1) |
| 3554 | { | 3503 | file_attribute_errno (absname1, err1); |
| 3555 | file_test_errno (absname1, err1); | ||
| 3556 | eassume (false); | ||
| 3557 | } | ||
| 3558 | 3504 | ||
| 3559 | return (timespec_cmp (get_stat_mtime (&st2), get_stat_mtime (&st1)) < 0 | 3505 | return (timespec_cmp (get_stat_mtime (&st2), get_stat_mtime (&st1)) < 0 |
| 3560 | ? Qt : Qnil); | 3506 | ? Qt : Qnil); |
diff --git a/src/lisp.h b/src/lisp.h index b081ae1cee8..e68d2732e21 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4315,7 +4315,6 @@ extern AVOID report_file_errno (const char *, Lisp_Object, int); | |||
| 4315 | extern AVOID report_file_error (const char *, Lisp_Object); | 4315 | extern AVOID report_file_error (const char *, Lisp_Object); |
| 4316 | extern AVOID report_file_notify_error (const char *, Lisp_Object); | 4316 | extern AVOID report_file_notify_error (const char *, Lisp_Object); |
| 4317 | extern Lisp_Object file_attribute_errno (Lisp_Object, int); | 4317 | extern Lisp_Object file_attribute_errno (Lisp_Object, int); |
| 4318 | extern Lisp_Object file_test_errno (Lisp_Object, int); | ||
| 4319 | extern bool internal_delete_file (Lisp_Object); | 4318 | extern bool internal_delete_file (Lisp_Object); |
| 4320 | extern Lisp_Object check_emacs_readlinkat (int, Lisp_Object, char const *); | 4319 | extern Lisp_Object check_emacs_readlinkat (int, Lisp_Object, char const *); |
| 4321 | extern bool file_directory_p (Lisp_Object); | 4320 | extern bool file_directory_p (Lisp_Object); |
diff --git a/src/lread.c b/src/lread.c index 4f3446b09db..151731a81d9 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -1343,26 +1343,18 @@ Return t if the file exists and loads successfully. */) | |||
| 1343 | /* openp already checked for newness, no point doing it again. | 1343 | /* openp already checked for newness, no point doing it again. |
| 1344 | FIXME would be nice to get a message when openp | 1344 | FIXME would be nice to get a message when openp |
| 1345 | ignores suffix order due to load_prefer_newer. */ | 1345 | ignores suffix order due to load_prefer_newer. */ |
| 1346 | Lisp_Object notfound = found; | ||
| 1347 | if (!load_prefer_newer && is_elc) | 1346 | if (!load_prefer_newer && is_elc) |
| 1348 | { | 1347 | { |
| 1349 | result = stat (SSDATA (efound), &s1); | 1348 | result = stat (SSDATA (efound), &s1); |
| 1350 | int err = errno; | ||
| 1351 | if (result == 0) | 1349 | if (result == 0) |
| 1352 | { | 1350 | { |
| 1353 | SSET (efound, SBYTES (efound) - 1, 0); | 1351 | SSET (efound, SBYTES (efound) - 1, 0); |
| 1354 | result = stat (SSDATA (efound), &s2); | 1352 | result = stat (SSDATA (efound), &s2); |
| 1355 | err = errno; | ||
| 1356 | SSET (efound, SBYTES (efound) - 1, 'c'); | 1353 | SSET (efound, SBYTES (efound) - 1, 'c'); |
| 1357 | if (result != 0) | ||
| 1358 | notfound = Fsubstring (found, make_fixnum (0), | ||
| 1359 | make_fixnum (-1)); | ||
| 1360 | } | 1354 | } |
| 1361 | if (result != 0) | 1355 | |
| 1362 | file_test_errno (notfound, err); | 1356 | if (result == 0 |
| 1363 | else if (timespec_cmp (get_stat_mtime (&s1), | 1357 | && timespec_cmp (get_stat_mtime (&s1), get_stat_mtime (&s2)) < 0) |
| 1364 | get_stat_mtime (&s2)) | ||
| 1365 | < 0) | ||
| 1366 | { | 1358 | { |
| 1367 | /* Make the progress messages mention that source is newer. */ | 1359 | /* Make the progress messages mention that source is newer. */ |
| 1368 | newer = 1; | 1360 | newer = 1; |