使用 dup2 撤消标准输出的重定向

Undo redirect of stdout with dup2

本文关键字:重定向 标准输出 撤消 dup2 使用      更新时间:2023-10-16

下面的代码将"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;
}

从此链接发表评论;

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;