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

    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, 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解决!

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

  • 相关阅读:
    没有 Lambda 演算何来匿名函数——匿名函数(匿名方法和Lambda)、委托、LINQ
    HTML 4.01 符号实体
    利用 IHttpModule 自定义 HTTP 处理模块
    数据结构单链表
    Ext.Net 1.2.0_Ext.Net.RendererFormat 常用数据格式转换呈现格式
    ASP.NET 以 Request.Querystring、Request.Form 或 Request.Params 获取客户端的数据
    Flex>连接WebService
    java.sql.SQLException: 关闭的连接
    jsp>SmartUpload相关类说明
    flex>样式和主题
  • 原文地址:https://www.cnblogs.com/fusae-blog/p/4256794.html
Copyright © 2011-2022 走看看