1 //源码地址:wget http://labfile.oss.aliyuncs.com/courses/572/mytouch.c
2
3 #include <stdio.h>
4 #include <getopt.h>
5 #include <sys/types.h>
6 #include <time.h>
7 #include <fcntl.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <stdbool.h>
11 #include <sys/time.h>
12 #include <sys/stat.h>
13
14 //定义参数 CH_ATIME访问时间 CH_MTIME是修改时间
15 #define CH_ATIME 1
16 #define CH_MTIME 2
17
18 //定义创建文件时的模式,此处对用户,组,其他人设置的权限都是可读可写的
19 //因为linux中文件默认没有x权限
20 #define MODE_RW_UGO (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
21 //标志文件access time 和 modify time 的改变情况
22
23 static int change_times;
24 //如果有-c选项,并且不存在命令行中输入的文件名,则不创建
25
26 static bool no_create;
27 //当设置新的access time 和 modify time的时候使用
28
29 static struct timespec newtime[2];
30 //mytouch命令核心的核心模块,用于创建或者更新文件的时间戳
31
32 int main(int argc, char const *argv[])
33 {
34 int c;
35 bool ok = true; //初始化 ok,change_times,no_create:
36 change_times = 0;
37 no_create = false;
38
39 //从命令行中得到命令的选项,即以'-'开头的参数.目前只支持-a,-c,-m。
40 while((c = getopt(argc,argv,"acm")) != -1)
41 {
42 switch(c)
43 {
44 case 'a':
45 change_times |= CH_ATIME;
46 break;
47 case 'c':
48 no_create = true;
49 break;
50 case 'm':
51 change_times |= CH_MTIME;
52 break;
53 default:
54 printf("fault option!");
55 }
56 }
57
58 if (change_times == 0)
59 {
60 change_times = CH_ATIME | CH_MTIME;
61 }
62
63 //当newtime[0],
64 newtime[0].tv_nsec = UTIME_NOW;
65 newtime[1].tv_nsec = UTIME_NOW;
66
67 //如果optind == argc ,代表少输入文件名字.
68 if(optind == argc)
69 {
70 printf("missing file operand
");
71 }
72
73 //针对多个文件名字调用mytouch函数
74 for(;optind < argc ; ++optind)
75 ok &= mytouch(argv[optind]);
76
77 exit(ok ? EXIT_SUCCESS: EXIT_FAILURE); //使用一个条件表达式
78 }
79
80 static bool
81 mytouch(const char *file)
82 {
83 bool ok;
84 int fd = -1;
85 if (!no_create)
86 {
87 fd = open(file, O_CREAT | O_WRONLY, MODE_RW_UGO);
88 }
89 //在主函数中,如果没有检测到(-a)(-m),则change_times == (CH_ATIME | CH_MTIME),
90 否则按照选项只用改变其中一个时间戳。
91 if (change_times != (CH_ATIME | CH_MTIME))
92 {
93 //只设定其中一个时间值。
94 if (change_times == CH_MTIME)
95 //如果change_times == CH_MTIME,即(-m),将对应的修改access time
96 的timespec结构的tv_nsec设置为UTIME_OMIT;参考utimensat函数的用法
97 newtime[0].tv_nsec = UTIME_OMIT;
98 else
99 //如果change_times == CH_MTIME,即(-a),将对应的修改modify time
100 的timespec结构的tv_nsec设置为UTIME_OMIT;参考utimensat函数的用法
101 newtime[1].tv_nsec = UTIME_OMIT;
102 }
103 //AT_FDCWD表示当前工作目录。
104 ok = (utimensat(AT_FDCWD, file, newtime, 0) == 0);
105 return true;
106 }
gcc -o mytouch mytouch.c
执行:./mytouch
-c 不创建文件
-m 只修改更改时间
-a 只修改访问时间
读者可以参考,touch命令自行修改代码
stat 文件名 //查看文件信息