1. 程式人生 > >linux—dup和dup2重定向檔案描述符

linux—dup和dup2重定向檔案描述符

【dup】
利用函式dup,我們可以複製一個描述符。傳給該函式一個既有的描述符,它就會返回一

個新的現有的最小的未被使用的描述符,這個新的描述符是傳給它的描述符的拷貝。這意味著,這兩個描述符共享同一個資料結構,指的是檔案描述符所用的資料結構相同,不是檔案描述符相同。

程式碼如下:         在此例中,dup之前,先關掉1號描述符,對應的是標準輸出,所以dup後的new_dup就是1,1號檔案描述符原來是標準輸出,現在是./log,所以後面標準輸出的helloworld 都被列印在./log 檔案裡了。 結果如下:
【dup2】
  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);