I am making a program to copy files from a source to a destination directory and would like to change the destination file timestamps so they match the source file timestamps.
So far I have discovered the utime() function and have manipulated the utimbuf struct with the times I would like to use.
However, the times do not take into account the nanoseconds.
For example:
If I want to copy "file1" and it has a timestamp of 123.213241, my copy will have 123.000000 when running my current program. I would like to include the nanoseconds .213241 etc.
Here is my code so far:
struct stat buf;
struct utimbuf time;
stat(filename, &buf) // get metadata of file "filename" and then store in buf
time.actime = buf.st_atim.tv_sec; // set times in time struct
time.modtime = buf.st_mtim.tv_sec;
utime(filename_copy, &time); // load file copy with time struct
How can I include nanoseconds in my file timestamps?
CodePudding user response:
According to POSIX, the function you need is utimensat() (or its close relative, futimens()). Both of these take a pair of struct timespec values in an array, which allows you to specify a time to nanoseconds. The first element is the access time; the second is the modification time.
Not all file systems support nanosecond timestamps. Not all systems actually support nanosecond resolution — for example, macOS only works to microseconds, even if you specify nanoseconds.
Note that modern versions of the stat() function return a structure with elements st_atim, st_ctim, and st_mtim. These are also struct timespec values. The <sys/stat.h> defines some backwards-compatibility macros:
For compatibility with earlier versions of this standard, the
st_atimemacro shall be defined with the valuest_atim.tv_sec. Similarly,st_ctimeandst_mtimeshall be defined as macros with the valuesst_ctim.tv_secandst_mtim.tv_sec, respectively.
For Linux, see utimensat(2). However, the documentation for stat(2) only mentions subsecond times in the Notes section near the bottom. Be cautious.
CodePudding user response:
Try adding a print statement with time=%ld.ld and see if that stops the truncating.
