linux下简单cp命令的实现

来源:岁月联盟 编辑:exp 时间:2012-05-29
linux下简单cp命令的实现 实现功能:$./cp  ~/filename  ~/OtherName                  //文件到文件的拷贝  $./cp  ~/directory/filename   .                        //文件到当前目录的拷贝  $./cp  ~/directory/filename  ~/directory/       //文件到目录的拷贝 不白费口舌,直接上代码才是王道!  001#include <stdio.h>002#include <stdlib.h>003#include <sys/stat.h>004#include <sys/types.h>005#include <fcntl.h>006#include <errno.h>007#include <unistd.h>008#include <string.h>009  www.2cto.com   010#define BUF_SIZE       1024011#define PATH_LEN       128012 013void my_err(char *err_string, int line )014{015    fprintf(stderr,"line:%d ",line);016    perror(err_string);017    exit(1);018}019 020void copy_data(const int frd,const int fwd)021{022    int read_len = 0, write_len = 0;023    unsigned char buf[BUF_SIZE], *p_buf;024 025    while ( (read_len = read(frd,buf,BUF_SIZE)) ) {026         027        if (-1 == read_len) {028            my_err("Read error", __LINE__);029        }030        else if (read_len > 0) { //把读取部分写入目标文件031            p_buf = buf;  www.2cto.com  032            while ( (write_len = write(fwd,p_buf,read_len)) ) {033                if(write_len == read_len) {034                    break;035                }036                else if (write_len > 0) {  //只写入部分037                    p_buf    += write_len;038                    read_len -= write_len;039                }040                else if(-1 == write_len) {041                    my_err("Write error", __LINE__);042                }043            }044            if (-1 == write_len) break;045        }046    }047}048 049int main(int argc, char **argv)050{051     052    int frd, fwd; //读写文件描述符053    int len = 0;054    char *pSrc, *pDes;  //分别指向源文件路径和目标文件路径055    struct stat src_st,des_st;056     057    if (argc < 3) {058        printf("用法 ./MyCp <源文件路径> <目标文件路径>/n");059        my_err("arguments error ", __LINE__);060    }061     062    frd = open(argv[1],O_RDONLY);063    if (frd == -1) {064        my_err("Can not opne file", __LINE__);065    }066 067    if (fstat(frd,&src_st) == -1) {068        my_err("stat error",__LINE__);069    }  www.2cto.com  070    /*检查源文件路径是否是目录*/071    if (S_ISDIR(src_st.st_mode)) {072        my_err("略过目录",__LINE__);073    }074     075    pDes = argv[2];076    stat(argv[2],&des_st);077    if (S_ISDIR(des_st.st_mode)) { //目标路径是目录,则使用源文件的文件名078         079        len = strlen(argv[1]);080        pSrc = argv[1] + (len-1); //指向最后一个字符081        /*先找出源文件的文件名*/082        while (pSrc >= argv[1] && *pSrc != '/') {083            pSrc--;084        }085        pSrc++;//指向源文件名086         087        len = strlen(argv[2]);088        // . 表示复制到当前工作目录089        if (1 == len && '.' == *(argv[2])) {090            len = 0;  //没有申请空间,后面就不用释放091            pDes = pSrc;092        }093        else { //复制到某目录下,使用源文件名094            pDes = (char *)malloc(sizeof(char)*PATH_LEN);095  www.2cto.com              if (NULL == pDes) {096                my_err("malloc error ", __LINE__);097            }098             099            strcpy(pDes,argv[2]);100         101            if ( *(pDes+(len-1)) != '/' ) { //目录缺少最后的'/',则补上’/‘102                strcat(pDes,"/");103            }104            strcat(pDes+len,pSrc);105        }106    }107     108    /*   打开目标文件, 使权限与源文件相同*/         109    fwd = open(pDes,O_WRONLY | O_CREAT | O_TRUNC,src_st.st_mode);110    if (fwd == -1) {111        my_err("Can not creat file", __LINE__);112    }113    copy_data(frd,fwd);114    //puts("end of copy");115    if (len > 0 && pDes != NULL)116  www.2cto.com          free(pDes);117     118    close(frd);119    close(fwd);120 121    return 0;122}
  作者 bo博