免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2604 | 回复: 0

fgets()报错问题(errno=4) [复制链接]

论坛徽章:
0
发表于 2007-11-23 15:15 |显示全部楼层
有一个获取进程个数的程序:
    sprintf(Cmd, "ps -ef|grep %s|grep %s|wc -l", prog, entr);
    fp = popen(Cmd, "r");
    if(fp == NULL) {
        printf("打开管道[%s]错\n", Cmd);
        return -1;
    }
    memset(buff, 0, sizeof(buff));
    if ( fgets(buff, 256, fp) == NULL ) {
        perror( "fgets:" );
        printf("fgets() error[%d][%ld]\n",i, (long)getpid() );
        pclose( fp );
        return -1;
    }

    。。。。。。

    pclose(fp);

    正常运行是没有问题的。但是如果捕获了SIGCHLD信号后,重复执行以上程序,则会不定时在fgets()

时报错:Interrupted system call(errno==4)。

    完整的程序代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<signal.h>
#include<unistd.h>
#include<errno.h>
#include<sys/wait.h>

struct   sigaction sa_old;
struct   sigaction sa_new;

/*------------------------------------------------------------------------
Function Name : agt_chld_exit
Description   : 子进程结束信号处理
Input         :
                _sign 捕捉到的信号
Output        :
Return        :
------------------------------------------------------------------------*/
void agt_chld_exit(int _sign)
{
    int    e = errno;
    int    stat = 0;
    pid_t  pid_tmp = 0;

    while((pid_tmp = waitpid(-1, &stat, WNOHANG)) > 0)
        printf("进程[%d]退出\n", pid_tmp);

    errno = e;

    return;
}

int
main()
{

    int i=0;

    FILE  *fp = NULL;
    char  Cmd[1025];
    char  buff[1025];
    char  prog[81];
    char  entr[9];
    int   Cnt = 0;
    int   ret = -1;

    memset(&sa_old, 0, sizeof(sa_old));
    memset(&sa_new, 0, sizeof(sa_new));

    signal(SIGPIPE, SIG_IGN);

    if(setpgrp() < 0) {
        printf( "setpgrp error.\n");
        exit(1);
    }

    signal(SIGPIPE, SIG_IGN);
    ret = sigemptyset(&sa_new.sa_mask);
    if(ret != 0) {
        printf( "SIGEMPTYSET RET=[%d]\n", ret);
        exit(1);
    }

    sa_new.sa_flags = 0;
    sa_new.sa_handler = agt_chld_exit;
    ret = sigaddset(&sa_new.sa_mask, SIGTERM);
    if(ret != 0) {
        printf( "SIGADDSET(SIGTERM) RET=[%d]\n", ret);
        exit(1);
    }

    ret = sigaddset(&sa_new.sa_mask, SIGCHLD);
    if(ret != 0) {
        printf("SIGADDSET RET=[%d]\n", ret);
        exit(1);
    }

    ret = sigaction(SIGTERM, &sa_new, &sa_old);
    if(ret != 0) {
        printf("SIGACTION RET=[%d]\n", ret);
        exit(1);
    }

    ret = sigaction(SIGCHLD, &sa_new, &sa_old);
    if(ret != 0) {
        printf("SIGACTION RET=[%d]\n", ret);
        exit(1);
    }

    memset(prog, 0, sizeof(prog));
    memset(Cmd, 0, sizeof(Cmd));
    memset(entr, 0, sizeof(entr));

    strcpy(prog, "aa");
    strcpy(entr, "bb");

while ( 1 ) {
    sprintf(Cmd, "ps -ef|grep %s|grep %s|wc -l", prog, entr);
    fp = popen(Cmd, "r");
    if(fp == NULL) {
        printf("打开管道[%s]错\n", Cmd);
        return -1;
    }
    memset(buff, 0, sizeof(buff));
    if ( fgets(buff, 256, fp) == NULL ) {
        perror( "fgets:" );
        printf("fgets() error[%d][%ld]\n",i, (long)getpid() );
        pclose( fp );
        return -1;
    }
    if ( strlen(buff) <= 0 ) {
        printf("fgets() buff== NULL\n" );
        pclose( fp );
        return -1;
    }

    pclose(fp);

    i++;
    if ( i > 30000 )
        break;
}

    return 0;
}

    如果不捕获SIGCHLD信号(把sigaction(SIGCHLD, &sa_new, &sa_old);那段屏蔽起来),fgets()就

不会报错;一旦放开,fgets()就会不定时报错(与SIGCHLD信号处理函数agt_chld_exit()中的处理没有

关系,即使agt_chld_exit()是个空函数,一样也会报错)。
    P.S,在tt.c中明明没有fork()子进程,怎么会收到SIGCHLD信号呢?是不是因为SIGCHLD是不可靠的

信号?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP