APUE习题4.6源代码----实现自己的简易 cp 命令

原题:

编写一个类似 cp 的程序,它复制包含空洞的文件,但不将字节0写到输出文件中去。

源代码:

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

#define BUF_SIZ 128

int my_cp( const char *file1, const char *file2 )
{
    int fd1, fd2;
    char buffer[BUF_SIZ];
    int res;
    int current_position = 0;
    int byte_count = 0;

    fd1 = open( file1, O_RDWR );
    if( -1 == fd1 ) {
        perror("open file1 failed");
        return -1;
    }

    fd2 = open( file2, O_RDWR | O_APPEND | O_CREAT | O_TRUNC, 0666 );
    if( -1 == fd2 ) {
        perror("open file2 failed");
        return -1;
    }

    memset( buffer, '\0', BUF_SIZ );
    res = read( fd1, buffer, BUF_SIZ );
    if( -1 == res ) {
        perror("file1 read error");
        return -1;
    }

    while( 0 != res ) {
        byte_count = 0;
        for( current_position=0; current_position<BUF_SIZ; current_position++ ) {
            if( '\0' != buffer[current_position] ) {
                buffer[byte_count] = buffer[current_position];
                byte_count++;
            }
        }

        res = write( fd2, buffer, byte_count );
        if( -1 == res ) {
            perror("file2 write failed");
            return -1;
        }

        memset( buffer, '\0', BUF_SIZ );
        res = read( fd1, buffer, BUF_SIZ );
        if( -1 == res ) {
            perror("file1 read failed");
            return -1;
        }
    }
}

int main(int argc, char *argv[])
{
    if( 3 != argc) {
        printf("correct usage: ./my_cp file1 file2\n");
        exit( EXIT_FAILURE );
    }

    //产生一个含有空洞的文件 file1
    int fd = open( argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666 );
    if( -1 == fd ) {
        perror("open failed");
        exit( EXIT_FAILURE );
    }

    int res = write( fd, "Hey,man!", strlen("Hey,man!") );
    if( -1 == res ) {
        perror("file1 write failed");
        exit( EXIT_FAILURE );
    }

    off_t offset = lseek( fd, 10000, SEEK_SET );
    if( -1 == offset ) {
        perror("lseek failed");
        exit( EXIT_FAILURE );
    }

    res = write( fd, "How are you?", strlen("How are you?") );
    if( -1 ==res ) {
        perror("file1 write failed");
        exit( EXIT_FAILURE );
    }

    //应用 my_cp 函数拷贝文件
    res = my_cp( argv[1], argv[2] );
    if( -1 == res ) {
        perror("copy failed");
        exit( EXIT_FAILURE );
    }

    exit( EXIT_SUCCESS );
}

运行结果:

[[email protected] APUE]$ ./my_cp file1 file2

[[email protected] APUE]$ cat file2

Hey,man!How are you?

输出文件在本例中为file2,大小为 20 Bytes = strlen("Hey,man!") + strlen("How are you?")。测试通过。

时间: 2024-08-27 14:10:24

APUE习题4.6源代码----实现自己的简易 cp 命令的相关文章

APUE习题3.2以及shell中重定向符号的使用

习题3.2的要求是不使用fcntl()而编写一个同dup2()功能相同的函数.直觉上是不断使用dup()直到返回指定的文件描述符. #include <stdio.h>#include <stdlib.h>#define OPEN_MAX 63 int my_dup2(int filedes,int filedes2); intmain(int argc, char* argv[]){  int fd,fd2;  char buf[] = "It work!\n"

APUE习题8.7

看书的时候发现这个习题没有答案,于是就想把自己做的结果贴上来,和大家分享分享! 首先把题目贴上来吧: /*********** 8.10节中提及POSIX.1要求在调用exec时关闭打开的目录流.按下列方法对此进行验证,对根目录调用opendir,查看在你的系统上实现的DIR结构,然后打印执行时关闭标志.接着open同一目录读取并打印执行时关闭标志 ***********/ 首先说,关于执行时关闭标志的作用,JesseEisen的这篇博客已经讲解的非常好了,(传送门在这里)我就不在这里献丑了,我

APUE习题3.2----自己实现的dup2( )函数的源码

原 dup2()函数: #include <unistd.h> int dup2( int fd, int fd2 ); 对于 dup2,可以用 fd2 参数指定新描述符的值.如果 fd2 已经打开,则先将其关闭.如若 fd 等于 fd2,则 dup2 返回 fd2,而不关闭它.否则,fd2 的 FD_CLOEXEC 文件描述符标志就被清除,这样 fd2 在进程调用 exec 时是打开状态.该函数返回的新文件描述符与参数 fd 共享同一个文件表项. 下面是自己实现的 dup2函数: #incl

APUE习题4.6---测试lseek作用

原题:如果使用追加标志打开一个文件以便读.写,能否仍用 lseek 在任一为止开始读?能否用 lseek 更新文件中任一部分的数据? 验证程序如下: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #define BUF_SIZ 32 int main() { int fd; int res; off

APUE习题3.5

比较 ./a.out  >  outfile  2> &1 和 ./a.out  2> &1  >  outfile 的区别,回答这个问题只要把笔记“shell脚本->输入输出重定向”中提到的输出重定向的本质给搞清楚就可以了,下面解析这个问题. 先分析 ./a.out  >  outfile  2> &1 ,shell命令是从左向右执行的,首先是将标准输出重定向到文件outfile中,再是将标准错误重定向到标准输出,从文件描述符层面来看首先

APUE习题3.6

如果在打开文件的时候加上了追加标志(O_APPEND),那么是否可以利用lseek函数来实现对文件在任意位置的读.写操作? 回答:可以实现任意位置的读操作,但是不可以实现任意位置的写操作.如果添加了O_APPEND标志,那么每次写操作的时候都会追加到文件末尾,而对读操作没有影响.

《unix环境高级编程&#183;第三版》源代码编译及使用

<unix环境高级编程·第三版>源代码编译及使用 <unix环境高级编程>中有很多示例代码需要包含作者自定义的头文件,如"apue.h".这些代码可以从以下网址下载 http://apuebook.com/code3e.html 1. 解压文件 tar -zxvf src.3e.tar.gz 2. 安装libbsd-dev,否则编译会报错不通过,会提示编译threads文件夹里面的内容时报错 3. cd apue.3e make 用 root 用户或者 sudo

分享《自然语言处理理论与实战》PDF及代码+唐聃+《深入浅出Python机器学习》PDF及代码+段小手+《深度学习实践:计算机视觉》PDF+缪鹏+《最优化理论与算法第2版》高清PDF+习题解答PDF+《推荐系统与深度学习》PDF及代码学习

<自然语言处理理论与实战>高清PDF,362页,带书签目录,文字可以复制:配套源代码.唐聃等著. <大数据智能互联网时代的机器学习和自然语言处理技术>PDF,293页,带书签目录,文字可以复制,彩色配图.刘知远等著.  下载: https://pan.baidu.com/s/1waP6C086-32_Lv0Du3BbNw 提取码: 1ctr <自然语言处理理论与实战>讲述自然语言处理相关学科知识和理论基础,并介绍使用这些知识的应用和工具,以及如何在实际环境中使用它们.由

源代码的下载和编译

4.1下载编译和测试源代码 Android源代码由很多东西组成,一种是Android系统应用程序的代码,android SDK带的各种工具,android NDK的源代码,HAL源代码. 1.配置Android源代码下载环境 在下载Android源代码之前必须要在Linux终端执行一系列命令来配置下载环境. 第一步:创建一个用于存放下载脚本文件(repo)的目录 #  mkdir  ~/bin #  PATH=~/bin:$PATH 第二步:下载repo脚本文件 # curl https://d