cp -r的linux C语言实现

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<dirent.h>

#define ARGS_CHECK(argc,num){if(argc!=num){fprintf(stderr,"argc error!\n");return -1;}}
#define ERROR_CHECK(ret,errnum,msg){if(ret==errnum){perror(msg);return -1;}}

int cpFile(char *old_path,char *new_path){
    int fd_read = open(old_path, O_RDONLY);                                     //1、按正确的权限打开文件
    ERROR_CHECK(fd_read, -1, "open");
    int fd_write = open(new_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    ERROR_CHECK(fd_write, -1, "open");
    char buf[4096] = { '\0'  };                                                 //2、创建缓冲区buf
    while (1) {
        memset(buf, '\0', sizeof(buf));                                         //3、循环重置buf后read读取和write写入
        int ret = read(fd_read, buf, sizeof(buf));
        if (ret == 0) {                                                         //4、read返回值为0后结束循环
            break;
        }
        write(fd_write, buf, sizeof(buf));

    }
    printf("Copied %s.\n",new_path);                                            //test
    close(fd_read);
    close(fd_write);
    return 0;
}

int createDir(char *old_path,char *new_path_back,char *dir_name){               //创建目录
    printf("chdir is %s.\n",new_path_back);                                     //test
    printf("mkdir %s.\n",dir_name);                                             //test
    strcat(new_path_back,dir_name);
    mkdir(new_path_back,0777);
}

int DFScp(char *old_path,char *new_path){                                       
    DIR *pd_old = opendir(old_path);                                            //1、打开目录文件
    ERROR_CHECK(pd_old,NULL,"opendir");
    DIR *pd_new = opendir(new_path);
    ERROR_CHECK(pd_new,NULL,"opendir");
    struct dirent *pdirent;                                                     //2、用dirent作循环的容器,存储目录节点的信息
    while((pdirent = readdir(pd_old))){
        if(!strcmp(pdirent->d_name,".") || !strcmp(pdirent->d_name,"..")){        //3、跳过.和.. ,输出目录文件名
            continue;
        }
        char p_new[512] = { 0 };
        char p_new_back[512] = { 0 };
        strcat(p_new,new_path);                                                    //拼接复制到的路径
        strcat(p_new,"/");
        strcpy(p_new_back,p_new);
        strcat(p_new,pdirent->d_name);
        char p_old[512] = { 0 };                                                //拼接被复制的路径
        strcat(p_old,old_path);
        strcat(p_old,"/");
        strcat(p_old,pdirent->d_name);
        if(pdirent->d_type == DT_REG){                                            //是文件,则复制文件
            cpFile(p_old,p_new);
        }
        else if(pdirent->d_type == DT_DIR){                                        //是空目录,则创建缺少的目录,再传入新的路径,递归调用cp -r
            createDir(p_old,p_new_back,pdirent->d_name);
            printf("Into Next:%s\n",p_new);                                     //test
            DFScp(p_old,p_new);
        }
    }
    return 0;
}

int main(int argc,char *argv[]){
    ARGS_CHECK(argc,3);
    DFScp(argv[1],argv[2]);
    return 0;
}

 

posted on 2021-02-24 21:42  平ping  阅读(501)  评论(0)    收藏  举报