免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: flyingbxf
打印 上一主题 下一主题

关于dup2()的疑问. [复制链接]

论坛徽章:
0
31 [报告]
发表于 2004-02-19 20:48 |只看该作者

关于dup2()的疑问.

原帖由 "kj501" 发表:

说错了,stdout应该是1,2是stderr。


说得对,我写错了, 应该是1

论坛徽章:
0
32 [报告]
发表于 2004-02-19 21:16 |只看该作者

关于dup2()的疑问.

原帖由 "kj501" 发表:
dup2函数执行时肯定会失败。
但从代码中也可以看出,我前面提出的先保存文件描述符,然后在重定向之后再恢复回来的思路是行得能的。
有不当之处,还请大家多多指教!


你对 dup2 的理解仍然有误, dup2 (a, b) 把 a 复制到 指定的“数字”(文件描述)上, 如果 b 是已打开的文件描述符, 先把 b 关掉(取消关联)。

你可以试一试, 把

  1. sfd = dup(testfd);
复制代码


注释掉,然后,很重要的一点,把 sfd 初始化为一个整数, 不要太大。我估计程序不会出错。

你试过后,请把结果告诉我。谢谢。

论坛徽章:
0
33 [报告]
发表于 2004-02-20 09:20 |只看该作者

关于dup2()的疑问.

原帖由 "win_hate" 发表:


我记得你是做嵌入式开发的,可能是环境不同。你换个台式机试一试可能就有这个问题。

我写错了,我的使用环境是uclinux,我在台式机上redhat8.0的环境下试了,不加fflush(stdout)果然全都输出到屏幕上了,文件里面没有写进去.不过我不明白能不能写进文件关缓冲什么事 呢?

论坛徽章:
0
34 [报告]
发表于 2004-02-20 14:36 |只看该作者

关于dup2()的疑问.

我来谈谈我的看法吧,我对这个问题还有一些疑问的

  1.                                                                                                                                              #include <stdio.h>;
  2. #include <unistd.h>;
  3.                                                                                                                                              
  4. int main(void)
  5. {
  6.         FILE *fp;
  7.         int fd, id;
  8.                                                                                                                                              
  9.         id = dup(STDOUT_FILENO);//这时id和STDOUT_FILENO一起指向stdout
  10.         if ((fp = fopen("install.log", "w")) == NULL) {
  11.                 perror("read error.\n");
  12.                 exit(-1);
  13.         }
  14.         fd = fileno(fp);//得到fp的文件描述符
  15.         dup2(fd, STDOUT_FILENO);//STDOUT_FILENO和stdout流断开,             //STDOUT_FILENO指向fd的对应文件,这样使输出到达fd的文件
  16.                                 //fd对应的是已经打开的文件install.log,//而stdout在这里指的是终端,现在任何的输入都输入到
  17.                                 //install.log中
  18.         printf("hello\n");
  19.                                                                                                                                              
  20.         fflush(stdout);//刷新stdout上的缓冲区,这样前面的hello写入文件//install.log中
  21.         dup2(id, STDOUT_FILENO);
  22.         printf("world\n");
  23.         fclose(fp);
  24.                                                                                                                                              
  25.         return 0;
  26. }

复制代码


以上的注释基本表达了我对这几个函数运用的了解,不过这里对fflush(stdout)的运用还有一点疑问,fflush(stream)刷新的是流stream上的缓冲,是不是可以理解为不论文件描述符STDOUT_FILENO定位到了哪个文件,stdout都保存有未写入文件的缓冲区的内容呢?按理来说,文件描述符比流更加底层才对呀

论坛徽章:
0
35 [报告]
发表于 2004-02-20 14:39 |只看该作者

关于dup2()的疑问.

倒,我的代码怎么在这里变得这么乱呀

论坛徽章:
0
36 [报告]
发表于 2004-02-20 22:32 |只看该作者

关于dup2()的疑问.

原帖由 "converse" 发表:

fflush(stdout);//刷新stdout上的缓冲区,这样前面的hello写入文件 install.log中
        dup2(id, STDOUT_FILENO);
        printf("world\n";
        fclose(fp);

原帖由 "converse" 发表:

不过这里对fflush(stdout)的运用还有一点疑问,fflush(stream)刷新的是流 stream上的缓冲,是不是可以理解为不论文件描述符STDOUT_FILENO定位到了哪个文件,stdout都保存有未写入文件的缓冲区的内容呢?按理来说,文件描述符比流更加底层才对呀


呵呵, 确实如此。 事实上,文件指针,比如说fp, 是根据fileno(fp)来对应文件的。你看上面的代码,STDOUT_FILENO 已经对应到 install.log,所以,当fflush(stdout)后, 缓冲内容写入文件 install.log。如果不fflush,执行
dup2 (id, STDOUT_FILENO), 这时 STDOUT_FILENO又对应回屏幕了, 然后缓冲中的内容和后来的数据都输到屏幕上了。

论坛徽章:
0
37 [报告]
发表于 2004-02-21 10:56 |只看该作者

关于dup2()的疑问.

原帖由 "win_hate" 发表:

注释掉,然后,很重要的一点,把 sfd 初始化为一个整数, 不要太大。我估计程序不会出错。

你试过后,请把结果告诉我。谢谢。

你的说法一点不错,我将

  1. sfd = dup(testfd);
复制代码

注释掉后,再将sfd初始化为0~1023之间的任何数,都可以执行成功。看来问题出在这一句:

  1. dup2(STDOUT_FILENO,sfd);
复制代码

我用的系统是linux(内核2.4.21),由于linux内核限制最大打开的文件总数为1024(这一点可能改进了,原来很多书上说的是最大只能打开256个文件),因此,dup2在执行时肯定会进行文件描述符的合法性检查,如果大于1023,肯定导致失败。sfd没有初始化时的值是由系统任意给出的(将sfd没有初始化的值打印出来,结果是1073817472),已经超出了1023的限制,从而导致dup2()执行失败。这才是问题的真正原因。其实在man文档中对错误原因说得很清楚:“oldfd  isn't  an  open  file  descriptor, or newfd is out of the allowed range for file descriptors.” 只是我自己没有认真看。
经过这次讨论,感觉自己对dup2()的理解加深不少,APUE上对dup2()的介绍对于全面理解这两个函数的使用并不充分。以后man文档一定要仔细看。
最后,非常感谢win_hate,希望以后能和你多多交流。

论坛徽章:
0
38 [报告]
发表于 2004-02-21 11:22 |只看该作者

关于dup2()的疑问.

这样针对一组函数功能的讨论真的可以提高很快,我也受益匪浅呀

建议斑竹加为精华

论坛徽章:
0
39 [报告]
发表于 2004-02-21 12:50 |只看该作者

关于dup2()的疑问.

[quote]原帖由 "kj501"]最后,非常感谢win_hate,希望以后能和你多多交流。[/quote 发表:


kj501 兄客气了, 这里我常来,期待与大家交流,向各位学习。

论坛徽章:
0
40 [报告]
发表于 2004-02-21 16:02 |只看该作者

关于dup2()的疑问.

我有一个不解的地方,就是freopen实现的功能也是把一个流重定向到另一个流去,它和dup、dup2的底层实现有什么不一样吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP