gpt4 book ai didi

我可以假设 stdio 流在 dup2 之后指向正确的文件描述符吗?

转载 作者:行者123 更新时间:2023-11-30 15:35:42 25 4
gpt4 key购买 nike

我有一些代码,我想将特定的代码片段封装到 fork 的子级中,这样如果代码导致问题,它不会影响父级,并且父级将能够报告。

fork 调用之后我没有 execing。只需简单的 fork 即可运行通常在父级中运行的代码。

子级中的代码将内容输出到 stdoutstderr。由于交错输出和 stdio 缓冲的问题,我现在正在研究 TLPI以获得更好的解决方案。

我想出的想法大致是:

    每个流的
  • pipe()
  • fork()
  • child :
    • close() 读取管道末尾
    • dup2() 写入分别结束于 stdoutstderr 的文件描述符
    • setbuf(fd, NULL) 关闭子进程内的 stdio 流缓冲。
  • 在父级中:
    • close() 写入管道末端
    • 使用select/pselect/epoll等(必须在Linux、BSD、AIX、Solaris等上运行)来观察读取结束管道中的新数据,当它到达 write() 时,它会直接发送到父进程中相应的文件描述符。

现在,我推测子进程内的 dup2setbuf 之间缺少一步。它是什么?

setbuf 接受一个 FILE*,而 dup2 当然作用于 int

我想到了

freopen,但它需要一条路径。如果我只想为流分配一个新的文件号,我该怎么做?

最佳答案

extern 变量 stdinstdoutstderrFILE * 指针。您可以将它们传递给 setbuf/setvbuf。但是,请注意,子进程具有单独的地址空间,因此虽然它将继承 fork() 时缓冲区的状态,但两者都可以继续安全地使用缓冲区,并且如果您 fflush STDOUTSTDERR,输出缓冲区无论如何都是空的。

这是我在 child 中执行此操作的方式(未经测试,请添加一些错误处理):

void
child ( ... )
{
const char *devnull = "/dev/null";

/* turn off buffering */

setvbuf (stdin, NULL, _IONBF);
setvbuf (stdout, NULL, _IONBF);
setvbuf (stderr, NULL, _IONBF);

for (i = getdtablesize () - 1; i >= 0; i--)
{
if ((i != write_end_of_pipe1) && (i != write_end_of_pipe2))
close (i);
}

i = open (devnull, O_RDWR);
if (i == -1)
{
fprintf (stderr, "Unable to open /dev/null\n");
return;
}

i = open (devnull, O_RDONLY);
if (i != 0)
{
dup2 (i, 0);
close (i);
}

dup2 (write_end_of_pipe1, 1);
close (write_end_of_pipe1);

dup2 (write_end_of_pipe2, 2);
close (write_end_of_pipe2);

return;
}

关于我可以假设 stdio 流在 dup2 之后指向正确的文件描述符吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22837946/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com