课本习题
10.1 下面程序的输出是什么?
#include "csapp.h"
int main()
{
int fd1,fd2;
fd1=Open("foo.txt",O_RDONLY,0);
Close(fd1);
fd2=Open("baz.txt",O_RDONLY,0);
printf("fd2=%d\n",fd2);
exit(0);
}
答:Unix进程生命周期开始时,打开的描述符赋给了stdin(描述符0)、stdout(描述符1)和stderr(描述符2)。open函数总是返回最低的未打开的描述符,所以第一次调用open会返回描述符3。调用close函数会释放描述符3.最后对open的调用会返回描述符3,因此程序的输出是“fd2=3”。
10.2:假设磁盘文件foobar.txt由6个ASCII码字符“foobar”组成。那么,下列程序的输出是什么?
#include "csapp.h"
int main()
{
int fd1,fd2;
char c;
fd1=Open("foobar.txt",O_RDONLY,0);
fd2=Open("foobar.txt",O_RDONLY,0);
Read(fd1,&c,1);
Read(fd2,&c,1);
printf("c=%c\n",c);
exit(0);
}
答:描述符fd1和fd2都要各自的打开文件表表项,所以每个描述符对于foobar.txt都有它自己的位置。因此,从fd2的读操作会读取foobar.txt的第一个字符,并输出c=f
10.3:就像前面那样,磁盘文件foobar.txt由6个ASCII码字符“foobar”组成。那么,下列程序的输出是什么?
#include "csapp.h"
int main()
{
int fd;
char c;
fd=Open("foobar.txt",O_RDONLY,0);
if(Fork()==0)
{
Read(fd,&c,1);
exit(0);
}
Wait(NULL);
Read(fd,&c,1);
printf("c=%c\n",c);
exit(0);
}
答:这里是子进程继承父进程的描述符表,以及所有进程共享的同一个打开文件表。因此,描述符fd在父子进程中都指向同一个打开文件表表项。当子进程读取文件的一个字节时,文件位置加1.因此,父进程会读取第二个字节,而输出就是c=o,而不是10.2中的 c=f
10.4:如何用dup2将标准输入重定向到描述符5?
答:重定向标准输入(描述符0)到描述符5,直接调用dup2(5,0)
10.5:假设磁盘文件foobar.txt由6个ASCII码字符“foobar”组成。那么下列程序的输出是什么?
#include "csapp.h"
int main()
{
int fd1,fd2;
char c;
fd1=Open("foobar.txt",O_RDONLY,0);
fd2=Open("foobar.txt",O_RDONLY,0);
Read(fd2,&c,1);
Dup2(fd2,fd1); Read(fd1,&c,1);
printf("c=%c\n",c);
exit(0);
}
答:由于重定向,所以答案应该是c=o