|
The primary interface required to access extended attributes at the programmatic level is the openat(2) function. Once a file descriptor has been obtained for
an attribute file by an openat() call, all normal file system semantics apply. There is no attempt to place special semantics on read(2), write(2), ftruncate(3C),
or other functions when applied to attribute file descriptors relative to "normal" file descriptors.
The set of existing attributes can be browsed by calling openat() with "." as the file name and the O_XATTR flag set, resulting in a file descriptor for the attribute directory. The list of attributes is obtained by calls to getdents(2) on the returned file descriptor. If the target file did not previously have any attributes associated with it, an empty top-level attribute directory is created for the file and subsequent getdents()
calls will return only "." and "..". While the owner of the parent file owns the extended attribute directory, it is not charged against its quota if the directory is empty. Attribute files themselves, however, are charged against the user quota as any other regular file.
Additional system calls have been provided as convenience functions. These include the fchownat(2), fstatat(2), futimesat(2), renameat(2), unlinkat(2). These new functions, along with openat(),
provide a mechanism to access files relative to an arbitrary point in the file system, rather than only the current working directory. This mechanism is particularly useful in situations when a file descriptor is available with no path. The openat() function, in particular, can be
used in many contexts where chdir() or fchdir() is currently required. See chdir(2). Open a file relative to a file descriptor
|
int openat (int fd, const char *path, int oflag [, mode_t mode])
|
The openat(2) function behaves exactly as open(2) except when given a relative path. Where open() resolves a relative path from the current working directory, openat() resolves the path based on the vnode indicated by the supplied file descriptor. When oflag is O_XATTR, openat() interprets the path argument as an extended attribute reference. The following code fragment uses openat() to examine the attributes of some already opened file:
|
dfd = openat(fd, ".", O_RDONLY|O_XATTR);
(void)getdents(dfd, buf, nbytes);
|
If openat() is passed the special value AT_FDCWD as its first (fd) argument, its behavior is identical to open() and the relative path arguments are interpreted relative to the current working directory. If the O_XATTR flag is provided to openat() or to open(), the supplied path is interpreted as a reference to an extended attribute on the current working directory. Unlink a file relative to a directory file descriptor
|
int unlinkat (int dirfd, const char *pathflag, int flagflag)
|
The unlinkat(2) function deletes an entry from a directory. The path argument indicates the name of the entry to remove. If path an absolute path, the dirfd argument is ignored. If it is a relative path, it is interpreted relative to the directory indicated by the dirfd argument. If dirfd does not refer to a valid directory, the function returns ENOTDIR. If the special value AT_FDCWD is specified for dirfd, a relative path argument is resolved relative to the current working directory. If the flag argument is 0, all other semantics of this function are equivalent to unlink(2). If flag is set to AT_REMOVEDIR, all other semantics of this function are equivalent to rmdir(2). Rename a file relative to directories
|
int renameat (int fromfd, const char *old, int tofd, const char *new)
|
The renameat(2) function renames an entry in a directory, possibly moving the entry into a different directory. The old argument indicates
the name of the entry to rename. If this argument is a relative path, it is interpreted relative to the directory indicated by the fd argument. If it is an absolute path, the fromfd argument is ignored. The new argument indicates the
new name for the entry. If this argument is a relative path, it is interpreted relative to the directory indicated by the tofd argument. If it is an absolute path, the tofd argument is ignored.
In the relative path cases, if the directory file descriptor arguments do not refer to a valid directory, the function returns ENOTDIR. All other semantics of this function are equivalent to rename(2).
If a special value AT_FDCWD is specified for either the fromfd or tofd arguments, their associated path arguments (old and new) are interpreted relative to the current working directory
if they are not specified as absolute paths. Any attempt to use renameat() to move a file that is not an extended attribute into an extended attribute directory (so that it becomes an extended attribute) will fail. The same is true for an attempt to move a file that is an extended attribute
into a directory that is not an extended attribute directory. Obtain information about a file
|
int fstatat (int fd, const char *path, struct stat* buf, int flag)
|
The fstatat(2) function obtains information about a file. If the path argument is relative, it is resolved relative to the fd argument file descriptor, otherwise the fd argument is ignored. If the fd argument is a special value AT_FDCWD the path is resolved relative to the current working directory. If the path argument is
a null pointer, the function returns information about the file referenced by the fd argument. In all other relative path cases, if the fd argument does not refer to a valid directory, the function returns ENOTDIR. If the flag argument is set to AT_SYMLINK_NOFOLLOW, the function will not automatically traverse a symbolic link at the position of the path. The fstatat() function is a multi-purpose function that can be used in place of stat(), lstat(), or fstat(). See stat(2).
The function call stat(path, buf) is identical to fstatat(AT_FDCWD, path, buf, 0).
The function call lstat(path, buf) is identical to fstatat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW)
The function call fstat(fildes, buf) is identical to fstatat(fildes, NULL, buf, 0). Set owner and group ID
|
int fchownat (int fd, const char *path, uid_t owner, gid_t group, int flag)
|
The fchownat(2) function sets the owner ID and group ID for a file. If the path argument is relative, it is resolved relative to the fd argument file descriptor, otherwise the fd argument is ignored. If the fd argument is a special value AT_FDCWD the path is resolved relative to the current working directory. If the path argument is a null pointer, the function
sets the owner and group ID of the file referenced by the fd argument. In all other relative path cases, if the fd argument does not refer to a valid directory, the function returns ENOTDIR. If the flag argument
is set to AT_SYMLINK_NOFOLLOW, the function will not automatically traverse a symbolic link at the position of the path. The fchownat() function is a multi-purpose function that can be used in place of chown(), lchown(), or fchown(). See chown(2).
The function call chown(path, owner, group) is equivalent to fchownat(AT_FDCWD, path, owner, group, 0).
The function call lchown(path, owner, group) is equivalent to fchownat(AT_FDCWD, path, owner, group, AT_SYMLINK_NOFOLLOW). Set file access and modification times
|
int futimesat (int fd, const char *path, const struct timeval times[2])
|
The futimesat(2) function sets the access and modification times for a file. If the path argument is relative, it is resolved relative
to the fd argument file descriptor; otherwise the fd argument is ignored. If the fd argument is the special value AT_FDCWD, the path is resolved relative to the current working directory. If the path
argument is a null pointer, the function sets the access and modification times of the file referenced by the fd argument. In all other relative path cases, if the fd argument does not refer to a valid directory, the function returns ENOTDIR.
The futimesat() function can be used in place of utimes(2).
The function call utimes(path, times) is equivalent to futimesat(AT_FDCWD, path, times). New pathconf() functionality
|
long int pathconf(const char *path, int name)
|
Two variables have been added to pathconf(2) to provide enhanced support for extended attribute manipulation. The XATTR_ENABLED variable
allows an application to determine if attribute support is currently enabled for the file in question. The XATTR_EXISTS variable allows an application to determine whether there are any extended attributes associated with the supplied path. Open/Create an attribute file
|
int attropen (const char *path, const char *attrpath, int oflag [, mode_t mode])
|
The attropen(3C) function returns a file descriptor for the named attribute, attrpath, of the file indicated by path.
The oflag and mode arguments are identical to the open(2) arguments and are applied to the open operation on the attribute
file (for example, using the O_CREAT flag creates a new attribute). Once opened, all normal file system operations can be used on the attribute file descriptor. The attropen() function is a convenience function and is equivalent to the following sequence of operations:
|
fd = open (path, O_RDONLY);
attrfd = openat(fd, attrpath, oflag|O_XATTR, mode);
close(fd);
|
The set of existing attributes can be browsed by calling attropen() with "." as the attribute name. The list of attributes is obtained by calling getdents(2) (or fdopendir(3C) followed by readdir(3C), see below) on the returned file descriptor. Convert an open file descriptor for a directory into a directory descriptor
|
DIR * fdopendir (const int fd)
|
The fdopendir(3C) function promotes a file descriptor for a directory to a directory pointer suitable for use with the readdir(3C) function. The originating file descriptor should not be used again following the call to fdopendir(). The directory pointer should be closed with a call to closedir(3C). If the provided file descriptor does not reference a directory, the function returns ENOTDIR. This function is useful in circumstances where the only available handle on a directory is a file
descriptor. See attropen(3C) and openat(2). Using the APIThe following examples demonstrate how the API might be used to perform basic operations on extended attributes: Example 1. List extended attributes on a file.
|
|
attrdirfd = attropen("test", ".", O_RDONLY);
dirp = fdopendir(attrdirfd);
while (dp = readdir(dirp)) {
...
|
|
Example 2. Open an extended attribute.
|
|
attrfd = attropen("test", dp->d_name, O_RDONLY);
|
or
|
attrfd = openat(attrdirfd, dp->d_name, O_RDONLY);
|
|
Example 3. Read from an extended attribute.
|
|
while (read(attrfd, buf, 512) > 0) {
...
|
|
Example 4. Create an extended attribute.
|
|
newfd = attropen("test", "attr", O_CREAT|O_RDWR);
|
or
|
newfd = openat(attrdirfd, "attr", O_CREAT|O_RDWR);
|
|
Example 5. Write to an extended attribute.
|
|
count = write(newfd, buf, length);
|
|
Example 6. Delete an extended attribute.
|
|
error = unlinkat(attrdirfd, "attr");
|
|
Applications intending to access the interfaces defined here as well as the POSIX and X/Open specification-conforming interfaces should define the macro _ATFILE_SOURCE to be 1 and set whichever feature test macros are appropriate to obtain the desired environment. See standards(5).
|