fchmodat()

Updated: April 19, 2023

Change the permissions for a file at a given location

Synopsis:

#include <sys/stat.h>

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

Arguments:

fd
A file descriptor that indicates the base directory for relative file paths. The pathname given in path is resolved by appending it to the directory associated with fd. You can set this argument to AT_FDCWD to use the current working directory as the base directory.
Note: You must use a file descriptor obtained from an open() call with the O_DIRECTORY flag set. Otherwise, the function fails and sets errno to ENOTDIR.

If path specifies an absolute path, fd has no effect.

path
The pathname of the file whose permissions you want to change. This can be absolute or relative; for details of how relative pathname resolution is done, see above.
mode
The new permissions for the file. For more information, see the entry for struct stat.
flags
A bitfield of the following flags:
  • AT_SYMLINK_NOFOLLOW — if path names a symbolic link, change the mode of the symbolic link instead of the mode of the file.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The fchmodat() function sets the S_ISUID, S_ISGID, and S_ISVTX bits and updates the permission bits to mode for the file specified by path. The path argument can contain an absolute or relative path. In the latter case, the fd argument is used to resolve the pathname, as explained in this argument's description (above).

If the access mode of the open file description associated with the fd file descriptor is not O_SEARCH, the function checks if directory searches are permitted using the current permissions of the directory underlying the file descriptor. If the access mode is O_SEARCH, the function doesn't perform the check.

When the flags field is 0, this function is equivalent to chmod() when fd is AT_FDCWD. For details about other possible flags settings, see this argument's description (above).

QNX Neutrino has no concept of a path operation (open(), readlink(), etc.) that references a path relative to an already open file descriptor (for a directory), as far as the filesystem resource manager is concerned. Therefore, it's not possible to eliminate the race inherent in looking up a pathname with multiple intervening directories or symbolic links. However, fchmodat() can still be used for maintaining a per-thread current working directory, using file descriptors maintained by the application.

To ensure that the S_ISUID and S_ISGID bits are set, an application should call stat() after a successful fchmodat() call to verify this. Any file descriptors currently open by any process on the file could become invalid if the file's mode is changed to a value that would deny access to that process. This can occur on a stateless file system, but won't occur in a conforming environment.

Returns:

0
Success.
-1
An error occurred (errno is set).

Errors:

EACCES
Search permission is denied on a component of the path prefix, or the access mode of the directory associated with fd is not O_SEARCH and the underlying directory doesn't permit searching.
EBADF
The path argument does not specify an absolute path and the fd argument is neither AT_FDCWD nor a valid file descriptor open for reading or searching.
EINTR
A signal interrupted the operation.
EINVAL
An invalid value was specified for mode or flags.
ELOOP
During resolution of the path argument, a loop was found in the symbolic links or more than SYMLOOP_MAX symbolic links were encountered.
ENAMETOOLONG
The length of a pathname component in path exceeds NAME_MAX, the length of the entire pathname exceeds PATH_MAX, or the path component generated from a symbolic link resolution has a length exceeding PATH_MAX.
ENOENT
A component of the specified path doesn't name an existing file, or path is an empty string.
ENOTDIR
One of the following conditions is true:
  • A component of the path prefix names an existing file that is neither a directory nor a symbolic link to one.
  • The path argument contains at least one non-slash character, ends with at least one slash character (/), and the last component names an existing file that is neither a directory nor a symbolic link to one.
  • The path argument is not an absolute path and fd is associated with a non-directory file.
  • The file descriptor in fd was created without O_DIRECTORY set.
EOPNOTSUPP
The AT_SYMLINK_NOFOLLOW bit is set in the flag argument, path names a symbolic link, and the system does not support changing the mode of a symbolic link.
EPERM
The effective user ID doesn't match the file's owner and the process doesn't have appropriate privileges.
EROFS
The named file resides on a read-only filesystem.

Classification:

POSIX 2008

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes