linux cp 命令實現
阿新 • • 發佈:2019-02-17
linux cp 簡單實現就是read 原始檔的內容到一個buffer, 然後再將buffer 中的內容 write 到要copy 的目標檔案中去,這樣就實現了cp 的功能。
看了busybox 中的實現無非就是read/write 操作,現在自己先實現一個最簡單的,對檔案操作熟悉一下。
#include <stdio.h> #include <stdlib.h> #include <sys/file.h> #define BUFSIZE 8*1024 //just implement as "cp a.file /path/to/your/dest/". int main(int argc,char* argv[]) { int i_arg = 0; printf("qc test log: argc = %d \n", argc); for(i_arg = 0; i_arg < argc; i_arg ++) { printf("qc test log: argv[%d] is %s \n",i_arg, argv[i_arg] ); } if(argc < 3) { printf("args number is wrong! \n"); //TODO //usage(); return 1; } char buf[BUFSIZE]; //concat target dest path with source file name, to get the target path/file.name string START. //argv[0] is the cmd self, eg "cp" //argv[1] is the cp source file, eg "test.txt" //argv[2] is the cp dest path, eg "/" //concat the dest path with source filename to get the target file(path+name): yes, simple test prog only, ^_^ char *dest_file = (char*)malloc(strlen(argv[1]) + strlen(argv[2])); int i, j, dest_path_length = strlen(argv[2]); for(i = 0; i < dest_path_length; i ++) dest_file[i]=argv[2][i]; for(j = 0; j < strlen(argv[1]); j ++, i ++) { dest_file[i] = argv[1][j]; } dest_file[i]='\0'; //target path/file.name Got END. //OMG ugly coding !!! int src_fd = open(argv[1], O_RDONLY); if(src_fd == -1) { printf("Source file %s doesn't not exist! \n", argv[1]); return 1; } int dest_fd = creat(dest_file, O_RDWR); if(dest_fd == -1) { printf("Dest file %s can't be created! \n", dest_file); return 1; } int ret = -1; // read length is the read system call return val. while(ret = read(src_fd, buf, BUFSIZE)) { write(dest_fd, buf, ret); // write the buf to dest_file. } close(src_fd); close(dest_fd); return 0; }
參考文章:
程式碼結構基本上保持了原作者的結構,註釋,程式碼風格重新寫的,感謝原作者的思路啟迪,但是原先程式碼寫的實在太ugly 了,沒有bs 的意思,也作為自省吧,寫程式碼寫一行是一行,都要保證每一行的beauty !!!
交叉編譯 cp.c , 如果使用的交叉編譯器中有標準庫的話比較簡單(Tiny6410 中帶的 ARM V6 toolchain 中就 有標準庫,所以編譯用到標準庫函式的程式碼直接編譯就行),如果交叉工具鏈只是一個純粹的交叉編譯器沒有標準庫的話,就需要交叉編譯標準庫(如glibc), 然後再編譯自己的程式:
CROSS_COMPILE_gcc cp.c -o cp -static --sysroot=your/path/to/glibc/
或者寫一個最簡單的Makefile:
CC = gcc
CFLAGS += -static
all:
$(CC) $(CFLAGS) hello.c -o hello