clinuxlibc

How to change only one of last (change | modification | access ) times in linux (UNIX)?


In some previous days, I searched and asked some questions about a file different timestamps.

Now I know I can get creation time by statx(2) and change only one of last (status change | modification | access) time of a file without changing other times, by touch -m and debugfs command/utilities.

I want to know how I can change each last (status change | modification | access) time without changing other times only by system call not by any command/utility. If it is not possible, how these command/utilities do that?

I know Criticism of atime.


Solution

  • The POSIX function for the job is futimens() and its close relative futimensat():

    #include <sys/stat.h>
    
    int futimens(int fd, const struct timespec times[2]);
    

    In particular, these support the special time value UTIME_OMIT to indicate "do not change this time field".

    These functions use the struct timespec which has the tv_nsec field to record nanoseconds. There's an older but probably more widely available function, utimes(), which uses struct timeval values, and those provide tv_usec to record microseconds.

    These functions allow you to set the access time (a-time) and modification time (m-time); they do not allow you to set the 'status change' time (c-time). There is no simple way to set the c-time — it is automatically updated to the current time by the file system. See Setting creation or change timestamps on Stack Overflow for a discussion of possibilities. Setting the system time, changing the file, and resetting the system time is an appalling "solution" if the system has multiple users using it — it isn't a very appealing "solution" even if you're the only person using the machine.