C语言编写 linux 下的 touch 命令

 用C语言实现linux 下 touch 命令的操作:

touch:创建文件或者修改文件或目录的时间戳。

实现效果:

可添加三个参数:

-c : --no-create     do not create any files   不创建不存在的文件

-a :  change only the access time      只修改文件的访问时间

-m : change only the modification time  只修改文件的修改时间

涉及的函数:

1.getopt()函数:解析命令行参数

/*函数原型*/
#include <unistd.h>
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg; 
extern int optind,  // 初始化值为1,下一次调用getopt时,从optind存储的位置重新开始检查选项。 
extern int opterr,  // 初始化值为1,当opterr=0时,getopt不向stderr输出错误信息。
extern int optopt; /*当命令行选项字符不包括在optstring中或者选项缺少必
                     要的参数时,该选项存储在optopt中, getopt返回'?’。*/

2.open()

int open(constchar*pathname, int flags);    
int open(constchar*pathname, int flags, mode_t mode);

作用:打开和创建文件。返回值:成功则返回文件描述符,否则返回 -1。

3.utimensat()

#include <sys/stat.h>
int utimensat(int dirfd, const char *pathname,const struct timespec times[2], intflags);

作用:utimensat 是以纳秒级的精度改变文件的时间戳。utimensat()通过文件的路径(pathname)获得文件。

这个系统调用函数都是通过一个时间数组 times 来改变时间戳的,times[0] 修改最后一次访问的时间(access time),times[1] 修改最后修改的时间 (modify time)。该时间数组是由秒和纳秒两个部分组成,数据结构如下:

struct timespec {
time_t tv_sec; /* 秒 */  
long tv_nsec; /* 纳秒 */
};

times[x].tv_sec = UTIME_OMIT; 相应的时间戳不变,times[x].tv_sec = UTIME_NOW; 相应的时间戳变成当前时间 

#include<fcntl.h>
#include<sys/stat.h>
#include<stdio.h>
#include<getopt.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdbool.h>
#include<sys/time.h>
#include<time.h>

#define CH_ATIME 1
#define CH_MTIME 2

/*定义创建文件时的模式,此处对用户,组,其他设置的权限都是可读可写的*/
#define MODE_RW_UGO (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)

static int change_times;//标志文件access time和modify time 的改变情况
static bool no_creat;  //如果有(-c) 选项,并且不存在命令行中输入的文件名,则不创建 
static struct timespec newtime[2];//当设置新的access time 和 modify time 的时候使用

static bool mytouch(const char *file)
{
	bool ok;
	int fd = -1;
	if(!no_creat)  //如果没有加-c,则在文件不存在的时候创建一个新文件
	{
		fd = open(file,O_CREAT | O_WRONLY,MODE_RW_UGO);
	}
	if(change_times != (CH_ATIME | CH_MTIME))
	{
		if(change_times == CH_MTIME)
		{
			newtime[0].tv_nsec = UTIME_OMIT;
		}
		else
		{
			newtime[1].tv_nsec = UTIME_OMIT;
		}
	}
	ok = (utimensat(AT_FDCWD,file,newtime,0) == 0);
	return false;
}

int main(int argc,char **argv)
{
	int c;
	bool ok = true;
	change_times = 0;
	no_creat = false;
	while((c = getopt(argc,argv,"acm")) != -1)
	{
		switch(c)
		{
			case 'a':
				change_times |= CH_ATIME;
				break;
			case 'c':
				no_creat = true;
				break;
			case 'm':
				change_times |= CH_MTIME;
				break;
			default:
				printf("fault option!\n");
		}
	}
	if(change_times == 0)
	{
		change_times = CH_ATIME | CH_MTIME;
	}
	newtime[0].tv_nsec = UTIME_NOW;
	newtime[1].tv_nsec = UTIME_NOW;
	if(optind == argc)
	{
		printf("misssing file operand\n");
	}
	for(;optind < argc; ++optind)
	{
		ok &= mytouch(argv[optind]);
	}
	exit(ok ? EXIT_SUCCESS : EXIT_FAILURE);

}












  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值