@var{filename}. If that file does not exist, it is created. This
function returns @code{nil}.
-An error is signaled if @var{filename} specifies a nonwritable file,
-or a nonexistent file in a directory where files cannot be created.
+An error is signaled if you cannot write or create @var{filename}.
When called from Lisp, this function is completely equivalent to:
@defun file-exists-p filename
This function returns @code{t} if a file named @var{filename} appears
to exist. This does not mean you can necessarily read the file, only
-that you can find out its attributes. (On GNU and other POSIX-like
+that you can probably find out its attributes. (On GNU and other POSIX-like
systems, this is true if the file exists and you have execute
permission on the containing directories, regardless of the
permissions of the file itself.)
-If the file does not exist, this function returns @code{nil}.
+If the file does not exist, or if there was trouble determining
+whether the file exists, this function returns @code{nil}.
Directories are files, so @code{file-exists-p} can return @code{t} when
given a directory. However, because @code{file-exists-p} follows
This function returns @code{t} if the file @var{filename} can be written
or created by you, and @code{nil} otherwise. A file is writable if the
file exists and you can write it. It is creatable if it does not exist,
-but the specified directory does exist and you can write in that
+but its parent directory does exist and you can write in that
directory.
In the example below, @file{foo} is not writable because the parent
@defun file-accessible-directory-p dirname
This function returns @code{t} if you have permission to open existing
files in the directory whose name as a file is @var{dirname};
-otherwise (or if there is no such directory), it returns @code{nil}.
+otherwise (e.g., if there is no such directory), it returns @code{nil}.
The value of @var{dirname} may be either a directory name (such as
@file{/foo/}) or the file name of a file which is a directory
(such as @file{/foo}, without the final slash).
@end defun
@defun access-file filename string
-This function opens file @var{filename} for reading, then closes it and
-returns @code{nil}. However, if the open fails, it signals an error
+If you can read @var{filename} this function returns @code{nil};
+otherwise it signals an error
using @var{string} as the error message text.
@end defun
the link points to is nontrivial, see below.)
If the file @var{filename} is not a symbolic link, or does not exist,
+or if there is trouble determining whether it is a symbolic link,
@code{file-symlink-p} returns @code{nil}.
Here are a few examples of using this function:
@defun file-directory-p filename
This function returns @code{t} if @var{filename} is the name of an
-existing directory, @code{nil} otherwise.
+existing directory. It returns @code{nil} if @var{filename} does
+not name a directory, or if there is trouble determining whether
+it is a directory.
This function follows symbolic links.
@example
This function returns @code{t} if the file @var{filename} exists and is
a regular file (not a directory, named pipe, terminal, or
other I/O device).
+It returns @code{nil} if @var{filename} does not exist or is not a regular
+file, or if there is trouble determining whether it is a regular file.
This function follows symbolic links.
@end defun
return file_metadata_errno ("Getting attributes", file, err);
}
-/* In theory, EACCES errors for predicates like file-readable-p should
- be checked further because they may be problems with an ancestor
- directory instead of with the file itself, which means that we
- don't have reliable info about the requested file. In practice,
- though, DOS_NT platforms set errno to EACCES for missing files like
- "/var/mail", so signaling EACCES errors would be a mistake there.
- So return nil for EACCES unless PICKY_EACCES, which is false by
- default on DOS_NT. */
-#ifndef PICKY_EACCES
-# ifdef DOS_NT
-enum { PICKY_EACCES = false };
-# else
-enum { PICKY_EACCES = true };
-# endif
-#endif
-
-Lisp_Object
-file_test_errno (Lisp_Object file, int err)
-{
- if (!PICKY_EACCES && err == EACCES)
- return Qnil;
- return file_metadata_errno ("Testing file", file, err);
-}
-
void
close_file_unwind (int fd)
{
DEFUN ("file-name-case-insensitive-p", Ffile_name_case_insensitive_p,
Sfile_name_case_insensitive_p, 1, 1, 0,
doc: /* Return t if file FILENAME is on a case-insensitive filesystem.
-The arg must be a string. */)
+Return nil if FILENAME does not exist or is not on a case-insensitive
+filesystem, or if there was trouble determining whether the filesystem
+is case-insensitive. */)
(Lisp_Object filename)
{
Lisp_Object handler;
if (!NILP (handler))
return call2 (handler, Qfile_name_case_insensitive_p, filename);
- /* If the file doesn't exist, move up the filesystem tree until we
- reach an existing directory or the root. */
+ /* If the file doesn't exist or there is trouble checking its
+ filesystem, move up the filesystem tree until we reach an
+ existing, trouble-free directory or the root. */
while (true)
{
int err = file_name_case_insensitive_err (filename);
- switch (err)
- {
- case -1: return Qt;
- default: return file_test_errno (filename, err);
- case ENOENT: case ENOTDIR: break;
- }
+ if (err <= 0)
+ return err < 0 ? Qt : Qnil;
Lisp_Object parent = file_name_directory (filename);
- /* Avoid infinite loop if the root is reported as non-existing
+ /* Avoid infinite loop if the root has trouble
(impossible?). */
if (!NILP (Fstring_equal (parent, filename)))
return Qnil;
}
\f
/* Return t if FILE exists and is accessible via OPERATION and AMODE,
- nil (setting errno) if not. Signal an error if the result cannot
- be determined. */
+ nil (setting errno) if not. */
static Lisp_Object
check_file_access (Lisp_Object file, Lisp_Object operation, int amode)
}
char *encoded_file = SSDATA (ENCODE_FILE (file));
- bool ok = file_access_p (encoded_file, amode);
- if (ok)
- return Qt;
- int err = errno;
- if (err == EROFS || err == ETXTBSY
- || (PICKY_EACCES && err == EACCES && amode != F_OK
- && file_access_p (encoded_file, F_OK)))
- {
- errno = err;
- return Qnil;
- }
- return file_test_errno (file, err);
+ return file_access_p (encoded_file, amode) ? Qt : Qnil;
}
DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0,
doc: /* Return t if file FILENAME exists (whether or not you can read it).
+Return nil if FILENAME does not exist, or if there was trouble
+determining whether the file exists.
See also `file-readable-p' and `file-attributes'.
This returns nil for a symlink to a nonexistent file.
Use `file-symlink-p' to test for such links. */)
should check ACLs though, which do affect this. */
return file_directory_p (encoded) ? Qt : Qnil;
#else
- if (file_access_p (SSDATA (encoded), W_OK | X_OK))
- return Qt;
- int err = errno;
- if (err == EROFS
- || (err == EACCES && file_access_p (SSDATA (encoded), F_OK)))
- {
- errno = err;
- return Qnil;
- }
- return file_test_errno (absname, err);
+ return file_access_p (SSDATA (encoded), W_OK | X_OK) ? Qt : Qnil;
#endif
}
\f
DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
doc: /* Return non-nil if file FILENAME is the name of a symbolic link.
The value is the link target, as a string.
-Otherwise it returns nil.
+Return nil if FILENAME does not exist or is not a symbolic link,
+of there was trouble determining whether the file is a symbolic link.
This function does not check whether the link target exists. */)
(Lisp_Object filename)
if (!NILP (handler))
return call2 (handler, Qfile_symlink_p, filename);
- return check_emacs_readlinkat (AT_FDCWD, filename,
- SSDATA (ENCODE_FILE (filename)));
+ return emacs_readlinkat (AT_FDCWD, SSDATA (ENCODE_FILE (filename)));
}
DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
doc: /* Return t if FILENAME names an existing directory.
+Return nil if FILENAME does not name a directory, or if there
+was trouble determining whether FILENAME is a directory.
Symbolic links to directories count as directories.
See `file-symlink-p' to distinguish symlinks. */)
(Lisp_Object filename)
if (!NILP (handler))
return call2 (handler, Qfile_directory_p, absname);
- if (file_directory_p (absname))
- return Qt;
- return file_test_errno (absname, errno);
+ return file_directory_p (absname) ? Qt : Qnil;
}
/* Return true if FILE is a directory or a symlink to a directory.
}
Lisp_Object encoded_absname = ENCODE_FILE (absname);
- if (file_accessible_directory_p (encoded_absname))
- return Qt;
- int err = errno;
- if (err == EACCES && file_access_p (SSDATA (encoded_absname), F_OK))
- return Qnil;
- return file_test_errno (absname, err);
+ return file_accessible_directory_p (encoded_absname) ? Qt : Qnil;
}
/* If FILE is a searchable directory or a symlink to a
DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
doc: /* Return t if FILENAME names a regular file.
This is the sort of file that holds an ordinary stream of data bytes.
+Return nil if FILENAME does not exist or is not a regular file,
+or there was trouble determining whether FILENAME is a regular file.
Symbolic links to regular files count as regular files.
See `file-symlink-p' to distinguish symlinks. */)
(Lisp_Object filename)
Vw32_get_true_file_attributes = true_attributes;
#endif
- if (stat_result == 0)
- return S_ISREG (st.st_mode) ? Qt : Qnil;
- return file_test_errno (absname, errno);
+ return stat_result == 0 && S_ISREG (st.st_mode) ? Qt : Qnil;
}
\f
DEFUN ("file-selinux-context", Ffile_selinux_context,
{
err1 = errno;
if (err1 != EOVERFLOW)
- return file_test_errno (absname1, err1);
+ return file_attribute_errno (absname1, err1);
}
-
if (stat (SSDATA (ENCODE_FILE (absname2)), &st2) != 0)
{
- file_test_errno (absname2, errno);
+ file_attribute_errno (absname2, errno);
return Qt;
}
-
if (err1)
- {
- file_test_errno (absname1, err1);
- eassume (false);
- }
+ file_attribute_errno (absname1, err1);
return (timespec_cmp (get_stat_mtime (&st2), get_stat_mtime (&st1)) < 0
? Qt : Qnil);