1. 程式人生 > >linux cp 命令實現

linux cp 命令實現

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