aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
authorPaul Eggert2019-09-21 11:27:46 -0700
committerPaul Eggert2019-09-21 11:38:36 -0700
commitd49d6ea9677eea1d30aae4244934b1c7336e35a3 (patch)
treec671f33693f458a7ba992a2a97250f620aec861d /src/fileio.c
parent56213b15e65a350f3f8cd9426a97691d8ff217ee (diff)
downloademacs-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.
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c108
1 files changed, 27 insertions, 81 deletions
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
266enum { PICKY_EACCES = false };
267# else
268enum { PICKY_EACCES = true };
269# endif
270#endif
271
272Lisp_Object
273file_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
280void 256void
281close_file_unwind (int fd) 257close_file_unwind (int fd)
282{ 258{
@@ -2453,7 +2429,9 @@ file_name_case_insensitive_err (Lisp_Object file)
2453DEFUN ("file-name-case-insensitive-p", Ffile_name_case_insensitive_p, 2429DEFUN ("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.
2456The arg must be a string. */) 2432Return nil if FILENAME does not exist or is not on a case-insensitive
2433filesystem, or if there was trouble determining whether the filesystem
2434is 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
2745static Lisp_Object 2719static Lisp_Object
2746check_file_access (Lisp_Object file, Lisp_Object operation, int amode) 2720check_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
2775DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0, 2738DEFUN ("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).
2740Return nil if FILENAME does not exist, or if there was trouble
2741determining whether the file exists.
2777See also `file-readable-p' and `file-attributes'. 2742See also `file-readable-p' and `file-attributes'.
2778This returns nil for a symlink to a nonexistent file. 2743This returns nil for a symlink to a nonexistent file.
2779Use `file-symlink-p' to test for such links. */) 2744Use `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)
2919DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0, 2875DEFUN ("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.
2921The value is the link target, as a string. 2877The value is the link target, as a string.
2922Otherwise it returns nil. 2878Return nil if FILENAME does not exist or is not a symbolic link,
2879of there was trouble determining whether the file is a symbolic link.
2923 2880
2924This function does not check whether the link target exists. */) 2881This 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
2942DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0, 2898DEFUN ("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.
2900Return nil if FILENAME does not name a directory, or if there
2901was trouble determining whether FILENAME is a directory.
2944Symbolic links to directories count as directories. 2902Symbolic links to directories count as directories.
2945See `file-symlink-p' to distinguish symlinks. */) 2903See `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)
3108DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0, 3059DEFUN ("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.
3110This is the sort of file that holds an ordinary stream of data bytes. 3061This is the sort of file that holds an ordinary stream of data bytes.
3062Return nil if FILENAME does not exist or is not a regular file,
3063or there was trouble determining whether FILENAME is a regular file.
3111Symbolic links to regular files count as regular files. 3064Symbolic links to regular files count as regular files.
3112See `file-symlink-p' to distinguish symlinks. */) 3065See `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
3141DEFUN ("file-selinux-context", Ffile_selinux_context, 3092DEFUN ("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);