免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3984 | 回复: 1
打印 上一主题 下一主题

标准输出被重定向后, 恢复不了 [复制链接]

论坛徽章:
0
1 [报告]
发表于 2009-02-07 15:19 |显示全部楼层
原帖由 spiritX 于 2009-2-6 16:09 发表
我的步骤是:
1. 保存标准输出(dup2);
2. 重定向标准输出到一个管道;
3. 利用(1)保存的恢复标准输出;

但是然后用printf竟然没有打印出来, 怎么回事 ?有哪些可能的原因 ?



可能是c库缓存机制的问题,你试试在printf之后加一句fflush(stdout)看看怎么样

论坛徽章:
0
2 [报告]
发表于 2009-02-07 15:35 |显示全部楼层
原帖由 zhuhefang2006 于 2009-2-6 18:40 发表
当STDOUT_FILENO被重定向到fd[1]以后,变成了全缓冲模式
所以  printf("this will not appear STDOUT_FILENO\n");里的“this will not appear STDOUT_FILENO\n”将会保存至缓冲区中
后来STDOUT_FILENO被恢复到 ...


差不多吧,但不完全准确,开始时"this will not appear STDOUT_FILENO"没打印出来确实是因为全缓存,但之后它打印出来并不是因为
dup2(fdcopy, STDOUT_FILENO)使stdout恢复成行缓存,它这时还是全缓存,包括下一句"write to STDOUT_FILENO"都还是保存在C库的缓存中,最后显示出来是因为进程退出时C库才进行的刷新,你可以在return前加一条sleep(x)验证一下。

我没有读glibc的源码,但根据strace分析了一下,似乎glibc只是在第一次printf时去检查stdout的类型,并且之后就认为stdout是这个类型了。由于你第一次在调用printf时,stdout已经被重定向到了管道,因此glibc就认为stdout是管道了,因此之后都进行全缓存。如果你在第一次dup2(STDOUT_FILENO, fdcopy)前就先printf一下,那么glibc就会认为stdout是终端而进行行缓存了,之后还是那些代码打印出来的结果就会完全不同。

以上仅是我根据strace的推测,希望了解glibc代码的兄弟确认一下。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP