2011-10-22 81 views
17

我知道dup,dup2,dup3「」(從手冊頁)創建文件描述符oldfd的副本。但是我無法消化它。有人可以解釋C中的dup()嗎?

因爲我知道文件描述符只是號碼來跟蹤文件位置及其方向(輸入/輸出)。難道這不是更容易

fd=fd2; 

每當我們想要複製文件描述符?

而且別的東西..

DUP()使用新的描述符的編號最小的未使用的描述符。

這是否意味着它也可以採取爲價值標準輸入標準輸出標準錯誤如果我們假定我們有close()方法 -ed其中的一個?

+3

對於你需要記住的是,內核保持數軌跡的第一個問題打開文件句柄。 'dup'是你告訴內核你想讓它跟蹤另一個文件句柄(指同一個文件)直到你關閉它的方式。 – user786653

回答

12

只是試圖迴應自己在第二個問題後試驗了一下。

答案是YES。如果標準輸入,標準輸出或標準錯誤都關閉,那麼您製作的文件描述符可以取值0,1,2。

例子:

close(1);  //closing stdout 
newfd=dup(1); //newfd takes value of least available fd number 

如果發生這種情況,文件描述符:

0 stdin  .--------------.  0 stdin  .--------------.  0 stdin 
1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd 
2 stderr '--------------'     '--------------'  2 stderr 
+1

問題再次出現:我該如何'dup()'我已經關閉的文件描述符? – Pithikos

+0

根據定義,dup()爲新描述符使用編號最小的未使用描述符。當你關閉一個文件描述符時,這意味着它可以使用。 –

2

看到這個page,標準輸出可以別名爲dup(1) ...

+0

+1。真棒鏈接 –

5

假設你正在寫一個shell程序和要重定向stdin和stdout中要運行的程序。它可能是這個樣子:

dup2(fdin, 0); 
dup2(fdout, 1); 

你爲什麼要究其原因:

fdin = open(infile, O_RDONLY); 
fdout = open(outfile, O_WRONLY); 
// Check for errors, send messages to stdout. 
... 
int pid = fork(0); 
if(pid == 0) { 
    close(0); 
    dup(fdin); 
    close(fdin); 
    close(1); 
    dup(fdout); 
    close(fdout); 
    execvp(program, argv); 
} 
// Parent process cleans up, maybe waits for child. 
... 

DUP2()是一個小更方便的方式來做到這一點的close()DUP()可以被替換要做到這一點,你要報告錯誤標準輸出(或標準錯誤),所以你不能關閉他們,並在子進程中打開一個新的文件。其次,如果open()調用返回錯誤,那麼執行fork會很浪費。

9

文件描述符比數字多一點。它也帶有各種半隱藏狀態(無論是否打開,它引用哪個文件描述,還有一些標誌)。 dup重複此信息,因此您可以獨立地關閉這兩個描述符。 fd=fd2沒有。

+1

這個。 「數字」是內核維護的數據結構的索引。函數的'dup'族克隆了該數據結構中節點的狀態,並將索引交給新節點。 – dmckee

+3

@dmckee:「內核」和「索引」是實現細節。有一些數據與「數字」相關聯,不能由程序直接操作,並且由'dup()'克隆。這就是程序員需要知道的全部內容。順便說一下,它不是一個非常有趣的數據,它只是一對標誌和一個非常有趣的數據(打開的文件描述)的索引,而不是由'dup()'克隆的。 –

5

有關DUP的一個最重要的事情()是它返回可用於新的文件描述符的最小整數。這就是重定向的基礎:

int fd_redirect_to = open("file", O_CREAT); 
close(1); /* stdout */ 
int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */ 
close(fd_redirect_to); /* we don't need this */ 

的事寫到文件描述符1(標準輸出)後,奇蹟般地進入「文件」。

+0

假設(不是無理)文件描述符0當前是打開的。如果沒有'dup2()'(或'dup3()',支持重定向如'200> somefile'是非常不方便的,但這是系統的最新增加)。 –

0

只是關於「重複標準輸出」的提示。

在一些Unix系統(而不是GNU/Linux)的

fd = open("/dev/fd/1", O_WRONLY); 

它相當於:

fd = dup(1);