免费注册 查看新帖 |

Chinaunix

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

关于dup2的疑惑~ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-09-08 17:03 |只看该作者 |倒序浏览
  1. #include<myhead.h>

  2. int main(){
  3.    int fd;
  4.    if((fd=open("tmp",O_WRONLY|O_TRUNC))<0){
  5.       perror("open error");
  6.    }

  7.    printf("%d %d\n",fd,STDOUT_FILENO); //出问题的代码
  8.    if(dup2(fd,STDOUT_FILENO)==-1){
  9.       perror("dup2() error");
  10.    }
  11.    close(fd);
  12.    printf("test dup2(2)\n");
  13.    close(STDOUT_FILENO);
  14.    exit(0);
  15. }
复制代码

出现问题的代码如上,我把带有注释的那行代码注释掉以后,tmp文件里面是空的,但是标准输出已经被重定向到了tmp文件,文件里面应该是"test dup2(2)"才对。当带有注释的代码有效的时候,结果确是对的。请问一下各位是哪里出了问题?
注:myhead.h是我自己为了方便而写的头文件,里面就include了一对常用的头文件,另外,tmp文件需先建立。另外,开发环境是ubuntu 7.04

[ 本帖最后由 ddvv 于 2007-9-8 18:08 编辑 ]

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2007-09-08 17:56 |只看该作者
到底哪一行代码被注释了?

论坛徽章:
0
3 [报告]
发表于 2007-09-08 18:32 |只看该作者
原帖由 isnowran 于 2007-9-8 18:30 发表

不要去做行为未定义的事情...


什么意思?

论坛徽章:
0
4 [报告]
发表于 2007-09-08 19:04 |只看该作者
原帖由 isnowran 于 2007-9-8 18:45 发表
把一个描述符关闭两次, 即使系统打印一段汉诺塔的移动过程, 我也不觉得稀奇, 嘻嘻


调用dup2(fd,STDOUT_FILENO)以后,原来的标准输出被关闭了,然后被定向到fd所指向的文件,这不是相当于tmp文件被打开了两次了吗?分别关闭fd和STDOUT_FILENO有什么错了么?不知道我这样理解是不是错了。另外,这个问题和汉诺塔有什么关系么?谢谢~

论坛徽章:
0
5 [报告]
发表于 2007-09-08 19:50 |只看该作者
原帖由 isnowran 于 2007-9-8 19:19 发表


看看, 你自己说 '原来的标准输出被关闭了',  再说 '分别关闭fd和STDOUT_FILENO' , 不矛盾么? STDOUT_FILENO 被关闭了两次.


呵呵,我不觉得矛盾哦,虽然它们的名字是一样的的。这里的STDOUT_FILENO只不过是一个数字而已,代表的仅仅是某个进程的一个文件描述符。
两次关闭的STDOUT_FILENO指向的是不同的文件,开始的时候是标准输出,后来是tmp文件。

论坛徽章:
0
6 [报告]
发表于 2007-09-08 20:44 |只看该作者
楼主的做法应该没错。但是需要在close  STDOUT_FILENO 前先 fflush(stdout)

我是在freebsd6.0 上试的,现象和楼主一模一样。后来google了一下,有人提到缓冲的问题,我就在close 之前fflush了一下。结果就可以了。

想不明白的是:
1 close的时候应该会自动清空缓冲区;
2 程序结束的时候也应该会清空缓冲呀。

在 comp.unix.programmer 也有不少讨论,不过没有看到令人信服的解答。

[ 本帖最后由 lgfang 于 2007-9-8 21:26 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2007-09-08 22:20 |只看该作者
恩,原来是缓冲的问题。感谢lgfang和isnowran的解释。
不过我还是搞不懂为什么加了前面加了一句printf以后就一切正常了呢?(也就是加上我说有问题的那句)是不是加上一句printf以后,后面那句printf执行以后就自动把stdout中的缓冲区flush了呢?

论坛徽章:
0
8 [报告]
发表于 2007-09-08 22:22 |只看该作者
原帖由 ddvv 于 2007-9-8 19:50 发表


呵呵,我不觉得矛盾哦,虽然它们的名字是一样的的。这里的STDOUT_FILENO只不过是一个数字而已,代表的仅仅是某个进程的一个文件描述符。
两次关闭的STDOUT_FILENO指向的是不同的文件,开始的时候是标准输出 ...

今天睡多了, 有点迟钝, 勿怪
猜测:
printf 使用的是stdout, 写入的东西在struct FILE的缓冲里, 而你关闭的是STDOUT_FILENO, 也就是 FILE结构中引用的文件描述符已经在同步到文件前无效了 (因为描述符当前指向的为块设备, 并不会因为\n 刷新缓冲), 你可以把 close( STDOUT_FILENO ) 替换为 fclose( stdout ) 应该能看到正确的结果.

论坛徽章:
0
9 [报告]
发表于 2007-09-08 22:35 |只看该作者

还素不明白。。。。。

论坛徽章:
0
10 [报告]
发表于 2007-09-08 23:54 |只看该作者
我对dup2也是很迷惑啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP