电子科技大学《linux操作系统编程》实验2:https://www.icourse163.org/learn/UESTC-1003040002?tid=1206878228#/learn/content?type=detail&id=1211971805&cid=1215051733

实现效果:

  • 上述两个
  • 命令参数缺失给出错误提示信息
  • 源文件为目录时给出错误提示信息
  • 目的文件为目录时将源文件在目的目录中复制一份(默认同名)
  • 目的文件已经存在时提供追写/重写选项

实现代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
//#define printError printf("%s\n", strerror(errno)), exit(1);
#define printError(s)  perror(s), exit(1);
extern int errno;
int max(int a, int b) {return a>=b ? a : b;}
bool isDirectory(char* path)
{
	struct stat ss;
	stat(path, &ss);
	return S_ISDIR(ss.st_mode) ? true : false;
}
int fd_src, fd_tar;//源文件描述符,目标文件描述符
char src[500], tar[500];//源文件路径,目标文件路径
char *buf;//读取源文件内容
char op[30];//目标文件存在时,覆盖还是追加
int src_path_len, tar_path_len, buf_len;//源文件路径/目标文件路径/读取的内容长度
int src_length;//源文件内容大小
int main(int argc, char *argv[])
{
	//源文件路径和目标文件路径缺失
	if(argc==1) printf("ERROR:If you want to implement the cp command function, please input the source and target path!\n");
	//目标文件路径缺失
	else if(argc==2) printf("ERROR:Please input the target path!\n");
	else
	{
		strcat(src, argv[1]);
		strcat(tar, argv[2]);

		if(isDirectory(src))//源路径是目录 报错
		{
			printf("ERROR:The source file cannot be a directory!\n");
			exit(-1);
		}

		if((fd_src=open(src, O_RDWR))==-1) printError(src);//源文件不存在或打开失败
		if((src_length=lseek(fd_src, 0, SEEK_END))==-1) printError(src);//lseek读取源文件大小失败
		lseek(fd_src, 0, SEEK_SET);//源文件定位到文件首,以便下面进行read
		buf = (char*)malloc(sizeof(char)*src_length*10);//动态分配内存,存储源文件内容
		if(read(fd_src, buf, max(0, src_length-1))==-1) printError(src);//源文件读取内容失败
		buf[strlen(buf)] = '\n';

		if(isDirectory(tar))//目标文件是目录,处理出新的目标路径(默认复制后的文件和源文件同名)
		{
			src_path_len = strlen(src); 
			tar_path_len = strlen(tar);
			int pos = 0;
			for(int i = 0; i < src_path_len; i++) 
				if(src[i]=='/') pos=i;
			if(pos==0) tar[tar_path_len++] = '/';
			for(int i = pos; i < src_path_len; i++) 
				tar[tar_path_len++] = src[i];
		}
		//printf("source path:%s\ntarget path:%s\n", src, tar);

		if(open(tar, O_RDWR)==-1)//目标文件不存在,则创建该文件
		{
			if((fd_tar=open(tar, O_RDWR|O_CREAT, 0666))==-1) printError(tar);//创建目标文件失败
		}
		else 
		{
			printf("Object file already exists, which one do you want to operate, overwrite or append?\n");
			printf("Please input overwrite or append?\n");
			scanf("%s", op);
			while(1)
			{
				if(op[0]=='o') //覆盖
				{
					if((fd_tar=open(tar, O_RDWR|O_TRUNC))==-1) printError(tar);
					break;
				}
				else if(op[0]=='a')//追加
				{
					if((fd_tar=open(tar, O_RDWR|O_APPEND))==-1) printError(tar);
					break;
				}
				else printf("Please input overwrite or append?\n");
			}
		}
		if(write(fd_tar, buf, max(0, src_length-1))==-1) printError(tar);//写入文件失败

		printf("All done!\n");

		close(fd_src);
		close(fd_tar);
		free(buf);
	}
	return 0;
}