'how to change access time of a file using utime and mktime syscalls and c++?

I was trying to change the access time of a file, but i didn't get the result i wanted.

this is what i tried:

struct tm time;
    time.tm_sec=56;
    time.tm_min=48;
    time.tm_hour=20;
    time.tm_mday=12;
    time.tm_mon=8;
    time.tm_year=1905;
struct utimbuf utime_par;
utime_par.actime=mktime(&time);
if(utime("file_name",&utime_par)!=0)
    {
    
      perror("smash error: utime failed");
      std::cout<<"entered";
      return;
    }

when I run on linux terminal

ls -l file_name

I get

-rwxrw-rw- 1 student student 3133 Jun 20  4461763 README.txt

Does anyone know what I did wrong?



Solution 1:[1]

According to the documentation of the function utime, struct utimbuf (which you pass to the function utime) is defined in the following way:

struct utimbuf {
    time_t actime;       /* access time */
    time_t modtime;      /* modification time */
};

However, you are only setting the actime field of this struct, which means that the field modtime has an indeterminate value when you pass it to the function utime.

In your case, you probably want to set both fields to the same time value:

utime_par.actime  = mktime( &time );
utime_par.modtime = mktime( &time );

Or, if you don't want to call the function mktime twice (which is a bit inefficient), you can also write:

utime_par.actime  = mktime( &time );
utime_par.modtime = time_par.actime;

Also, as already pointed out in the comments section, the field tm_year in a struct tm should not be the absolute year, but rather the number of years since the year 1900. Therefore, it is probably wrong that you write 1905 into this field, as that corresponds to the year 3805.

Another issue is that you should set the field tm_isdst in the struct tm, to indicate whether daylight savings was in effect. You can simply set this field to a negative value, which will tell mktime that you are not providing this information, and that it should therefore determine this itself. By not setting this field, the value of this field will be indeterminate, which means that you may be providing mktime false information about whether daylight savings was in effect. This could lead to the timestamp on the file being wrong by one hour.

Solution 2:[2]

I think you have successfully updated the access time of your file_name, but you failed to check the result with ls.

I just copy your code, and change the access time of my file successfully.

The problem is:

ls -l file_name

ls shows the mtime — updated when the file contents change. This is the "default" file time in most cases. But I guess you have not changed the file contents of your file

What you should do is:

ls -l --time=atime your-file-name

What does --time mean? You could check its meaning by man ls

       --time=WORD
              change the default of using modification times; access time (-u): atime, access, use; change time (-c): ctime, status; birth time: birth, creation;

              with -l, WORD determines which time to show; with --sort=time, sort by WORD (newest first)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andreas Wenzel
Solution 2