Chinaunix首页 | 论坛 | 博客
  • 博客访问: 26164
  • 博文数量: 15
  • 博客积分: 415
  • 博客等级: 下士
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-05 20:42
文章分类

全部博文(15)

文章存档

2011年(9)

2010年(6)

我的朋友

分类: LINUX

2011-03-08 15:38:04

在写一个小测试程序时遇到了一个问题,代码如下
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <fcntl.h>

  4. int main()
  5. {
  6.    int tfd = -1;
  7.    int nfd = -1;

  8.    nfd = open("/dev/null", O_RDWR);

  9.    tfd = dup(STDOUT_FILENO);
  10. #if 1
  11.    printf("tfd is %d\n", tfd);
  12. #endif
  13.    dup2(nfd, STDOUT_FILENO);
  14.    printf("aaaaaaaaaaaaaaaaaa\n");
  15.    system("/bin/ls /tmp/");
  16.    dup2(tfd, STDOUT_FILENO);
  17.    close(tfd);
  18.    close(nfd);

  19.    printf("bbbbbbbbbbbbbbbbbb\n");

  20.    return 0;
  21. }

上述代码的输出为

[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跟踪程序的系统调用,发现确实如上所述

 

阅读(473) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~