免费注册 查看新帖 |

Chinaunix

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

关于AIX5.2上的popen()函数大讨论! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-05-16 22:02 |只看该作者 |倒序浏览
在AIX5.2上测试程序,发现popen一个程序读的时候总是报被信号打断,所以写了个程序进行测试,发现当捕获SIGCHLD信号的时候,确实有这个问题,但在HP11.11和Linux 2.6内核下没有这个问题。
怀疑是主进程执行popen()的时候进行fork(),之后popen()返回,主进程接着read(),而子进程写入标准输出,也可能管道的数据有缓存,直到子进程退出close()的时候才往里写,或者写得太快,主进程还没来得及被唤醒,而子进程一退,发上发SIGCHLD信号给主进程,而主进程还在那儿read()呢,所以read()被中断,报中断错。
  1. #include <stdio.h>                /* printf() */
  2. #include <stdlib.h>                /* exit() */
  3. #include <unistd.h>                /* popen() */
  4. #include <errno.h>                /* errno */
  5. #include <string.h>                /* strerror() */

  6. static void open_read(char *pname);
  7. static void sig_child(int signo);

  8. int main(int argc, char *argv[])
  9. {
  10.         int i;
  11.         int ln;

  12.         ln = atoi(argv[2]);

  13.         signal(SIGCHLD, sig_child);
  14.         for(i = 0; i < ln; i++) {
  15.                 open_read(argv[1]);        
  16.         }

  17.         exit(EXIT_SUCCESS);        

  18.         return 0;
  19. }

  20. static void open_read(char *pname)
  21. {
  22.         int i;
  23.         char buf[BUFSIZ];
  24.         FILE *fp;
  25.         int r;

  26.         if ((fp = popen(pname, "r")) == NULL) {
  27.                 perror("popen");
  28.                 exit(EXIT_FAILURE);        
  29.         }
  30.         for(i = 0; i < BUFSIZ; i++) {
  31.                 if ((r = read(fileno(fp), buf, 1)) < 0) {
  32.                         perror("error read");
  33.                         exit(1);
  34.                 } else if (r > 0) {
  35.                         (void)fprintf(stdout, "read: %s\n", buf);
  36.                 } else {
  37.                         (void)fprintf(stdout, "read finished\n");
  38.                         break;
  39.                 }
  40.         }
  41.         if (pclose(fp) < 0) {
  42.                 perror("pclose");
  43.                 exit(EXIT_FAILURE);        
  44.         }
  45. }

  46. static void sig_child(int signo)
  47. {
  48.         fprintf(stderr, "receiving signal child\n");
  49. }
复制代码

[ 本帖最后由 lanying_wzw 于 2008-5-23 18:51 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-05-19 11:14 |只看该作者
怎么,没人关注吗?

论坛徽章:
0
3 [报告]
发表于 2008-05-21 15:23 |只看该作者
这么长时间了,还是没有人?

论坛徽章:
0
4 [报告]
发表于 2008-09-22 10:35 |只看该作者
解决了,AIX默认不会重起被中断的系统调用

论坛徽章:
0
5 [报告]
发表于 2008-09-22 10:36 |只看该作者
原帖由 lanying_wzw 于 2008-9-22 10:35 发表
解决了,AIX默认不会重起被中断的系统调用

学习了

论坛徽章:
0
6 [报告]
发表于 2008-09-22 11:11 |只看该作者
原帖由 lanying_wzw 于 2008-9-22 10:35 发表
解决了,AIX默认不会重起被中断的系统调用


楼主在linux 2.6下测试过吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP