您的位置:首页 > 运维架构 > Linux

linux 关闭popen 打开的命令

2016-08-05 21:06 507 查看
程序设计了一个图形界面用于开了一个线程执行终端命令,通过pope打开一个管道来执行命令,

此时需要循环读取程序执行的结果。

void* command_exec(void* cmdstr)

{

     FILE *cmdStream=NULL;   

     char *cmd = (char *)cmdstr;    

     char buff[200];

     if(NULL==(cmdStream=popen(cmd,"r")))       

     {      

         fprintf(stderr,"execute command failed: %s",strerror(errno));       

         pthread_exit(NULL);       

     }

 

    while(fgets(buff,200, cmdStream)!=NULL)

    {

  

        g_printf("%s\n", buff);     

 

    }   

     pclose(cmdStream); 

    pthread_exit(NULL);   

}

由于命令一直都在执行,一直在while循环中 , 该线程不能结束,此时需要结束命令,通过pthread_kill结束线程来实现发现命令所起的进程并没有关闭,而且cmdSream文件流也没有正常close,   最后通过信号处理函数

void command_exit() {

    if(cmdStream != NULL) {

   

        pclose2(cmdStream);  

       cmdStream = NULL;

        pthread_exit((void *)2);

    }

}

关闭了管道,但是命令进程还是存在着,最后通过修改popen , pclose 函数源码自己实现结束进程来完成。

修改后的函数如下,在pclose 中添加了kill

#define SHELL "/bin/bash"

static pid_t *childpid=NULL;  /*ptr to array allocated at run-time*/

static int maxfd;  /*from our open_max(), {Prox openmax}*/

FILE *popen2(const char *cmdstring, const char *type)

{

    int i, pfd[2];

    pid_t pid;

    FILE *fp;

     

    /*only allow "r" or "w"*/

    if(type[0] != 'r' && type[0]!='w' || type[1] != 0) {

    errno=EINVAL;

        return (NULL);

    }

    if(childpid == NULL) {  /*first time throngh, allocate zeroed out array for child pids*/

       maxfd = sysconf(_SC_OPEN_MAX);

       if((childpid = calloc(maxfd, sizeof(pid_t))) == NULL)

           return(NULL);

    }

    if(pipe(pfd) < 0)

    return(NULL);  //errno set by pipe()

    if((pid = fork()) < 0)

    return(NULL);  //error set by fork()

    else if(pid==0) {  /*child*/

        if(*type == 'r') {

            close(pfd[0]);

            if(pfd[1] != STDOUT_FILENO) {

                dup2(pfd[1], STDOUT_FILENO);

                close(pfd[1]);

            }

        } else {

            close(pfd[1]);

            if(pfd[0] != STDIN_FILENO) {

                dup2(pfd[0], STDIN_FILENO);

                close(pfd[0]);

            }

        }

        /*close all descriptiors in childpid*/

        for(i = 0; i < maxfd; i++)

            if(childpid[i] > 0)

                close(i);

        execl(SHELL, "bash", "-c", cmdstring, (char *)0);

        _exit(127);

    }

    /*parent*/

    if(*type == 'r') {

        close(pfd[1]);

        if((fp = fdopen(pfd[0], type)) == NULL)

            return (NULL);

    }else {

        close(pfd[0]);

        if((fp = fdopen(pfd[1], type)) == NULL)

            return (NULL);

    }

    childpid[fileno(fp)] = pid; /*remember child pid for this fd*/

    return(fp);

}

int pclose2(FILE *fp)

{

    int fd, stat;

    pid_t pid;

    printf("hello>>>>>>>>>>>>>\n");

    if(childpid == NULL)  /*popen() has never benn called*/

        return (-1);

    fd = fileno(fp);

    if((pid = childpid[fd]) == 0)

        return (-1); //fp wasn't opened by popen()

    childpid[fd] = 0;

    if(fclose(fp) == EOF)

        return (-1);

        if( kill(pid, SIGKILL) != 0) {

            printf("kill failed\n");

            perror("kill");

        }

        else {

            printf("%d killed\n", pid);

        }

    while(waitpid(pid, &stat, 0) < 0) {

        if(errno != EINTR )

            return (-1); /*error other than EINTR from waitpid()*/

       

    }

    return(stat);

}

解决了问题、保持在图形界面上只执行一个命令进程并显示命令结果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: