linux—dup和dup2重定向檔案描述符
利用函式dup,我們可以複製一個描述符。傳給該函式一個既有的描述符,它就會返回一【dup2】個新的現有的最小的未被使用的描述符,這個新的描述符是傳給它的描述符的拷貝。這意味著,這兩個描述符共享同一個資料結構,指的是檔案描述符所用的資料結構相同,不是檔案描述符相同。
程式碼如下: 在此例中,dup之前,先關掉1號描述符,對應的是標準輸出,所以dup後的new_dup就是1,1號檔案描述符原來是標準輸出,現在是./log,所以後面標準輸出的helloworld 都被列印在./log 檔案裡了。 結果如下:
dup2函式跟dup函式相似,但dup2函式允許呼叫者規定一個有效描述符和目標描述符的id【總結】。dup2函式成功返回時,目標描述符(dup2函式的第二個引數)將變成源描述符(dup2函式的
第一個引數)的複製品,換句話說,兩個檔案描述符現在都指向同一個檔案,並且是函式第一
個引數指向的檔案。
程式碼如下:
結果如下:
APUE和man文件都用一句話簡明的說出了這兩個函式的作用:複製一個現存的檔案描述符。
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
程序表項
————————————————fd標誌 檔案指標
_____________________
fd 0:|________|____________|------------> 檔案表
fd 1:|________|____________|
fd 2:|________|____________|
fd 3:|________|____________|
| ....... |
|_____________________|圖1
從圖1來分析這個過程,當呼叫dup函式時,核心在程序中建立一個新的檔案描述符,此
描述符是當前可用檔案描述符的最小數值,這個檔案描述符指向oldfd所擁有的檔案表項。
程序表項
————————————————fd標誌 檔案指標
_____________________
fd 0:|________|____________| ______
fd 1:|________|____________|----------------> | |
fd 2:|________|____________| |檔案表|
fd 3:|________|____________|----------------> |______|
| ....... |
|_____________________|圖2:呼叫dup後的示意圖
如圖2 所示,假如oldfd的值為1, 當前檔案描述符的最小值為3, 那麼新描述符3指向
描述符1所擁有的檔案表項。
dup2和dup的區別就是可以用newfd引數指定新描述符的數值,如果newfd已經開啟,則
先將其關閉。如果newfd等於oldfd,則dup2返回newfd, 而不關閉它。dup2函式返回的新
檔案描述符同樣與引數oldfd共享同一檔案表項。
APUE用另外一個種方法說明了這個問題:
實際上,呼叫dup(oldfd);
等效與
fcntl(oldfd, F_DUPFD, 0)而呼叫dup2(oldfd, newfd);
等效與
close(oldfd);
fcntl(oldfd, F_DUPFD, newfd);