电子科技大学《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;
}