APUE第三章的最后面给出的函数,如今还用不着,因此,先留个名字,待到时候用着了再补上好了。async
dup和dup2函数:用来复制文件描述符的
函数
sync函数,fsync函数和fdatasync函数:大体的功能是将缓冲区的数据刷进队列中,等待写入到硬盘中。spa
fcnti函数:能够改变已打开文件的性质。.net
ioctl函数:控制设备。指针
1.当读/写磁盘文件时,本章中描述的函数是否有缓冲机制?请说明缘由。code
答:是没有的。上述提到的函数是open,read,write等基于POSIX的函数,是直接调用内核中的一个系统调用。而ISO C的标准输入输出函数才是有缓冲的函数,引入了流的概念。具体可参照这篇文章:http://blog.csdn.net/zhangxinrun/article/details/5873047blog
2.编写一个与3.12节中dup2功能相同的函数,要求不调用fcntl函数,而且要有正确的出错处理。队列
答:首先要知道dup2函数的功能和fcntl函数的功能。it
dup2函数:io
功能:复制一个文件描述符,并返回一个任意指定的文件描述符。
#include <unistd.h>
int dup2(int oldfd, int newfd);
返回:newfd
若是newfd已经打开,则先将其关闭。
fcntl函数:
目前只需知道dup2(oldfd, newfd) 等效于
close(newfd);
fcntl(oldfd, F_DUPFD, newfd);
思路:
1.先关闭newfd,以防万一。而后利用dup(oldfd),不断产生新的fd,直至fd==newfd,再关闭掉其他的fd。
2.由于oldfd和newfd都表明同一个文件,因此其实就是其文件指针指向同一个文件表。因此给文件指针赋值也行,可是不知道结构体的内容,因此也就没法执行了。
思路1代码:
/*实现dup2函数,不能用fcntl函数*/ #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #define BUFFSIZE 4096 #define SIZE 20 int my_dup2(int oldfd, int newfd); int main(void) { char *filename = "test"; int newfd = 10; char buf[BUFFSIZE]; int oldfd = open(filename, O_RDONLY); /* 打开一个文件 */ int n; my_dup2(oldfd, newfd); /* 将test文件(注意:fd是用了newfd)的内容输出到stdout里 */ while ((n = read(newfd, buf, BUFFSIZE)) > 0) if (write(STDOUT_FILENO ,buf, n) != n) { perror("write error"); exit(1); } if (n < 0) { perror("read error"); exit(1); } close(newfd); exit(0); } int my_dup2(int oldfd, int newfd) { int tmp[SIZE]; int i = 0; if (oldfd == newfd) return newfd; close(newfd); /*利用dup函数不断产生新的fd,若是fd跟newfd相等,则中止*/ while (1) { tmp[i] = dup(oldfd); if(tmp[i] == newfd) break; i++; } /* 关掉多余的fd */ i = 0; while (1) { if(tmp[i] != newfd) { close(tmp[i]); i++; } else break; } return newfd; }
结果运行以下:
若是将中间那个my_dup2函数注释掉的话,结果以下:
到此,习题3-2解决!
习题部分就作到这里好了,或许有空会更新接下来的习题部分。