dup
和dup2
都可用來復制一個現存的文件描述符,使兩個文件描述符指向同一個file
結構體。如果兩個文件描述符指向同一個file
結構體,File Status Flag和讀寫位置只保存一份在file
結構體中,並且file
結構體的引用計數是2。如果兩次open
同一文件得到兩個文件描述符,則每個描述符對應一個不同的file
結構體,可以有不同的File Status Flag和讀寫位置。請注意區分這兩種情況。
#include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd);
如果調用成功,這兩個函數都返回新分配或指定的文件描述符,如果出錯則返回-1。dup
返回的新文件描述符一定該進程未使用的最小文件描述符,這一點和open
類似。dup2
可以用newfd
參數指定新描述符的數值。如果newfd
當前已經打開,則先將其關閉再做dup2
操作,如果oldfd
等於newfd
,則dup2
直接返回newfd
而不用先關閉newfd
再復制。
下面這個例子演示了dup
和dup2
函數的用法,請結合後面的連環畫理解程序的執行過程。
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
重點解釋兩個地方:
第3幅圖,要執行dup2(fd, 1);
,文件描述符1原本指向tty
,現在要指向新的文件somefile
,就把原來的關閉了,但是tty
這個文件原本有兩個引用計數,還有文件描述符save_fd
也指向它,所以只是將引用計數減1,並不真的關閉文件。
第5幅圖,要執行dup2(save_fd, 1);
,文件描述符1原本指向somefile
,現在要指向新的文件tty
,就把原來的關閉了,somefile
原本只有一個引用計數,所以這次減到0,是真的關閉了。