在写一个小测试程序时遇到了一个问题,代码如下
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- int main()
- {
- int tfd = -1;
- int nfd = -1;
- nfd = open("/dev/null", O_RDWR);
- tfd = dup(STDOUT_FILENO);
- #if 1
- printf("tfd is %d\n", tfd);
- #endif
- dup2(nfd, STDOUT_FILENO);
- printf("aaaaaaaaaaaaaaaaaa\n");
- system("/bin/ls /tmp/");
- dup2(tfd, STDOUT_FILENO);
- close(tfd);
- close(nfd);
- printf("bbbbbbbbbbbbbbbbbb\n");
- return 0;
- }
上述代码的输出为
[root@/tmp/test]# ./a.out
tfd is 4
bbbbbbbbbbbbbbbbbb
但是如果把第一个printf语句注释掉的话,输出为
[root@/tmp/test]# ./a.out
aaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbb
并没有如想象中那样“标准输出已经被重定向到/dev/null,aaaa就应该看到不了”
之后经过请教高人发现,原因如下:
1 printf是行缓存
2 printf第一次调用write()时会调用fstat(1)看1是否打开
3 如果1没有打开,缓存保留
4 第二次调用printf时就不用fstat()检查了
后来通过strace跟踪程序的系统调用,发现确实如上所述
阅读(506) | 评论(0) | 转发(0) |