UNIX环境高级编程习题——第三章

第三章习题

3.1 当读/写磁盘文件时,本章中描述的函数确实是不带缓冲机制的吗?请说明原因:

1、本章中描述的read和write函数都是系统调用,这两个函数都是在内核中进行的,所以是不带缓冲的I/O函数。而带有缓冲机制的函数是以内存空间作为缓冲区,避免不当操作降低多写性能。

3.2 编写一个与3.12节中dup2功能相同的函数,要求不掉用fcntl函数,并且要有正确的出错处理:

/*************************************************************************
    > File Name: test3_2.c
    > Author: King
    > Mail: arturiapendragon_1@163.com 
    > Created Time: 2017年08月05日 星期六 10时12分01秒
 ************************************************************************/

#include <apue.h>

int
my_dup2(int fd, int fd2)
{
    int     t;
    int     dups[256];
    int     i = 0;

    if (fd2 < 0 || fd2 > 256)
    {
        printf("fd2 must more than 0 less than 256");
    }
    if (fd == fd2)
        return fd2;
    else
    {
        if (close(fd2) == 0)
        {
            return dup(fd);
        }
        else
        {
            do
            {
                t = dup(fd);
                dups[i] = t;
                i++;
            }
            while (t != fd2);

            while (i)
                close(dups[--i]);
            return t;
        }
    }
}

3.3 假设一个进程执行下面3个函数调用:
fd1 = open(path, oflags);
fd2 = dup(fd1);
fd3 = open(path, oflags);
画出类似于图3-9的结果图。对fcntl作用于fd1来说,F_SETFD命令会影响哪一个文件描述符,F_SETFL呢?
这里写图片描述

(1)F_SETFD标志是文件描述符标记,只作用于一个进程的一个描述符,所以对于fctnl作用于fd1来说,只会影响fd1。
(2)F_SETFL标志是文件状态标记,作用于任何进程中的所有描述符,所以对于fctnl作用于fd1来说,会影响fd1,fd2。

3.4 许多程序都包含下面一段代码:
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
if (fd > 2)
close(fd);
为了说明if语句的必要性,假设fd是1,画出每次调用dup2时3个描述符项及相应的文件表项的变化情况。然后再画出fd为3的情况。
这里写图片描述

标准输入、标准输出和标准错误的文件描述符都指向同一文件表项,可以使用标准输入、标准输出和标准错误的文件描述符打开该文件,并设置文件状态标记或偏移量。

3.5 在Bourne shell、Bourne-again shell 和 Korn shell中,digit1 > &digit2表示将米哦啊舒服digit1重定向至描述符digit2的同以文件。请说明下面两条命令的区别
./a.out > outfile 2>&1
./a.out > 2>&1 outfile
(提示:shell从左到右处理命令行)

(1)./a.out > outfile 2>&1
这条命令首先将标准输出重定向到outfile中,然后将标准错误文件描述符重定向到标准输出指向的文件表项中,所以标准输出和标准错误的文件描述符均指向outfile。
(2)./a.out > 2>&1 outfile
这条命令首先将标准错误文件描述符重定向到标准输出指向的文件表项中,然后标准输出文件描述符又重定向到outfile文件中。所以最后标准输出的文件描述符和标准错误的文件描述符不是指向同一个文件表项。

3.6 如果使用追加标志打开一个文件以便读、写,能否仍用lseek在任一位置开始读?能否用lseek更新文件中任一部分的数据?请编写一段程序验证

能。程序如下

/***********************************************************************
    >  File Name: test3-6.c
    >  Author : Fedora
    >  mail: ArturiaPendragon_1@163.com
    >  Create Time: 2017-05-07
***********************************************************************/

#include "apue.h"
#include <unistd.h>
#include <fcntl.h>

int main(void)
{
    int fd;
    if((fd=open("lseek",O_RDWR | O_APPEND)) < 0)
    {
        err_sys("open file error!");
        exit(-1);
    }

    int offt;
    if((offt=lseek(fd, 0, SEEK_END)) == -1)
    {
        err_sys("lseek error!");
        exit(-1);
    }


    int wb;
    if((wb=write(fd,"test\n", 5)) < 0)
    {
        err_sys("write error!");
        exit(-1);
    }
    int rb;
    char *rd;
    if((rb=read(fd,rd,wb)) < 0)
    {
        err_sys("read error");
        exit(-1);
    }

    if(write(STDOUT_FILENO, rd, rb) != rb){
        err_sys("ouput result error!");
        exit(-1);
    }

/*
    int n;
    char *rd;
    int wd;
    while ((n=read(fd,rd,1024)) > 0)
        if (write(STDOUT_FILENO,rd,wd) != wd)
            err_sys("write error!");
    if (n < 0)
        err_sys("write error");
*/
    exit(0);
}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值