I'm trying to create a simple shell in C for Unix. I've been able to do all the parsing of commands and execution, but I'm having a problem with piping. I think the problem is that I'm not hooking into the correct pipe for the input of the second command.

我正在尝试在C中为Unix创建一个简单的shell。我已经能够完成所有命令和执行的解析,但是我遇到了管道问题。我认为问题是我没有连接到正确的管道输入第二个命令。

For example, if I type "ls | wc", it will pause after the "wc" command, which I think is because its waiting for input. I think the problem is when I use dup2(reading[i],0), and its not hooking into the correct pipe.

例如,如果我输入“ls | wc”,它将在“wc”命令之后暂停,我认为这是因为它等待输入。我认为问题是当我使用dup2(读取[i],0),并且它没有挂钩到正确的管道时。

I know this is a bit of a broad question, but if there are any pointers I could get, I would appreciate it. Here is the code that creates new processes and tries to pipe them.

我知道这是一个广泛的问题,但如果有任何指示我可以得到,我会很感激。这是创建新进程并尝试管道它们的代码。

    int fileds[2];
    int reading[num_cmds];
    int writing[num_cmds];

    int p;
    for(p=0; p < num_cmds; p++)
    {
        reading[p] = -1;
        writing[p] = -1;
    }

    int j;
    for(j=0; j < num_cmds-1; j++)    //Create pipes for commands
    {
        int fileds[2];
        pipe(fileds);
        reading[j+1] = fileds[0];
        writing[j] = fileds[1];
    }

    int i = 0;
    for(i = 0; i < num_cmds;i++)
    {           
        cmd_args = parse_cmd(cmds[i],output_file,input_file,&run_bg); //Get command and args

        pid_t childpid;
        int status;
        childpid=fork();

        if (childpid >= 0) 
        {
            if (childpid == 0) 
            {               
                if(writing[i] != -1)
                {
                    dup2(writing[i],1);
                    close(writing[i]);
                }

                if(reading[i] != -1)
                {
                    dup2(reading[i],0);
                    close(reading[i]);
                }

                int h;
                for(h = 0; h < num_cmds; h++)
                {
                    close(writing[h]);
                    close(reading[h]);
                }

                if(execvp(cmd_args[0],cmd_args) == -1) 
                {
                    perror("Problem with command");
                    exit(0);
                }
            }
            else 
            {
                wait(&status);
                int m;
                for(m = 0; m < num_cmds; m++)
                {
                    if( writing[m] != -1) close(writing[m]);
                    if( reading[m] != -1) close(reading[m]);
                }
            }
        }
        else 
        {
             perror("fork"); 
             continue;
        }


        input_file[0] = 0;
        output_file[0] = 0;
        run_bg = 0;
    }

}



UPDATE: I was able to figure it out, thanks to Richard. It was a combination of closing the file descriptors in the wrong order and not closing some at all. Here's the working code.

更新:感谢理查德,我能够弄明白。它是以错误的顺序关闭文件描述符而根本不关闭某些文件描述符的组合。这是工作代码。

int fileds[2];
    int reading[num_cmds];
    int writing[num_cmds];

    int p;
    for(p=0; p < num_cmds; p++)
    {
        reading[p] = -1;
        writing[p] = -1;
    }

    int j;
    for(j=0; j < num_cmds-1; j++)
    {
        int fileds[2];
        pipe(fileds);
        reading[j+1] = fileds[0];
        writing[j] = fileds[1];
    }

    int i = 0;
    for(i = 0; i < num_cmds;i++)
    {           
        cmd_args = parse_cmd(cmds[i],output_file,input_file,&run_bg);

        pid_t childpid;
        int status;
        childpid=fork();

        if (childpid >= 0) 
        {
            if (childpid == 0) 
            {               
                if(writing[i] != -1)
                {
                    close(1);
                    dup2(writing[i],1);
                }

                if(reading[i] != -1)
                {
                    close(0);
                    dup2(reading[i],0);
                }

                if(execvp(cmd_args[0],cmd_args) == -1) 
                {
                    perror("Problem with command");
                    exit(0);
                }
            }
            else 
            {

                wait(&status);
                close(writing[i]);

                if(i > 0) 
                {
                    close(reading[i]);
                }
            }
        }
        else 
        {
             perror("fork");
        }


        input_file[0] = 0;
        output_file[0] = 0;
        run_bg = 0;
    }

2 个解决方案

#1


2

I think your problem may be that you wait for each process inside the loop and then close all the file descriptors. This makes the file descriptors invalid for the next call to dup2() and results in stdin for the next process staying unchanged.

我认为您的问题可能是您等待循环内的每个进程,然后关闭所有文件描述符。这使得文件描述符对于下一次调用dup2()无效,并导致stdin使下一个进程保持不变。

Just a guess, I haven't run the code.

只是一个猜测,我没有运行代码。

更多相关文章

  1. 检查通过程序的C管道 - 边界情况
  2. 如何使用Angular.js从json文件中使用id获取特定数据
  3. 如何从一个节点生成exe文件。js应用?
  4. 在批处理文件中使用JSMin
  5. 使用HTML文件中的React调用.js文件中的Javascript函数
  6. 在JavaScript中进行文件处理,第四部分:对象URLs
  7. [转]在网页中加入声音文件,并且用JavaScript对其进行播放控制
  8. 基于缓冲区数据创建文件
  9. 怎么javascript读取本地文件中的数据,并显示在html上

随机推荐

  1. Android(安卓)的属性分析
  2. Android和Linux kernel发展史
  3. Android图形合成和显示系统---基于高通MS
  4. Android电源管理系列之PowerManagerServi
  5. 自定义gradle插件
  6. Android 自定义Menu
  7. android AlarmManager 的相關應用
  8. Android(安卓)选择图片、上传图片之Pictu
  9. 让Activity变成一个窗口:Activity属性设定
  10. android handler