实现自己的cp命令

1 综述

    在Unix和Linux系统里,cp是经常使用的一个命令,用于复制文件,用法如下:

    $cp src_file dest_file

    以下就使用若干系统调用来实现自己的cp。


2 原理

    open:打开一个文件;

    close:关闭文件;

    read:从文件中读取数据到缓冲区;

    write:将数据从缓冲区写入文件;

    fcntl:给文件加锁;

    sbrk:申请堆内存;

    brk:释放堆内存。

    以下直接上代码:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
    char *buf = NULL;
    int fd_src = -1;
    int fd_dest = -1;
    int buf_size = 4096;
    int cnt = 0;
    struct flock lock;

    if (argc < 3) {
        printf("usage: %s <src_file> <dest_file> [buf_size]\n", argv[0]);
        return 0;
    }

    if ((fd_src=open(argv[1], O_RDONLY)) == -1) {
        perror("open src. file");
        return 1;
    }
    if ((fd_dest=open(argv[2], O_WRONLY|O_CREAT|O_EXCL, 0664)) == -1) {
        perror("open dest. file");
        close(fd_src);
        return 2;
    }
    if (argc == 4) {
        buf_size = atoi(argv[3]);
    }
    buf = sbrk(buf_size);
    if ((void*)-1 == buf) {
        perror("malloc");
        close(fd_src);
        close(fd_dest);
        return 3;
    }

    lock.l_type = F_RDLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;
    lock.l_pid = -1;
    if (fcntl(fd_src, F_SETLK, &lock) == -1) {
        fprintf(stderr, "%s has been locked by other process\n", argv[1]);
        close(fd_src);
        close(fd_dest);
        return 8;
    }

    errno = 0;
    while ((cnt = read(fd_src, buf, buf_size)) > 0) {
        if (write(fd_dest, buf, cnt) < cnt) {
            perror("write");
            close(fd_src);
            close(fd_dest);
            return 4;
        }
    }
    if (0 != errno) {
        perror("read");
    }
    close(fd_src);
    fd_src = -1;
    close(fd_dest);
    fd_dest = -1;
    brk(buf);

    return 0;
}


3 总结

 

    我的cp除了需要指定源文件和目的文件之外,还可以指定缓冲区的大小,其它就类似系统的cp了,代码很简单,也能实现了文件复制功能。

 

posted @ 2013-07-30 18:46  jlins  阅读(582)  评论(0编辑  收藏  举报