CHMOD(2)

CHMOD(2) | System Calls Manual | CHMOD(2)

# NAME

`chmod`, `lchmod`, `fchmod`, `fchmodat` —
change mode of file

# LIBRARY

Standard C Library (libc, -lc)

# SYNOPSIS

`#include <sys/stat.h>`

int
`chmod`(const char *path, mode_t mode);

int
`lchmod`(const char *path, mode_t mode);

int
`fchmod`(int fd, mode_t mode);

`#include <sys/stat.h>`
`#include <fcntl.h>`

int
`fchmodat`(int fd, const char *path, mode_t mode, int flag);

# DESCRIPTION

The function `chmod`() sets the file permission bits of the file specified by the pathname path to mode. `fchmod`() sets the permission bits of the specified file descriptor fd. `lchmod`() is like `chmod`() except in the case where the named file is a symbolic link, in which case `lchmod`() sets the permission bits of the link, while `chmod`() sets the bits of the file the link references.

`fchmodat`() works the same way as `chmod`() (or `lchmod`() if `AT_SYMLINK_NOFOLLOW` is set in flag) except if path is relative. In that case, it is looked up from a directory whose file descriptor was passed as fd. Search permission is required on this directory. fd except if that file descriptor was opened with the `O_SEARCH` flag. fd can be set to `AT_FDCWD` in order to specify the current directory.

`chmod`() verifies that the process owner (user) either owns the file specified by path (or fd), or is the super-user. A mode is created from or'd permission bit masks defined in `<sys/stat.h>`:

    #define S_IRWXU 0000700    /* RWX mask for owner */
    #define S_IRUSR 0000400    /* R for owner */
    #define S_IWUSR 0000200    /* W for owner */
    #define S_IXUSR 0000100    /* X for owner */

    #define S_IRWXG 0000070    /* RWX mask for group */
    #define S_IRGRP 0000040    /* R for group */
    #define S_IWGRP 0000020    /* W for group */
    #define S_IXGRP 0000010    /* X for group */

    #define S_IRWXO 0000007    /* RWX mask for other */
    #define S_IROTH 0000004    /* R for other */
    #define S_IWOTH 0000002    /* W for other */
    #define S_IXOTH 0000001    /* X for other */

    #define S_ISUID 0004000    /* set user id on execution */
    #define S_ISGID 0002000    /* set group id on execution */
    #define S_ISVTX 0001000    /* sticky bit */

The mode `ISVTX` (the ‘sticky bit’) can be set on regular files, but has no effect. For historical reasons this can be done only by the super-user.

If mode `ISVTX` (the ‘sticky bit’) is set on a directory, an unprivileged user may not delete or rename files of other users in that directory. The sticky bit may be set by any user on a directory which the user owns or has appropriate permissions.

For more information about the history and properties of the sticky bit, see sticky(7).

Changing the owner of a file turns off the set-user-id and set-group-id bits; writing to a file turns off the set-user-id and set-group-id bits unless the user is the super-user. This makes the system somewhat more secure by protecting set-user-id (set-group-id) files from remaining set-user-id (set-group-id) if they are modified, at the expense of a degree of compatibility.

# RETURN VALUES

The `chmod`(), `lchmod`(), `fchmod`(), and `fchmodat`() functions return the value 0 if successful; otherwise the value -1 is returned and the global variable errno is set to indicate the error.

# ERRORS

`chmod`(), `lchmod`() and `fchmodat`() will fail and the file mode will be unchanged if:

[`EACCES`]
  Search permission is denied for a component of the path prefix.
[`EFAULT`]
  path points outside the process's allocated address space.
[`EFTYPE`]
  The effective user ID is not the super-user, the mode includes the sticky bit (`S_ISVTX`), and path does not refer to a directory.
[`EIO`]
  An I/O error occurred while reading from or writing to the file system.
[`ELOOP`]
  Too many symbolic links were encountered in translating the pathname.
[`ENAMETOOLONG`]
  A component of a pathname exceeded {`NAME_MAX`} characters, or an entire path name exceeded {`PATH_MAX`} characters.
[`ENOENT`]
  The named file does not exist.
[`ENOTDIR`]
  A component of the path prefix is not a directory.
[`EPERM`]
  The effective user ID does not match the owner of the file and the effective user ID is not the super-user; or the mode includes the setgid bit (`S_ISGID`) but the file's group is neither the effective group ID nor is it in the group access list.
[`EROFS`]
  The named file resides on a read-only file system.

In addition, `fchmodat`() will fail if:

[`EBADF`]
  path does not specify an absolute path and fd is neither `AT_FDCWD` nor a valid file descriptor open for reading or searching.
[`ENOTDIR`]
  path is not an absolute path and fd is a file descriptor associated with a non-directory file.

`fchmod`() will fail if:

[`EBADF`]
  The descriptor is not valid.
[`EFTYPE`]
  The effective user ID is not the super-user, the mode includes the sticky bit (`S_ISVTX`), and fd does not refer to a directory.
[`EINVAL`]
  fd refers to a socket, not to a file.
[`EIO`]
  An I/O error occurred while reading from or writing to the file system.
[`EPERM`]
  The effective user ID does not match the owner of the file and the effective user ID is not the super-user; or the mode includes the setgid bit (`S_ISGID`) but the file's group is neither the effective group ID nor is it in the group access list.
[`EROFS`]
  The file resides on a read-only file system.

# SEE ALSO

chmod(1), chflags(2), chown(2), open(2), stat(2), getmode(3), setmode(3), sticky(7), symlink(7)

# STANDARDS

The `chmod`() function conforms to IEEE Std 1003.1-1990 (“POSIX.1”). The `fchmod`() function conforms to X/Open Portability Guide Issue 4, Version 2 (“XPG4.2”). The `fchmodat`() function conforms to IEEE Std 1003.1-2008 (“POSIX.1”).

# HISTORY

The `chmod`() function call appeared in Version 1 AT&T UNIX. The `fchmod`() function call appeared in 4.2BSD. The `lchmod`() function call appeared in NetBSD 1.3.

November 20, 2021 | NetBSD 10.0