CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Linux/Unix社区 >  程序开发区

关于POPEN的问题! (dup2 )

楼主kofiory(幽灵)2006-08-03 14:39:33 在 Linux/Unix社区 / 程序开发区 提问

写了个POPEN的函数,是在库函数的基础上修改的,但里面我有几个问题不明白:  
  FILE*   my_popen(   const   VB   *inCommand,   const   VB   *inMode,   pid_t   *outPid   )  
  {  
  INT aPipedes[2];  
  FILE* apStream =   NULL;  
  FILE* outRet =   NULL;  
  INT aSubRet =   0;  
  INT aErrNo =   0;  
  pid_t aPid =   0;  
   
  if(   (   inCommand   ==   NULL   )   ||    
  (   inMode   ==   NULL   )   ||    
  (   *inMode   !=   'r'   &&   *inMode   !=   'w'   )   )  
  {  
  outRet   =   NULL;  
  goto   ERR_END;  
  }  
   
  /*   Create   the   pipe.     */  
  aSubRet   =   pipe(   aPipedes   );  
  if(   aSubRet   <   0   ){  
  outRet   =   NULL;  
  goto   ERR_END;  
  }  
   
  /*   Fork   off   the   child.     */  
  aPid   =   fork();  
  if(   aPid   ==   (pid_t)-1   ){  
  /*   The   fork   failed.     */  
  (void)close(   aPipedes[0]   );  
  (void)close(   aPipedes[1]   );  
  outRet   =   NULL;  
  goto   ERR_END;  
          }   else   if(   aPid   ==   (pid_t)0   )  
  {  
  /*   We   are   the   child   side.     Make   the   write   side   of  
  the   pipe   be   stdin   or   the   read   side   be   stdout.     */  
  const   VB   *new_argv[4];  
   
  if(   (   *inMode   ==   'w'   ?   dup2(   aPipedes[STDIN_FILENO],   STDIN_FILENO   )   :    
  dup2(   aPipedes[STDOUT_FILENO],   STDOUT_FILENO   )   )   <   0   ){  
  _exit   (127);  
  }  
   
  /*   Close   the   pipe   descriptors.     */  
  (void)   close   (aPipedes[STDIN_FILENO]);  
  (void)   close   (aPipedes[STDOUT_FILENO]);  
   
  /*   Exec   the   shell.     */  
  new_argv[0]   =   SH_NAME;  
  new_argv[1]   =   "-c";  
  new_argv[2]   =   inCommand;  
  new_argv[3]   =   NULL;  
   
  (void)   execve   (SH_PATH,   (VB   *const   *)   new_argv,   __environ);  
   
  /*   Die   if   it   failed.     */  
  _exit   (127);  
          }  
   
  /*   We   are   the   parent   side.     */  
  *outPid   =   aPid;  
   
  /*   Close   the   irrelevant   side   of   the   pipe   and   open   the   relevant   side   as   a    
  new   stream.     Mark   our   side   of   the   pipe   to   close   on   exec,   so   new   children    
  won't   see   it.     */  
  if   (*inMode   ==   'r')  
  {  
  (void)   close   (aPipedes[STDOUT_FILENO]);  
  (void)   fcntl   (aPipedes[STDIN_FILENO],   F_SETFD,   FD_CLOEXEC);  
  apStream   =   fdopen   (aPipedes[STDIN_FILENO],   inMode);  
          }  
  else  
          {  
  (void)   close   (aPipedes[STDIN_FILENO]);  
  (void)   fcntl   (aPipedes[STDOUT_FILENO],   F_SETFD,   FD_CLOEXEC);  
  apStream   =   fdopen   (aPipedes[STDOUT_FILENO],   inMode);  
          }  
   
  if(   apStream   ==   NULL   )  
  {  
  /*   The   stream   couldn't   be   opened   or   the   child   structure   couldn't   be    
  allocated.     Kill   the   child   and   close   the   other   side   of   the   pipe.     */  
  (   void   )kill(   *outPid,   SIGKILL   );  
  (   void   )close(   aPipedes[   *inMode   ==   'r'   ?   STDOUT_FILENO   :   STDIN_FILENO   ]   );  
  (   void   )waitpid(   *outPid,   (INT   *)   NULL,   0   );  
  outRet   =   NULL;  
  goto   ERR_END;  
  }  
   
  outRet   =   apStream;  
   
  ERR_END:  
  return   outRet;  
   
  }  
   
  函数代码已经贴出,编译无任何问题,可正常使用.  
  (1):  
  if(   (   *inMode   ==   'w'   ?   dup2(   aPipedes[STDIN_FILENO],   STDIN_FILENO   )   :    
  dup2(   aPipedes[STDOUT_FILENO],   STDOUT_FILENO   )   )   <   0   ){  
  _exit   (127);  
  }  
  此段代码中,dup2使用时候,怎么可以用宏做为参数啊?不是2个参数都要INT型吗?  
   
  (2):   当apStream   ==   NULL时,KILL掉子进程后,为何还要执行WAITPID,而且,CLOSE不也执行多了吗?后面的不就多余执行了吗? 问题点数:20、回复次数:4Top

1 楼LunTanZeng(筱淼)回复于 2006-08-03 17:08:50 得分 0

sfTop

2 楼kofiory(幽灵)回复于 2006-08-04 11:18:17 得分 0

问题1,我自己已经想明白了  
  关于问题2我还不明白啊@!Top

3 楼Ropyn(剑心)回复于 2006-08-04 14:44:06 得分 0

kill(   *outPid,   SIGKILL   );  
  这行并不能真正杀死子进程,它只是让进程进入zombie状态,PCB也没有回收,并让子进程发送SIGCHLD给父,期待父来回收PCB.  
  所以后面还要用waitpid来回收zombie进程的PCB(进程控制块)  
  Top

4 楼gettext(冰雪之崖)回复于 2006-08-05 00:48:42 得分 0

pipe()打开的是两个file   descriptors,父子进程各用一个。   kill()之前close()的是自己不用的,kill()之后close()的是自己用的。  
  kill()之后的waitpid()是为了释放子进程的资源。  
  man   waitpid  
                The   waitpid   function   suspends   execution   of   the   current   process     until  
                a     child   as   specified   by   the   pid   argument   has   exited,   or   until   a   sig-  
                nal   is   delivered   whose   action   is   to   terminate   the   current   process     or  
                to     call     a   signal   handling   function.     If   a   child   as   requested   by   pid  
                has   already   exited   by   the   time   of   the   call   (a   so-called   "zombie"   pro-  
                cess),     the     function   returns   immediately.     Any   system   resources   used  
                by   the   child   are   freed.  
  Top

相关问题

关键词

得分解答快速导航

  • 帖主:kofiory

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo