elisp: Testing Accessibility
24.6.1 Testing Accessibility
----------------------------
These functions test for permission to access a file for reading,
writing, or execution. Unless explicitly stated otherwise, they
recursively follow symbolic links for their file name arguments, at all
levels (at the level of the file itself and at all levels of parent
directories).
On some operating systems, more complex sets of access permissions
can be specified, via mechanisms such as Access Control Lists (ACLs).
Extended Attributes, for how to query and set those permissions.
-- Function: file-exists-p filename
This function returns ‘t’ if a file named FILENAME appears to
exist. This does not mean you can necessarily read the file, only
that you can find out its attributes. (On Unix and GNU/Linux, 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, or if access control policies prevent
you from finding its attributes, this function returns ‘nil’.
Directories are files, so ‘file-exists-p’ returns ‘t’ when given a
directory name. However, symbolic links are treated specially;
‘file-exists-p’ returns ‘t’ for a symbolic link name only if the
target file exists.
-- Function: file-readable-p filename
This function returns ‘t’ if a file named FILENAME exists and you
can read it. It returns ‘nil’ otherwise.
-- Function: file-executable-p filename
This function returns ‘t’ if a file named FILENAME exists and you
can execute it. It returns ‘nil’ otherwise. On Unix and
GNU/Linux, if the file is a directory, execute permission means you
can check the existence and attributes of files inside the
directory, and open those files if their modes permit.
-- Function: file-writable-p filename
This function returns ‘t’ if the file FILENAME can be written or
created by you, and ‘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 directory.
In the example below, ‘foo’ is not writable because the parent
directory does not exist, even though the user could create such a
directory.
(file-writable-p "~/no-such-dir/foo")
⇒ nil
-- Function: file-accessible-directory-p dirname
This function returns ‘t’ if you have permission to open existing
files in the directory whose name as a file is DIRNAME; otherwise
(or if there is no such directory), it returns ‘nil’. The value of
DIRNAME may be either a directory name (such as ‘/foo/’) or the
file name of a file which is a directory (such as ‘/foo’, without
the final slash).
For example, from the following we deduce that any attempt to read
a file in ‘/foo/’ will give an error:
(file-accessible-directory-p "/foo")
⇒ nil
-- Function: access-file filename string
This function opens file FILENAME for reading, then closes it and
returns ‘nil’. However, if the open fails, it signals an error
using STRING as the error message text.
-- Function: file-ownership-preserved-p filename &optional group
This function returns ‘t’ if deleting the file FILENAME and then
creating it anew would keep the file’s owner unchanged. It also
returns ‘t’ for nonexistent files.
If the optional argument GROUP is non-‘nil’, this function also
checks that the file’s group would be unchanged.
If FILENAME is a symbolic link, then, unlike the other functions
discussed here, ‘file-ownership-preserved-p’ does _not_ replace
FILENAME with its target. However, it does recursively follow
symbolic links at all levels of parent directories.
-- Function: file-modes filename
This function returns the “mode bits” of FILENAME—an integer
summarizing its read, write, and execution permissions. Symbolic
links in FILENAME are recursively followed at all levels. If the
file does not exist, the return value is ‘nil’.
(coreutils)File permissions, for a description of mode
bits. For example, if the low-order bit is 1, the file is
executable by all users; if the second-lowest-order bit is 1, the
file is writable by all users; etc. The highest possible value is
4095 (7777 octal), meaning that everyone has read, write, and
execute permission, the SUID bit is set for both others and group,
and the sticky bit is set.
Changing Files, for the ‘set-file-modes’ function, which
can be used to set these permissions.
(file-modes "~/junk/diffs")
⇒ 492 ; Decimal integer.
(format "%o" 492)
⇒ "754" ; Convert to octal.
(set-file-modes "~/junk/diffs" #o666)
⇒ nil
$ ls -l diffs
-rw-rw-rw- 1 lewis lewis 3063 Oct 30 16:00 diffs
*MS-DOS note:* On MS-DOS, there is no such thing as an executable
file mode bit. So ‘file-modes’ considers a file executable if its
name ends in one of the standard executable extensions, such as
‘.com’, ‘.bat’, ‘.exe’, and some others. Files that begin with the
Unix-standard ‘#!’ signature, such as shell and Perl scripts, are
also considered executable. Directories are also reported as
executable, for compatibility with Unix. These conventions are
also followed by ‘file-attributes’ (File Attributes).