diff options
Diffstat (limited to 'man2/utimensat.2')
-rw-r--r-- | man2/utimensat.2 | 613 |
1 files changed, 613 insertions, 0 deletions
diff --git a/man2/utimensat.2 b/man2/utimensat.2 new file mode 100644 index 0000000..77456fc --- /dev/null +++ b/man2/utimensat.2 @@ -0,0 +1,613 @@ +'\" t +.\" Copyright (C) 2008, Linux Foundation, written by Michael Kerrisk +.\" <mtk.manpages@gmail.com> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.TH utimensat 2 2023-07-20 "Linux man-pages 6.05.01" +.SH NAME +utimensat, futimens \- change file timestamps with nanosecond precision +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.BR "#include <fcntl.h>" " /* Definition of " AT_* " constants */" +.B #include <sys/stat.h> +.PP +.BI "int utimensat(int " dirfd ", const char *" pathname , +.BI " const struct timespec " times "[_Nullable 2], int " flags ); +.BI "int futimens(int " fd ", const struct timespec " times "[_Nullable 2]);" +.fi +.PP +.RS -4 +Feature Test Macro Requirements for glibc (see +.BR feature_test_macros (7)): +.RE +.PP +.BR utimensat (): +.nf + Since glibc 2.10: + _POSIX_C_SOURCE >= 200809L + Before glibc 2.10: + _ATFILE_SOURCE +.fi +.PP +.BR futimens (): +.nf + Since glibc 2.10: + _POSIX_C_SOURCE >= 200809L + Before glibc 2.10: + _GNU_SOURCE +.fi +.SH DESCRIPTION +.BR utimensat () +and +.BR futimens () +update the timestamps of a file with nanosecond precision. +This contrasts with the historical +.BR utime (2) +and +.BR utimes (2), +which permit only second and microsecond precision, respectively, +when setting file timestamps. +.PP +With +.BR utimensat () +the file is specified via the pathname given in +.IR pathname . +With +.BR futimens () +the file whose timestamps are to be updated is specified via +an open file descriptor, +.IR fd . +.PP +For both calls, the new file timestamps are specified in the array +.IR times : +.I times[0] +specifies the new "last access time" (\fIatime\fP); +.I times[1] +specifies the new "last modification time" (\fImtime\fP). +Each of the elements of +.I times +specifies a time as the number of seconds and nanoseconds +since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). +This information is conveyed in a +.BR timespec (3) +structure. +.PP +Updated file timestamps are set to the greatest value +supported by the filesystem that is not greater than the specified time. +.PP +If the +.I tv_nsec +field of one of the +.I timespec +structures has the special value +.BR UTIME_NOW , +then the corresponding file timestamp is set to the current time. +If the +.I tv_nsec +field of one of the +.I timespec +structures has the special value +.BR UTIME_OMIT , +then the corresponding file timestamp is left unchanged. +In both of these cases, the value of the corresponding +.I tv_sec +.\" 2.6.22 was broken: it is not ignored +field is ignored. +.PP +If +.I times +is NULL, then both timestamps are set to the current time. +.\" +.PP +The status change time (ctime) will be set to the current time, even if the +other time stamps don't actually change. +.SS Permissions requirements +To set both file timestamps to the current time (i.e., +.I times +is NULL, or both +.I tv_nsec +fields specify +.BR UTIME_NOW ), +either: +.IP \[bu] 3 +the caller must have write access to the file; +.\" 2.6.22 was broken here -- for futimens() the check is +.\" based on whether or not the file descriptor is writable, +.\" not on whether the caller's effective UID has write +.\" permission for the file referred to by the descriptor. +.IP \[bu] +the caller's effective user ID must match the owner of the file; or +.IP \[bu] +the caller must have appropriate privileges. +.PP +To make any change other than setting both timestamps to the +current time (i.e., +.I times +is not NULL, and neither +.I tv_nsec +field is +.B UTIME_NOW +.\" 2.6.22 was broken here: +.\" both must be something other than *either* UTIME_OMIT *or* UTIME_NOW. +and neither +.I tv_nsec +field is +.BR UTIME_OMIT ), +either condition 2 or 3 above must apply. +.PP +If both +.I tv_nsec +fields are specified as +.BR UTIME_OMIT , +then no file ownership or permission checks are performed, +and the file timestamps are not modified, +but other error conditions may still be detected. +.\" +.\" +.SS utimensat() specifics +If +.I pathname +is relative, then by default it is interpreted relative to the +directory referred to by the open file descriptor, +.I dirfd +(rather than relative to the current working directory of +the calling process, as is done by +.BR utimes (2) +for a relative pathname). +See +.BR openat (2) +for an explanation of why this can be useful. +.PP +If +.I pathname +is relative and +.I dirfd +is the special value +.BR AT_FDCWD , +then +.I pathname +is interpreted relative to the current working +directory of the calling process (like +.BR utimes (2)). +.PP +If +.I pathname +is absolute, then +.I dirfd +is ignored. +.PP +The +.I flags +field is a bit mask that may be 0, or include the following constant, +defined in +.IR <fcntl.h> : +.TP +.B AT_SYMLINK_NOFOLLOW +If +.I pathname +specifies a symbolic link, then update the timestamps of the link, +rather than the file to which it refers. +.SH RETURN VALUE +On success, +.BR utimensat () +and +.BR futimens () +return 0. +On error, \-1 is returned and +.I errno +is set to indicate the error. +.SH ERRORS +.TP +.B EACCES +.I times +is NULL, +or both +.I tv_nsec +values are +.BR UTIME_NOW , +and the effective user ID of the caller does not match +the owner of the file, +the caller does not have write access to the file, +and the caller is not privileged +(Linux: does not have either the +.B CAP_FOWNER +or the +.B CAP_DAC_OVERRIDE +capability). +.\" But Linux 2.6.22 was broken here. +.\" Traditionally, utime()/utimes() gives the error EACCES for the case +.\" where the timestamp pointer argument is NULL (i.e., set both timestamps +.\" to the current time), and the file is owned by a user other than the +.\" effective UID of the caller, and the file is not writable by the +.\" effective UID of the program. utimensat() also gives this error in the +.\" same case. However, in the same circumstances, when utimensat() is +.\" given a 'times' array in which both tv_nsec fields are UTIME_NOW, which +.\" provides equivalent functionality to specifying 'times' as NULL, the +.\" call succeeds. It should fail with the error EACCES in this case. +.\" +.\" POSIX.1-2008 has the following: +.\" .TP +.\" .B EACCES +.\" .RB ( utimensat ()) +.\" .I fd +.\" was not opened with +.\" .B O_SEARCH +.\" and the permissions of the directory to which +.\" .I fd +.\" refers do not allow searches. +.\" EXT2_IMMUTABLE_FL and similar flags for other filesystems. +.TP +.B EBADF +.RB ( futimens ()) +.I fd +is not a valid file descriptor. +.TP +.B EBADF +.RB ( utimensat ()) +.I pathname +is relative but +.I dirfd +is neither +.B AT_FDCWD +nor a valid file descriptor. +.TP +.B EFAULT +.I times +pointed to an invalid address; or, +.I dirfd +was +.BR AT_FDCWD , +and +.I pathname +is NULL or an invalid address. +.TP +.B EINVAL +Invalid value in +.IR flags . +.TP +.B EINVAL +Invalid value in one of the +.I tv_nsec +fields (value outside range [0, 999,999,999], and not +.B UTIME_NOW +or +.BR UTIME_OMIT ); +or an invalid value in one of the +.I tv_sec +fields. +.TP +.B EINVAL +.\" SUSv4 does not specify this error. +.I pathname +is NULL, +.I dirfd +is not +.BR AT_FDCWD , +and +.I flags +contains +.BR AT_SYMLINK_NOFOLLOW . +.TP +.B ELOOP +.RB ( utimensat ()) +Too many symbolic links were encountered in resolving +.IR pathname . +.TP +.B ENAMETOOLONG +.RB ( utimensat ()) +.I pathname +is too long. +.TP +.B ENOENT +.RB ( utimensat ()) +A component of +.I pathname +does not refer to an existing directory or file, +or +.I pathname +is an empty string. +.TP +.B ENOTDIR +.RB ( utimensat ()) +.I pathname +is a relative pathname, but +.I dirfd +is neither +.B AT_FDCWD +nor a file descriptor referring to a directory; +or, one of the prefix components of +.I pathname +is not a directory. +.TP +.B EPERM +The caller attempted to change one or both timestamps to a value +other than the current time, +or to change one of the timestamps to the current time while +leaving the other timestamp unchanged, +(i.e., +.I times +is not NULL, neither +.I tv_nsec +field is +.BR UTIME_NOW , +and neither +.I tv_nsec +field is +.BR UTIME_OMIT ) +and either: +.RS +.IP \[bu] 3 +the caller's effective user ID does not match the owner of file, +and the caller is not privileged +(Linux: does not have the +.B CAP_FOWNER +capability); or, +.IP \[bu] +.\" Linux 2.6.22 was broken here: +.\" it was not consistent with the old utimes() implementation, +.\" since the case when both tv_nsec fields are UTIME_NOW, was not +.\" treated like the (times == NULL) case. +the file is marked append-only or immutable (see +.BR chattr (1)). +.\" EXT2_IMMUTABLE_FL EXT_APPEND_FL and similar flags for +.\" other filesystems. +.\" +.\" Why the inconsistency (which is described under NOTES) between +.\" EACCES and EPERM, where only EPERM tests for append-only. +.\" (This was also so for the older utimes() implementation.) +.RE +.TP +.B EROFS +The file is on a read-only filesystem. +.TP +.B ESRCH +.RB ( utimensat ()) +Search permission is denied for one of the prefix components of +.IR pathname . +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lbx lb lb +l l l. +Interface Attribute Value +T{ +.na +.nh +.BR utimensat (), +.BR futimens () +T} Thread safety MT-Safe +.TE +.sp 1 +.SH VERSIONS +.SS C library/kernel ABI differences +On Linux, +.BR futimens () +is a library function implemented on top of the +.BR utimensat () +system call. +To support this, the Linux +.BR utimensat () +system call implements a nonstandard feature: if +.I pathname +is NULL, then the call modifies the timestamps of +the file referred to by the file descriptor +.I dirfd +(which may refer to any type of file). +Using this feature, the call +.I "futimens(fd,\ times)" +is implemented as: +.PP +.in +4n +.EX +utimensat(fd, NULL, times, 0); +.EE +.in +.PP +Note, however, that the glibc wrapper for +.BR utimensat () +disallows passing NULL as the value for +.IR pathname : +the wrapper function returns the error +.B EINVAL +in this case. +.SH STANDARDS +POSIX.1-2008. +.SH VERSIONS +.TP +.BR utimensat () +Linux 2.6.22, +glibc 2.6. +POSIX.1-2008. +.TP +.BR futimens () +glibc 2.6. +POSIX.1-2008. +.SH NOTES +.BR utimensat () +obsoletes +.BR futimesat (2). +.PP +On Linux, timestamps cannot be changed for a file marked immutable, +and the only change permitted for files marked append-only is to +set the timestamps to the current time. +(This is consistent with the historical behavior of +.BR utime (2) +and +.BR utimes (2) +on Linux.) +.PP +If both +.I tv_nsec +fields are specified as +.BR UTIME_OMIT , +then the Linux implementation of +.BR utimensat () +succeeds even if the file referred to by +.I dirfd +and +.I pathname +does not exist. +.SH BUGS +Several bugs afflict +.BR utimensat () +and +.BR futimens () +before Linux 2.6.26. +These bugs are either nonconformances with the POSIX.1 draft specification +or inconsistencies with historical Linux behavior. +.IP \[bu] 3 +POSIX.1 specifies that if one of the +.I tv_nsec +fields has the value +.B UTIME_NOW +or +.BR UTIME_OMIT , +then the value of the corresponding +.I tv_sec +field should be ignored. +Instead, the value of the +.I tv_sec +field is required to be 0 (or the error +.B EINVAL +results). +.IP \[bu] +Various bugs mean that for the purposes of permission checking, +the case where both +.I tv_nsec +fields are set to +.B UTIME_NOW +isn't always treated the same as specifying +.I times +as NULL, +and the case where one +.I tv_nsec +value is +.B UTIME_NOW +and the other is +.B UTIME_OMIT +isn't treated the same as specifying +.I times +as a pointer to an array of structures containing arbitrary time values. +As a result, in some cases: +a) file timestamps can be updated by a process that shouldn't have +permission to perform updates; +b) file timestamps can't be updated by a process that should have +permission to perform updates; and +c) the wrong +.I errno +value is returned in case of an error. +.\" Below, the long description of the errors from the previous bullet +.\" point (abridged because it's too much detail for a man page). +.\" .IP * +.\" If one of the +.\" .I tv_nsec +.\" fields is +.\" .BR UTIME_OMIT +.\" and the other is +.\" .BR UTIME_NOW , +.\" then the error +.\" .B EPERM +.\" should occur if the process's effective user ID does not match +.\" the file owner and the process is not privileged. +.\" Instead, the call successfully changes one of the timestamps. +.\" .IP * +.\" If file is not writable by the effective user ID of the process and +.\" the process's effective user ID does not match the file owner and +.\" the process is not privileged, +.\" and +.\" .I times +.\" is NULL, then the error +.\" .B EACCES +.\" results. +.\" This error should also occur if +.\" .I times +.\" points to an array of structures in which both +.\" .I tv_nsec +.\" fields are +.\" .BR UTIME_NOW . +.\" Instead the call succeeds. +.\" .IP * +.\" If a file is marked as append-only (see +.\" .BR chattr (1)), +.\" then Linux traditionally +.\" (i.e., +.\" .BR utime (2), +.\" .BR utimes (2)), +.\" permits a NULL +.\" .I times +.\" argument to be used in order to update both timestamps to the current time. +.\" For consistency, +.\" .BR utimensat () +.\" and +.\" .BR futimens () +.\" should also produce the same result when given a +.\" .I times +.\" argument that points to an array of structures in which both +.\" .I tv_nsec +.\" fields are +.\" .BR UTIME_NOW . +.\" Instead, the call fails with the error +.\" .BR EPERM . +.\" .IP * +.\" If a file is marked as immutable (see +.\" .BR chattr (1)), +.\" then Linux traditionally +.\" (i.e., +.\" .BR utime (2), +.\" .BR utimes (2)), +.\" gives an +.\" .B EACCES +.\" error if +.\" .I times +.\" is NULL. +.\" For consistency, +.\" .BR utimensat () +.\" and +.\" .BR futimens () +.\" should also produce the same result when given a +.\" .I times +.\" that points to an array of structures in which both +.\" .I tv_nsec +.\" fields are +.\" .BR UTIME_NOW . +.\" Instead, the call fails with the error +.\" .BR EPERM . +.IP \[bu] +POSIX.1 says that a process that has \fIwrite access to the file\fP +can make a call with +.I times +as NULL, or with +.I times +pointing to an array of structures in which both +.I tv_nsec +fields are +.BR UTIME_NOW , +in order to update both timestamps to the current time. +However, +.BR futimens () +instead checks whether the +.IR "access mode of the file descriptor allows writing" . +.\" This means that a process with a file descriptor that allows +.\" writing could change the timestamps of a file for which it +.\" does not have write permission; +.\" conversely, a process with a read-only file descriptor won't +.\" be able to update the timestamps of a file, +.\" even if it has write permission on the file. +.SH SEE ALSO +.BR chattr (1), +.BR touch (1), +.BR futimesat (2), +.BR openat (2), +.BR stat (2), +.BR utimes (2), +.BR futimes (3), +.BR timespec (3), +.BR inode (7), +.BR path_resolution (7), +.BR symlink (7) |