2013-01-24 21 views
2

下面的代碼寫入兩個「A」和「B」的文件「out.txt」,與第一呼叫打開返回3和第二呼叫返回4.撤消標準輸出的重定向與DUP2

什麼我期望將「A」寫入文件,將「B」寫入屏幕。我也希望每個案例都能回到3。

我應該做些什麼來解決下面的代碼:

int main(int argc, char** argv) 
{ 
    int file = open("out.txt", O_APPEND | O_WRONLY); 
    if(file != 3) return 1; 

    if(dup2(file,1) < 0) return 1; 
    std::cout << "A" << std::endl; 

    if(dup2(1,file) < 0) return 1; 
    std::cout << "B" << std::endl; 

    file = open("out.txt", O_APPEND | O_WRONLY); 
    if(file != 3) return 1; 

    return 0; 
} 
+0

那麼,你再次打開文件。你爲什麼期望它再次返回3?這是一個新的文件描述符。另外,您不關閉文件3(都不是4)。 – leemes

回答

4

this link評論;

if(dup2(file,1) < 0) return 1; 

使得newfd是oldfd副本,如果necessary`

即第一閉塞newfd,它關閉stdout和使文件描述符1文件描述符的克隆3.

if(dup2(1,file) < 0) return 1; 

如果oldfd是有效的文件描述符,並且newfd與oldfd具有相同的值,則dup2()不執行任何操作,並返回newfd。

所以它什麼也不做,因爲文件描述符1具有相同的值作爲文件描述符3

file = open("out.txt", O_APPEND | O_WRONLY); 

會打開一個文件,下一個可用的文件描述符。由於文件描述符3正忙,它將(在這種情況下)使用4.

你想要做的事情更多的是沿着;

int stdoutCopy = dup(1);    // Clone stdout to a new descriptor 
if(dup2(file, 1) < 0) return 1;   // Change stdout to file 
close(file);       // stdout is still valid 
std::cout << "A" << std::endl; 
if(dup2(stdoutCopy,1) < 0) return 1; // Change stdout back from the clone 
close(stdoutCopy);      // Close the clone 
std::cout << "B" << std::endl;