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] ", 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 ", 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了,代码很简单,也能实现了文件复制功能。