如何在 C 中回滚重定向的 stdio?

How to rollback redirected stdio in C?

第 1 轮

从一些示例中,我知道如何将 stdio 重定向到 null。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fd = open("/dev/null", O_RDWR);
    int in, out, err;

    if (fd < 0) {
        perror("open file error!");

        return -1;
    }

    printf("test1\n");

    dup2(fd, STDIN_FILENO);
    dup2(fd, STDOUT_FILENO);
    dup2(fd, STDERR_FILENO);

    printf("test2\n");

    close(fd);

    return 0;
}

执行代码后,我的控制台显示:

test1

test2 被重定向到 /dev/null。

但是,现在,我想将 stdio 从 /dev/null 回滚到标准输入和输出。

我该怎么做?

第 2 轮

感谢您的回复。

实际上,我遇到了一个程序重定向 stdio(例如示例 1)并 fork 我的程序(例如示例 2)的问题。

示例 1
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fd = open("/dev/null", O_RDWR);

    if (fd < 0) {
        perror("open file error!");

        return -1;
    }

    printf("test1\n");

    dup2(fd, STDIN_FILENO);
    dup2(fd, STDOUT_FILENO);
    dup2(fd, STDERR_FILENO);

    execl("hello_world", NULL);

    close(fd);

    return 0;
}
示例 2
#include <stdio.h>

int main()
{
    printf("Hello World!\n");

    return 0;
}

在我 运行 示例 1 之后,我的控制台显示:

test1

如何更改示例 2 以将 printf() 重定向到控制台? 谢谢。

一个简单的解决方案是使用 dup 保存初始文件描述符(您不应假设它们是相同的),然后稍后使用 dup2.

恢复它们

只要你有一个控制终端(/dev/null 习惯用法所暗示的),你应该能够将输出重定向到 /dev/tty.

但是你应该知道真正的守护进程,比如从 cron 启动的那个,没有控制终端,在那种情况下 /dev/tty 不会被定义。

对于你的第 2 轮问题,exec 调用和类似的保留打开的文件描述符,这意味着你需要恢复你在调用 execl 之前所做的事情,请参阅此示例以了解如何 save/restore 它们: Re-opening stdout and stdin file descriptors after closing them