第三章习题
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);
}