summaryrefslogtreecommitdiffstats
path: root/man2/utimensat.2
diff options
context:
space:
mode:
Diffstat (limited to 'man2/utimensat.2')
-rw-r--r--man2/utimensat.2613
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)