Next: , Previous: Truenames, Up: Information about Files

25.6.4 Other Information about Files

This section describes the functions for getting detailed information about a file, other than its contents. This information includes the mode bits that control access permissions, the owner and group numbers, the number of names, the inode number, the size, and the times of access and modification.

— Function: file-modes filename

This function returns the mode bits describing the file permissions of filename, as an integer. It recursively follows symbolic links in filename at all levels. If filename does not exist, the return value is nil.

See File Permissions, for a description of mode bits. If the low-order bit is 1, then the file is executable by all users, if the second-lowest-order bit is 1, then the file is writable by all users, etc. The highest value returnable is 4095 (7777 octal), meaning that everyone has read, write, and execute permission, that the SUID bit is set for both others and group, and that the sticky bit is set.

          (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 0 3063 Oct 30 16:00 diffs

See Changing Files, for functions that change file permissions, such as set-file-modes.

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, below.

If the filename argument to the next two functions is a symbolic link, then these function do not replace it with its target. However, they both recursively follow symbolic links at all levels of parent directories.

— Function: file-nlinks filename

This functions returns the number of names (i.e., hard links) that file filename has. If the file does not exist, then this function returns nil. Note that symbolic links have no effect on this function, because they are not considered to be names of the files they link to.

          % ls -l foo*
          -rw-rw-rw-  2 rms       4 Aug 19 01:27 foo
          -rw-rw-rw-  2 rms       4 Aug 19 01:27 foo1
          
          (file-nlinks "foo")
               ⇒ 2
          (file-nlinks "doesnt-exist")
               ⇒ nil
— Function: file-attributes filename &optional id-format

This function returns a list of attributes of file filename. If the specified file cannot be opened, it returns nil. The optional parameter id-format specifies the preferred format of attributes UID and GID (see below)—the valid values are 'string and 'integer. The latter is the default, but we plan to change that, so you should specify a non-nil value for id-format if you use the returned UID or GID.

The elements of the list, in order, are:

  1. t for a directory, a string for a symbolic link (the name linked to), or nil for a text file.
  2. The number of names the file has. Alternate names, also known as hard links, can be created by using the add-name-to-file function (see Changing Files).
  3. The file's UID, normally as a string. However, if it does not correspond to a named user, the value is an integer or a floating point number.
  4. The file's GID, likewise.
  5. The time of last access, as a list of four integers (sec-high sec-low microsec picosec). (This is similar to the value of current-time; see Time of Day.) Note that on some FAT-based filesystems, only the date of last access is recorded, so this time will always hold the midnight of the day of last access.

  6. The time of last modification as a list of four integers (as above). This is the last time when the file's contents were modified.
  7. The time of last status change as a list of four integers (as above). This is the time of the last change to the file's access mode bits, its owner and group, and other information recorded in the filesystem for the file, beyond the file's contents.
  8. The size of the file in bytes. If the size is too large to fit in a Lisp integer, this is a floating point number.
  9. The file's modes, as a string of ten letters or dashes, as in ‘ls -l’.
  10. t if the file's GID would change if file were deleted and recreated; nil otherwise.
  11. The file's inode number. If possible, this is an integer. If the inode number is too large to be represented as an integer in Emacs Lisp but dividing it by 2^16 yields a representable integer, then the value has the form (high . low), where low holds the low 16 bits. If the inode number is too wide for even that, the value is of the form (high middle . low), where high holds the high bits, middle the middle 24 bits, and low the low 16 bits.
  12. The filesystem number of the device that the file is on. Depending on the magnitude of the value, this can be either an integer or a cons cell, in the same manner as the inode number. This element and the file's inode number together give enough information to distinguish any two files on the system—no two files can have the same values for both of these numbers.

For example, here are the file attributes for files.texi:

          (file-attributes "files.texi" 'string)
               ⇒  (nil 1 "lh" "users"
                    (20614 64019 50040 152000)
                    (20000 23 0 0)
                    (20614 64555 902289 872000)
                    122295 "-rw-rw-rw-"
                    nil  (5888 2 . 43978)
                    (15479 . 46724))

and here is how the result is interpreted:

nil
is neither a directory nor a symbolic link.
1
has only one name (the name files.texi in the current default directory).
"lh"
is owned by the user with name "lh".
"users"
is in the group with name "users".
(20614 64019 50040 152000)
was last accessed on October 23, 2012, at 20:12:03.050040152 UTC.
(20000 23 0 0)
was last modified on July 15, 2001, at 08:53:43 UTC.
(20614 64555 902289 872000)
last had its status changed on October 23, 2012, at 20:20:59.902289872 UTC.
122295
is 122295 bytes long. (It may not contain 122295 characters, though, if some of the bytes belong to multibyte sequences, and also if the end-of-line format is CR-LF.)
"-rw-rw-rw-"
has a mode of read and write access for the owner, group, and world.
nil
would retain the same GID if it were recreated.
(5888 2 . 43978)
has an inode number of 6473924464520138.
(15479 . 46724)
is on the file-system device whose number is 1014478468.

SELinux is a Linux kernel feature which provides more sophisticated file access controls than ordinary “Unix-style” file permissions. If Emacs has been compiled with SELinux support on a system with SELinux enabled, you can use the function file-selinux-context to retrieve a file's SELinux security context. For the function set-file-selinux-context, see Changing Files.

— Function: file-selinux-context filename

This function returns the SELinux security context of the file filename. This return value is a list of the form (user role type range), whose elements are the context's user, role, type, and range respectively, as Lisp strings. See the SELinux documentation for details about what these actually mean.

If the file does not exist or is inaccessible, or if the system does not support SELinux, or if Emacs was not compiled with SELinux support, then the return value is (nil nil nil nil).