popen()/pclose()阻塞性问题验证

 背景:

popen()函数通过创建一个管道,调用fork()产生一个子进程,执行一个shell以运行命令来开启一个进程。这个管道必须由pclose()函数关闭,而不是fclose()函数。

pclose()函数关闭标准I/O流,等待命令执行结束,然后返回shell的终止状态。如果shell不能被执行,则pclose()返回的终止状态与shell已执行exit一样。

而子进程的退出状态,常用以下几个宏进行获取。

1、 WIFEXITED(status) 若此值为非0 表明进程正常结束。

若上宏为真,此时可通过WEXITSTATUS(status)获取进程退出状态(exit时参数)

示例:

        if(WIFEXITED(status)){

            printf("退出值为 %d\n", WEXITSTATUS(status));

        }

2、 WIFSIGNALED(status)为非0 表明进程异常终止。

若上宏为真,此时可通过WTERMSIG(status)获取使得进程退出的信号编号

示例:

    if(WIFSIGNALED(status)){

        printf("使得进程终止的信号编号: %d\n",WTERMSIG(status));  

}

验证内容:

主要确认以下几点:

1,  WEXITSTATUS等宏,能否正确取得shell退出状态?

2,  popen之后直接调用pclose是否会等待命令执行结束?

3,  如果没有pclose,会如何?

 验证代码:

测试用代码如下:

复制代码
#include <stdio.h> #include <sys/wait.h>int main(void) {         int iRet = 0;         FILE *fp = NULL;         char buff[512] = {'\0'};          fp = popen("./test.sh", "r");         if (NULL == fp)         {                 printf("popen failed.\n");                 return 1;         } /*         while(fgets(buff, sizeof(buff), fp) != NULL)         {                 printf("%s", buff);         } */         iRet = pclose(fp);         printf("iRet = %d\n", iRet);         printf("wifexited : %d\n", WIFEXITED(iRet));         printf("wifsignaled : %d\n", WIFSIGNALED(iRet));         printf("wifstopped : %d\n", WIFSTOPPED(iRet));         //if (WIFEXITED(iRet))                printf("exit :%d\n", WEXITSTATUS(iRet));         //if (WIFSIGNALED(iRet))                printf("signal :%d\n", WTERMSIG(iRet));          return 0; }
复制代码

被调用的脚本如下:

复制代码
#!/bin/sh  #echo "before..."        #注意,echo被注释掉,即,不会输出。 sleep 30  #echo "after..."  exit 1
复制代码

 

结果:

50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信