At struct stat, it maintains 3 time fields:
st_atime: lass-access time of file data, like read system call. Note: this is not the last access time of i-node information, like "stat" or "lstat" system call. Unix doesn't maintain the last access time of i-node information.
st_mtime: last-modification time of file data, like "write" system call.
st_ctime: last-change time of i-node status, like "chmod" "chown" system call.
Get above 3 times:
1) List 3 times of io.out
2) Change the permission of io.out
3) List 3 times again, and it changed "last-change" status time since it is related with i-node informatoin.
4) Run the io.out which needs reading its binary content.
5) List 3 times again, and it changed the "last-access" file content time since running needs reading all file content from disk data block.
ubuntu@ip-172-31-23-227:~$ stat io.out
File: ‘io.out’
Size: 9889 Blocks: 24 IO Block: 4096 regular file
Device: ca01h/51713d Inode: 271668 Links: 1
Access: (0775/-rwxrwxr-x) Uid: ( 1000/ ubuntu) Gid: ( 1000/ ubuntu)
Access: 2014-08-24 14:08:00.874584999 +0000
Modify: 2014-08-24 14:07:51.946584999 +0000
Change: 2014-08-24 14:07:51.946584999 +0000
Birth: -
ubuntu@ip-172-31-23-227:~$ chmod o-r io.out
ubuntu@ip-172-31-23-227:~$ stat io.out
File: ‘io.out’
Size: 9889 Blocks: 24 IO Block: 4096 regular file
Device: ca01h/51713d Inode: 271668 Links: 1
Access: (0771/-rwxrwx--x) Uid: ( 1000/ ubuntu) Gid: ( 1000/ ubuntu)
Access: 2014-08-24 14:08:00.874584999 +0000
Modify: 2014-08-24 14:07:51.946584999 +0000
Change: 2014-08-24 14:30:05.522584999 +0000
Birth: -
ubuntu@ip-172-31-23-227:~$ ./io.out
symlink error!
ubuntu@ip-172-31-23-227:~$ stat io.out
File: ‘io.out’
Size: 9889 Blocks: 24 IO Block: 4096 regular file
Device: ca01h/51713d Inode: 271668 Links: 1
Access: (0771/-rwxrwx--x) Uid: ( 1000/ ubuntu) Gid: ( 1000/ ubuntu)
Access: 2014-08-24 14:30:57.770584999 +0000
Modify: 2014-08-24 14:07:51.946584999 +0000
Change: 2014-08-24 14:30:05.522584999 +0000
Birth: -
ls command:
1) List 3 times of fileio.c
2) By default, ls command will use last-modification time
3) -u option will make ls command use last-access time
4) -c option will make ls command use last-change status time.
ubuntu@ip-172-31-23-227:~$ stat fileio.c
File: ‘fileio.c’
Size: 352 Blocks: 8 IO Block: 4096 regular file
Device: ca01h/51713d Inode: 271669 Links: 1
Access: (0660/-rw-rw----) Uid: ( 1000/ ubuntu) Gid: ( 1000/ ubuntu)
Access: 2014-08-24 14:40:08.966584999 +0000
Modify: 2014-08-24 14:07:42.226584999 +0000
Change: 2014-08-24 14:36:00.002584999 +0000
Birth: -
ubuntu@ip-172-31-23-227:~$ ls -l fileio.c
-rw-rw---- 1 ubuntu ubuntu 352 Aug 24 14:07 fileio.c
ubuntu@ip-172-31-23-227:~$ ls -lu fileio.c
-rw-rw---- 1 ubuntu ubuntu 352 Aug 24 14:40 fileio.c
ubuntu@ip-172-31-23-227:~$ ls -lc fileio.c
-rw-rw---- 1 ubuntu ubuntu 352 Aug 24 14:36 fileio.c
2. Change the file times
We can use system utime to change the file time by ourselves.
Definition:
ubuntu@ip-172-31-23-227:~$ less /usr/include/utime.h
......
/* Structure describing file times. */
struct utimbuf
{
__time_t actime; /* Access time. */
__time_t modtime; /* Modification time. */
};
/* Set the access and modification times of FILE to those given in
*FILE_TIMES. If FILE_TIMES is NULL, set them to the current time. */
extern int utime (const char *__file,
const struct utimbuf *__file_times)
__THROW __nonnull ((1));
......
fileio.c:
#include<stdio.h>
#include<stdlib.h>
#include<utime.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
int main(int argc, char* argv[])
{
int fd;
struct stat buff;
struct utimbuf tbf;
// Fetch the existing time on argv[1] file
if(lstat(argv[1], &buff) < 0) {
printf("lstat error!\n");
exit(1);
}
tbf.actime = buff.st_atime;
tbf.modtime = buff.st_mtime;
// Truncate the argv[1] file to change the
// last-access time and last-modification time
// to the current time.
if(open(argv[1], O_RDWR | O_TRUNC) < 0) {
printf("open error!\n");
exit(2);
}
// Change the lass access time and last modification
// time back to original time
if(utime(argv[1], &tbf) < 0) {
printf("utime error!\n");
exit(3);
}
exit(0);
}
shell:
1) List 3 times of t1
2) Run date command to know the current time: 14:59:26
3) Run the program against t1, it truncated file t1, which is supposed to change the last access time and the last modification time to 14:59:26(current time), but it used utime to change time back, so both of time should be still: 14:55:42
4) List 3 times of t1, both last access time and last modification time don't change. But last-change status time get changed to current time: 14:59:31, this is because, "utime" system call will automatically update the "last-change-status time", since it changes the i-node information. This is also why "struct utimbuf" only contains last-access time and last-modification time.
ubuntu@ip-172-31-23-227:~$ stat t1
File: ‘t1’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: ca01h/51713d Inode: 271668 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ ubuntu) Gid: ( 1000/ ubuntu)
Access: 2014-08-24 14:55:42.150584999 +0000
Modify: 2014-08-24 14:55:42.150584999 +0000
Change: 2014-08-24 14:55:42.150584999 +0000
Birth: -
ubuntu@ip-172-31-23-227:~$ date
Sun Aug 24 14:59:26 UTC 2014
ubuntu@ip-172-31-23-227:~$ ./io.out t1
ubuntu@ip-172-31-23-227:~$ stat t1
File: ‘t1’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: ca01h/51713d Inode: 271668 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ ubuntu) Gid: ( 1000/ ubuntu)
Access: 2014-08-24 14:55:42.000000000 +0000
Modify: 2014-08-24 14:55:42.000000000 +0000
Change: 2014-08-24 14:59:31.462584999 +0000
Birth: -
Note: Use "utime" system call to change the time of file needs the process's effective user id be owner of file or super user.
If "struct utimebuf" is null-pointer when calling the "utime" system call, it will setup both time to be current time, this needs process's effective user id be owner of file or must have write permission.
No comments:
Post a Comment