zoukankan      html  css  js  c++  java
  • 【转】《APUE》第三章笔记(4)及习题3-2

    原文网址:http://www.cnblogs.com/fusae-blog/p/4256794.html

    APUE第三章的最后面给出的函数,现在还用不着,所以,先留个名字,待到时候用着了再补上好了。

    dup和dup2函数:用来复制文件描述符的

    sync函数,fsync函数和fdatasync函数:大致的功能是将缓冲区的数据刷进队列中,等待写入到硬盘中。

    fcnti函数:可以改变已打开文件的性质。

    ioctl函数:控制设备。

    习题:

    1.当读/写磁盘文件时,本章中描述的函数是否有缓冲机制?请说明原因。

    答:是没有的。上述提到的函数是open,read,write等基于POSIX的函数,是直接调用内核中的一个系统调用。而ISO C的标准输入输出函数才是有缓冲的函数,引入了流的概念。具体可参照这篇文章:http://blog.csdn.net/zhangxinrun/article/details/5873047

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

    答:首先要知道dup2函数的功能和fcntl函数的功能。

    dup2函数:

    功能:复制一个文件描述符,并返回一个任意指定的文件描述符。

    #include <unistd.h>

    int dup2(int oldfd, int newfd);

    返回:newfd

    如果newfd已经打开,则先将其关闭。

    fcntl函数:

    目前只需知道dup2(oldfd, newfd) 等效于 

    close(newfd);

    fcntl(oldfd, F_DUPFD, oldfd);

    思路:

    1.先关闭newfd,以防万一。然后利用dup(oldfd),不断产生新的fd,直至fd==newfd,再关闭掉其余的fd。

    2.因为oldfd和newfd都代表同一个文件,所以其实就是其文件指针指向同一个文件表。所以给文件指针赋值也行,但是不知道结构体的内容,所以也就无法执行了。

    思路1代码:

    1. /*实现dup2函数,不能用fcntl函数*/  
    2. #include <unistd.h>  
    3. #include <fcntl.h>  
    4. #include <stdio.h>  
    5. #include <stdlib.h>  
    6.   
    7. #define BUFFSIZE    4096  
    8. #define SIZE    20  
    9.   
    10. int my_dup2(int oldfd, int newfd);  
    11.   
    12. int main(void)  
    13. {  
    14.     char    *filename = "test";  
    15.     int newfd = 10;  
    16.     char    buf[BUFFSIZE];  
    17.     int oldfd = open(filename, O_RDONLY);   /* 打开一个文件 */  
    18.     int n;  
    19.   
    20.       
    21.     my_dup2(oldfd, newfd);  
    22.       
    23.     /* 将test文件(注意:fd是用了newfd)的内容输出到stdout里 */  
    24.     while ((n = read(newfd, buf, BUFFSIZE)) > 0)  
    25.         if (write(STDOUT_FILENO ,buf, n) != n)  
    26.         {  
    27.             perror("write error");  
    28.             exit(1);  
    29.         }  
    30.       
    31.     if (n < 0)  
    32.     {  
    33.         perror("read error");  
    34.         exit(1);  
    35.     }  
    36.   
    37.     close(newfd);  
    38.   
    39.     exit(0);  
    40. }  
    41.   
    42. int my_dup2(int oldfd, int newfd)  
    43. {  
    44.     int tmp[SIZE];  
    45.     int i = 0;  
    46.   
    47.     if (oldfd == newfd)  
    48.         return newfd;  
    49.   
    50.     close(newfd);  
    51.   
    52.     /*利用dup函数不断产生新的fd,如果fd跟newfd相等,则停止*/  
    53.     while (1)  
    54.     {  
    55.         tmp[i] = dup(oldfd);  
    56.         if(tmp[i] == newfd)  
    57.             break;  
    58.         i++;  
    59.     }  
    60.         /* 关掉多余的fd */  
    61.     i = 0;  
    62.     while (1)  
    63.     {  
    64.         if(tmp[i] != newfd)  
    65.         {  
    66.             close(tmp[i]);  
    67.             i++;  
    68.         }     
    69.         else  
    70.             break;  
    71.     }  
    72.   
    73.           
    74.   
    75.     return newfd;  
    76. }  

    结果运行如下:

    如果将中间那个my_dup2函数注释掉的话,结果如下:

    到此,习题3-2解决!

    习题部分就做到这里好了,或许有空会更新接下来的习题部分。

  • 相关阅读:
    oracle rank() 排名函数
    oracle rank over partition by
    oracle over函数
    oracle extract函数
    mybatis的<choose>和<when>、<otherwise>标签
    python字符串操作实方法大合集
    GO安全并发之无锁原子操作
    设计模式(Design Patterns)Java版
    Linux内核参数调优
    TCP协议解析
  • 原文地址:https://www.cnblogs.com/wi100sh/p/4280510.html
Copyright © 2011-2022 走看看