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博