linux下實現我本身簡單的 cp 命令

 實現功能:
$./cp  ~/filename  ~/OtherName                  //文件到文件的拷貝

$./cp  ~/directory/filename   .                        //文件到當前目錄的拷貝

$./cp  ~/directory/filename  ~/directory/       //文件到目錄的拷貝
不白費口舌,直接上代碼纔是王道!
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>

#define BUF_SIZE       1024
#define PATH_LEN       128

void my_err(char *err_string, int line )
{
    fprintf(stderr,"line:%d ",line);
    perror(err_string); 
    exit(1);
}

void copy_data(const int frd,const int fwd)
{
	int read_len = 0, write_len = 0;
	unsigned char buf[BUF_SIZE], *p_buf;

	while ( (read_len = read(frd,buf,BUF_SIZE)) ) {
		
		if (-1 == read_len) {
			my_err("Read error", __LINE__);
		}
		else if (read_len > 0) { //把讀取部分寫入目標文件
			p_buf = buf;
			while ( (write_len = write(fwd,p_buf,read_len)) ) {
				if(write_len == read_len) {
					break;
				}
				else if (write_len > 0) {  //只寫入部分
					p_buf    += write_len;
					read_len -= write_len;
				}
				else if(-1 == write_len) {
					my_err("Write error", __LINE__);
				}
			}
			if (-1 == write_len) break;
		}
	}
}

int main(int argc, char **argv) 
{
	
	int frd, fwd; //讀寫文件描述符
	int len = 0;
	char *pSrc, *pDes;  //分別指向源文件路徑和目標文件路徑
	struct stat src_st,des_st;
	
	if (argc < 3) {
		printf("用法 ./MyCp <源文件路徑> <目標文件路徑>\n");
		my_err("arguments error ", __LINE__);
	}
	
	frd = open(argv[1],O_RDONLY);
	if (frd == -1) {
		my_err("Can not opne file", __LINE__);
	}

	if (fstat(frd,&src_st) == -1) {
		my_err("stat error",__LINE__);
	}
	/*檢查源文件路徑是不是目錄*/
	if (S_ISDIR(src_st.st_mode)) {
		my_err("略過目錄",__LINE__);
	}
	
	pDes = argv[2];
	stat(argv[2],&des_st);
	if (S_ISDIR(des_st.st_mode)) { //目標路徑是目錄,則使用源文件的文件名
		
		len = strlen(argv[1]);
		pSrc = argv[1] + (len-1); //指向最後一個字符
		/*先找出源文件的文件名*/
		while (pSrc >= argv[1] && *pSrc != '/') {
			pSrc--;
		}
		pSrc++;//指向源文件名
		
		len = strlen(argv[2]); 
		// . 表示複製到當前工做目錄
		if (1 == len && '.' == *(argv[2])) {
			len = 0;  //沒有申請空間,後面就不用釋放
			pDes = pSrc;
		}
		else { //複製到某目錄下,使用源文件名
			pDes = (char *)malloc(sizeof(char)*PATH_LEN);
			if (NULL == pDes) {
				my_err("malloc error ", __LINE__);
			}
			
			strcpy(pDes,argv[2]);
		
			if ( *(pDes+(len-1)) != '/' ) { //目錄缺乏最後的'/',則補上’/‘
				strcat(pDes,"/");
			}
			strcat(pDes+len,pSrc);
		}
	}
	
	/*   打開目標文件, 使權限與源文件相同*/          
	fwd = open(pDes,O_WRONLY | O_CREAT | O_TRUNC,src_st.st_mode);
    if (fwd == -1) {
		my_err("Can not creat file", __LINE__);
	}
	copy_data(frd,fwd);
	//puts("end of copy");
	if (len > 0 && pDes != NULL)
		free(pDes);
	
	close(frd);
	close(fwd);

	return 0;
}

本博文原來在此發表,因爲那個博客再也不更新因此把它轉過來了!c++

相關文章
相關標籤/搜索