• C语言实现linux下面的touch命令


      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 文件名 //查看文件信息

  • 相关阅读:
    06.django升级打怪学习记
    05.django升级打怪学习记
    04.django升级打怪学习记
    03.django升级打怪学习记
    02.django升级打怪学习记
    python学习手册笔记——39.元类
    python学习手册笔记——35.异常的设计
    关于我
    [Jenkins]Console Output中文显示问号的问题解决
    [Jenkins]JDK版本过高导致的java.io.IOException: Remote call on xxxx failed
  • 原文地址:https://www.cnblogs.com/nanfengnan/p/14190127.html
Copyright © 2020-2023  润新知