标签:
写在前面:本人通信专业大二,自学apue,时间有限,这个系列都是抽时间写的,目前已经看到15章,现在从头做题,如有错误还请指教。
第一题:
write和read这样的函数都属于系统调用,这里具体所指的没有缓冲区是没有用户缓冲区,而不是指没有内核缓冲区,这里以我个人的认识认为,这里write和read将数据拷贝到缓冲区后并不直接写到文件中,而是等一定条件发生后才写进去,但是具体机制还需研究。同时这里也暴露了一个问题,每次进行I/O都需要进行系统调用,这无疑是对系统资源的一种浪费,所以这也为后来的标准I/O函数库的产生做了铺垫。
第二题:
先上代码:
#include "apue.h" #include <stdio.h> #include <fcntl.h> int dup2_self (const int ofd , const int nfd) ; int main () { int fd; int flag; fd = open ("tempfile" , O_RDWR | O_CREAT | O_TRUNC); flag = dup2(0 , fd); write (fd , "hello\n" , 6); } int dup2_self (const int ofd , const int nfd) { char *fdptr; int openmax = sysconf (_SC_OPEN_MAX); int tempfd; int count = 0; int fdarr[openmax]; int i; if (ofd > openmax || nfd > openmax) { fprintf (stderr , "the arguement error\n"); exit (1); } fdptr = malloc (30 * sizeof (char)); sprintf (fdptr , "/proc/%d/fd/%d" , getpid() , ofd); if (access (fdptr , 0) < 0) { fprintf (stderr , "the ofd is not open\n"); exit (2); } sprintf (fdptr , "/proc/%d/fd/%d" , getpid() , nfd); if (access (fdptr , 0) < 0) { fprintf (stderr , "the nfd is not open\n"); exit (3); } if (nfd == ofd) return nfd; close (nfd); while (tempfd = dup (ofd)) { if (tempfd == nfd) break; else fdarr[count++] = tempfd; } printf ("%d\n" , nfd); for ( i = 0 ; i < count ; i++) close (fdarr [i]); return nfd; }
这段代码显然无法做到dup2的原子性,但是在功能上至少可以实现所需要的功能,当然可靠性我也没有非常多的验证,这个最近本的实现让我弄清楚了很多问题:第一——dup2的使用规则,其实就是将文件描述符和文件描述标志的关系去掉,重新引导到另外一个文件描述标志中上。第二——dup的使用方法,它总是返回最小的可用的文件描述符值,比如在这里nfd(这里我在linux上将这个值打印出来是3)已经close后,再dup后就直接还是3,可见close掉后还是可用的文件描述符。第三——如何查看一个进程所打开的文件描述符在/proc/pid/fd/#就可以。最后结果就是我往main中的fd write的时候,它会在标准输出显示。
——————————————————————————————————————————————————分割线2016.6.1
标签:
原文地址:http://www.cnblogs.com/zzlpp/p/5551624.html