系统命令cp的实现

2014-07-23 13:33:11   最后更新: 2014-07-23 13:33:11   访问数量:680




通常我们复制一个文件的过程是先read后write,但是,UNIX系统具有空洞文件的特殊情况,因此不能简单地使用这种方法,否则所有的空洞会被\0填充而使得目标文件比源文件大一些(因为空洞的被填充),下面是我的代码(有参考系统命令cp的源码):

#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <sys/stat.h> int main () { int rfd = open ("holefile", O_RDONLY); int wfd = open ("cpholefile", O_WRONLY | O_CREAT); int res; struct stat statbuf; if (fstat(rfd, &statbuf) < 0) { perror ("fstat"); return -1; } if (statbuf.st_size <= statbuf.st_blocks * 512) { char ch[100]; while ((res = read (rfd, ch, sizeof (ch))) != 0) { if (res < 0) { perror ("read"); return -1; } if (write (wfd, ch, res) != res) { perror ("write"); return -1; } } if (fstat(wfd, &statbuf) < 0) { perror ("fstat"); return -1; } } else { char c; while ((res = read (rfd, &c, sizeof (c))) != 0) { if (res < 0) { perror ("read"); return -1; } if (c == 0) { lseek (wfd, 1, SEEK_CUR); continue; } else { if (write (wfd, &c, 1) != 1) { perror ("write"); return -1; } } } } close (rfd); close (wfd); return 0; }

 

但是,这个程序有一下两个问题:

  1. 当空洞很少,即statbuf.st_size <= statbuf.st_blocks * 512时,可能造成空洞的忽略
  2. 当空洞与\0同时存在于一个文件中时,所有的\0都会被当作空洞处理

 

对于第一个问题,linux系统的处理方式是用st_size和ST_NBLOCKSIZE(磁盘实际占用空间)比较,因为ST_NBLOCKSIZE并不是POSIX.1中的标准字段,为了程序的可移植性,我没有选择使用

 

而第二个问题也是系统cp命令存在的问题,因为具有空洞的文件还是比较少遇到的情况,所以这个问题被UNIX系统保留了,我暂时也想不到更好的处理方法,如果有谁可以有更好的方法以克服这个问题,欢迎与我联系,谢谢!

 






读书笔记      技术帖      linux      unix      c++      cpp      c语言      龙潭书斋      apue      unix环境高级编程      技术分享      cp     


京ICP备15018585号