当前位置: 技术问答>linux和unix
dup2后的奇异现象
来源: 互联网 发布时间:2017-02-27
本文导语: 我写了这样一个程序: #include #include #include int main( ) { int fd = open("file", O_CREAT|O_WRONLY, 0644); int newfd = dup(1); dup2(fd, 1); close(fd); printf("hellon"); dup2(newfd, 1); printf("worldn"); return 0; } 本来...
我写了这样一个程序:
本来期待程序运行时会把"hellon"写入到文件file中,把"worldn"输出到屏幕上,但结果却是都在屏幕上。如果没有倒数第四行的dup2函数调用,就会都写入到文件file中。
跟踪系统调用的结果发现两个printf的输出的字符串内容被合在一起调用的write。也就是说,printf遇到n并没有清缓冲。
但更奇怪的问题在于,只要在main函数中第一个dup2调用之前的任何一行插入一个printf调用,后面的输出就不会合并,而是像我先前预期的那样把"hellon"写入到文件file中,把"worldn"输出到屏幕上了。
求高手解惑!
环境:ubuntu和fedora都是如此。
#include
#include
#include
int main( )
{
int fd = open("file", O_CREAT|O_WRONLY, 0644);
int newfd = dup(1);
dup2(fd, 1);
close(fd);
printf("hellon");
dup2(newfd, 1);
printf("worldn");
return 0;
}
本来期待程序运行时会把"hellon"写入到文件file中,把"worldn"输出到屏幕上,但结果却是都在屏幕上。如果没有倒数第四行的dup2函数调用,就会都写入到文件file中。
跟踪系统调用的结果发现两个printf的输出的字符串内容被合在一起调用的write。也就是说,printf遇到n并没有清缓冲。
但更奇怪的问题在于,只要在main函数中第一个dup2调用之前的任何一行插入一个printf调用,后面的输出就不会合并,而是像我先前预期的那样把"hellon"写入到文件file中,把"worldn"输出到屏幕上了。
求高手解惑!
环境:ubuntu和fedora都是如此。
|
#include
#include
#include
int main( )
{
printf("startn");
int fd = open("file", O_CREAT|O_WRONLY, 0644);
int newfd = dup(1);
dup2(fd, 1);
close(fd);
printf("hellon");
dup2(newfd, 1);
printf("worldn");
return 0;
}
我测了一下,manpage setvbuf了一下,得出结论,任意一个FILE*,在首次操作它的时候,它会fstat判断fd的类型,如果是文件就设置FILE为全缓冲,是终端就行缓冲,否则全缓冲。
这里你在第一次操作stdout时,它的fd已经是文件了,所以printf会做首次检测,设置它为全缓冲。
所以我在行首做了一个printf操作,让FILE先被设置为行缓冲,因为这是第一次操作stdout,并且fileno(stdout)是与终端关联的。
|
When the first I/O operation occurs
on a file, malloc(3) is called, and a buffer is obtained. If a stream refers to a terminal (as stdout normally does) it is line buffered. The standard
error stream stderr is always unbuffered by default.
|
楼上正确, ,
应该是由行缓冲变为了全缓冲。
验证如下:
至于你说的在第二个dup2前加个printf的话,hello 输出到文件,world输出到屏幕 的事。。 我试验了仍然是都输出到屏幕 。使用的环境是ubuntu 12.04 LTS.
理解这个行缓冲和全缓冲就行了。 不用太纠缠于太细节的东西 , 因为有些是和实现有关的。 若标准未规定, 则和各自的实现有关 (glibc库的实现)
应该是由行缓冲变为了全缓冲。
验证如下:
至于你说的在第二个dup2前加个printf的话,hello 输出到文件,world输出到屏幕 的事。。 我试验了仍然是都输出到屏幕 。使用的环境是ubuntu 12.04 LTS.
理解这个行缓冲和全缓冲就行了。 不用太纠缠于太细节的东西 , 因为有些是和实现有关的。 若标准未规定, 则和各自的实现有关 (glibc库的实现)
#include
#include
#include
int main( )
{
int fd = open("file", O_CREAT|O_WRONLY, 0644);
int newfd = dup(1);
dup2(fd, 1);
close(fd);
setlinebuf(stdout);
printf("hellon");
dup2(newfd, 1);
printf("worldn");
return 0;
}
|
怀疑是标准输出重定向到文件中之后,缓冲方式由原来的行缓冲变为了全缓冲
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。