《APUE》第三章筆記(4)及習題3-2

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解決!

習題部分就作到這裏好了,或許有空會更新接下來的習題部分。

相關文章
相關標籤/搜索