【问题标题】:How to rollback redirected stdio in C?如何在C中回滚重定向的stdio?
【发布时间】:2016-01-26 05:51:10
【问题描述】:

第一轮

通过一些例子,我知道如何将 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 回滚到标准输入和输出。

我该怎么做?

第二轮

感谢您的回复。

实际上,我遇到了一个程序重定向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() 重定向到控制台? 谢谢。

【问题讨论】:

  • 我不确定在每种情况下都可以做到这一点。例如,一旦文本被传送到 Windows 控制台,除非您手动清除屏幕,否则它会一直存在。

标签: c libc


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    如果您确实有一个控制终端(/dev/null 惯用语所暗示的),您应该能够将输出重定向到 /dev/tty

    但您应该知道,真正的守护进程(例如从 cron 启动的守护进程)没有控制终端,在这种情况下,/dev/tty 不会被定义。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-05
        • 1970-01-01
        相关资源
        最近更新 更多