c-为什么将stdout重定向到memfd_create()的结果似乎只有在事先使用stdout的情况下才有效



我在64位机器上运行Ubuntu 20.04。

我想将stdout重定向到从memfd_create获得的描述符。使用memfd_create创建的匿名文件似乎只有在stdout在用于重定向的dup2()之前获得非空输出的情况下才能获得内容。为什么?

这是SSCCU:

#define _GNU_SOURCE        
#include <sys/mman.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
int main() {
int temp_fd = memfd_create("temp", 0);
struct stat sb;
printf("an");
dup2(temp_fd, 1);
printf("bn");
fstat(temp_fd, &sb);
fprintf(stderr, "%lun", sb.st_size);
}

在这里,正如预期的那样,当bn到达匿名文件时,将打印2。

但是,如果我们删除printf("an");则打印0。

为什么?

如果我们用fflush(stdout)printf("")替换printf("an"),则仍然打印0。

如果我们用printf("a");替换,则如预期的那样打印3。

似乎必须在dup2之前将非空字符串打印到stdout

编辑(答案后(:memfd_create()的相关性是什么?好吧,如果没有这个,输出文件就不是匿名的和不稳定的,所以我只是在之后手动检查了结果,一切都很好。

您的libc版本似乎会在第一次打印内容之前检查FD 1是否是终端。如果它是一个终端,它会设置行缓冲,因此每次打印新行时都会刷新缓冲区。否则,将进行完全缓冲,因此只有在满时才会刷新。

这并不能保证行为。这正是安装在您计算机上的libc版本的作用。

如果您想在任何特定时间刷新缓冲区,可以使用fflush(stdout)。也可以使用setvbuf设置特定的缓冲模式。

相关内容

最新更新