288 Chapter 15
(To be accurate, on Linux, it is the process’s file-system user ID, rather than
its effective user ID, that is checked against the file’s user ID, as described in
Section 9.5.)
z If buf is specified as pointer to a utimbuf structure, then the last file access and
modification times are updated using the corresponding fields of this struc-
ture. In this case, the effective user ID of the process must match the file’s user
ID (having write permission on the file is not sufficient) or the caller must be
privileged (CAP_FOWNER).
To change just one of the file timestamps, we first use stat() to retrieve both times,
use one of these times to initialize the utimbuf structure, and then set the other as
desired. This is demonstrated in the following code, which makes the last modifica-
tion time of a file the same as the last access time:
struct stat sb;
struct utimbuf utb;
if (stat(pathname, &sb) == -1)
errExit("stat");
utb.actime = sb.st_atime; /* Leave access time unchanged */
utb.modtime = sb.st_atime;
if (utime(pathname, &utb) == -1)
errExit("utime");
A successful call to utime() always sets the last status change time to the current
time.
Linux also provides the BSD-derived utimes() system call, which performs a sim-
ilar task to utime().
The most notable difference between utime() and utimes() is that utimes() allows
time values to be specified with microsecond accuracy (the timeval structure is
described in Section 10.1). This provides (partial) access to the nanosecond accu-
racy with which file timestamps are provided in Linux 2.6. The new file access time
is specified in tv[0], and the new modification time is specified in tv[1].
An example of the use of utimes() is provided in the file files/t_utimes.c in the
source code distribution for this book.
The futimes() and lutimes() library functions perform a similar task to utimes(). They
differ from utimes() in the argument used to specify the file whose timestamps are
to be changed.
#include <sys/time.h>
int utimes(const char *pathname, const struct timeval tv[2]);
Returns 0 on success, or –1 on error