我在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
设置特定的缓冲模式。