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;
}
参考文章:
http://wenku.baidu.com/view/190fbf797fd5360cba1adbb3.html
代码结构基本上保持了原作者的结构,注释,代码风格重新写的,感谢原作者的思路启迪,但是原先代码写的实在太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