【问题标题】:Error using pipes and exec.Second command does not exit使用管道时出错,exec.Second 命令不退出
【发布时间】:2012-10-30 18:16:20
【问题描述】:

代码将命令作为输入并执行它。管道也被处理。 问题是假设如果我输入 ls | grep x 作为命令。进程 grep 不退出,因此程序停止。任何想法。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
void parse(int *cont,char *command,char **exarg)
{
    char *x=strchr(command,'&');
    if(x!=NULL)
    {
        *cont=1;
        *(--x)='\0';
    }
    x=strtok(command," ");
    while(x!=NULL)
    {
        *exarg++=x;
        x=strtok(NULL," ");
    }
    *exarg='\0';
}

int divide(char *cmd,char **cmdarr)
{
    int i=0;
    char *x;
    x=strtok(cmd,"|");
    while(x!=NULL)
    {
        i++;
        *cmdarr++=x;
        x=strtok(NULL,"|");
    }
    *cmdarr='\0';
    return i;
}

void main()
{
    pid_t pid;
    int cont;
    int i=0;
    int orgnum;
    char *cmdarr[50];
    char c[50];
    int p1[2];
    int p2[2];
    char *argument[50];
    if(pipe(p1)<0)
        printf("error\n");
    if(pipe(p2)<0)
        printf("error2\n");
    for(;;)
    {
        printf("Enter the command:");
        gets(c);
        if(!strcmp("exit",c))
            break;
        orgnum=divide(c,cmdarr);
        printf("%d\n",orgnum);
        for(i=0;i<orgnum;i++)
        {
            pid=fork();
            if(pid==0)
            {
                if(i==0)
                {
                    close(p1[0]);
                    close(p1[1]);
                    close(p2[0]);
                    if((i+1)!=orgnum)
                    {
                        dup2(p2[1],STDOUT_FILENO);
                        dup2(p2[1],STDERR_FILENO);
                    }
                    close(p2[1]);
                    parse(&cont,cmdarr[i],argument);
                    if((execvp(argument[0],argument))<0)
                    {
                        printf("Wrong cmd");
                        exit(0);
                    }
                }
                else if(i>0)
                {
                    if((i+1)%2==0)
                    {
                        close(p1[0]);
                        close(p2[1]);
                        dup2(p2[0],STDIN_FILENO);
                        close(p2[0]);
                        if((i+1)!=orgnum)
                        {
                            dup2(p1[1],STDOUT_FILENO);
                            dup2(p1[1],STDERR_FILENO);
                        }
                        close(p1[1]);
                    }
                    else if((i+1)%2==1)
                    {
                        close(p2[0]);
                        close(p1[1]);
                        dup2(p1[0],STDIN_FILENO);
                        close(p1[0]);
                        if((i+1)!=orgnum)
                        {
                            dup2(p2[1],STDOUT_FILENO);
                            dup2(p2[1],STDERR_FILENO);
                        }
                        close(p2[1]);
                    }
                    parse(&cont,cmdarr[i],argument);
                    if((execvp(argument[0],argument))<0)
                    {
                        printf("Wrng cmd");
                        exit(0);
                    }
                }
            }
            else if(pid>0){
                close(p1[0]);
                close(p1[1]);
                close(p2[0]);
                close(p2[1]);
                wait(NULL);}
        }
    }
}

【问题讨论】:

    标签: c exec piping dup2


    【解决方案1】:

    所以你有循环:

    叉子 如果是孩子
    执行
    否则,如果是父母
    关闭管道
    等等

    当你有类似“ls | grep foo”的东西时,

    第 1 步:您在 child 中执行 ls, 并关闭所有管道,并在父级中等待“ls”终止,

    第 2 步:在子进程中执行 'grep',并使用管道作为输入,但在第 1 步中关闭它们。


    【讨论】:

    • 是的,因为在步骤 1 中的进程没有使用管道。第二个进程 'grep' 是一个全新的子进程,因为循环 for(i=0;i
    猜你喜欢
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 2014-06-07
    • 1970-01-01
    • 2011-10-15
    相关资源
    最近更新 更多