如何在 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
第 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