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解決!
習題部分就作到這裏好了,或許有空會更新接下來的習題部分。