使用dup2撤消stdout的重定向

时间:2013-01-24 11:15:02

标签: c++

以下代码将“A”和“B”写入文件“out.txt”,第一次调用打开返回3,第二次调用返回4。

我期望将“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;
}

1 个答案:

答案 0 :(得分:4)

评论来自this link;

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

使newfd成为oldfd的副本,必要时首先关闭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;