编写一个类似cp命令的程序,当使用该程序复制一个包含空洞的普通文件时,要求目标文件的空洞与源文件一致。

准备工作

  • 创建一个空洞文件  首先先编写一个小程序去创建空洞文件。 代码如下:

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <stdlib.h>

    int main(void)
    {
    int fd;
    int ret;
    fd=open("hole.txt",O_CREAT|O_RDWR,0644);
    if(fd==-1)
    exit(EXIT_FAILURE);
    write(fd,"hello",5);
    ret=lseek(fd,100000,SEEK_CUR);
    if(ret==-1)
    exit(EXIT_FAILURE);
    write(fd,"world",5);
    close(fd);
    exit(EXIT_SUCCESS);
    }

  • 编译运行

    $ gcc 4-2.c -o hole
    $ ./hole
    $ cat hole.txt
    helloworld
    $ du -h hole.txt
    8.0K hole.txt
    $ od -c hole.txt
    0000000 h e l l o \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
    0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
    *
    0303240 \0 \0 \0 \0 \0 w o r l d
    0303252

  • 程序代码

    #include <ctype.h>
    #include "tlpi_hdr.h"
    #include <stdbool.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    int main(int argc, char *argv[])
    {
    char buf[1024];
    int input,output, ret;
    ssize_t len;
    /* 读取选项 */

    if(argc!=3||strcmp(argv[1],"--help")==0)
    {
    printf("usage:%s cp file1 to file2 \n",argv[0]);
    exit(EXIT_SUCCESS);
    }
    input=open(argv[1], O_RDONLY , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    if(input==-1)
    errExit("open input");
    output=open(argv[2], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    if(input==-1)
    errExit("open output");
    while((ret=read(input,buf,1024))>0)
    {
    write(output,buf,ret);
    }

    exit(EXIT_SUCCESS);
    }
  • 编译运行

    make && ./4-2 hole.txt test.txt
  • 检查结果

    $ od -c test.txt
    0000000 h e l l o \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
    0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
    *
    0303240 \0 \0 \0 \0 \0 w o r l d
    0303252