在管持续execvp? [英] Persistent execvp on pipe?

查看:171
本文介绍了在管持续execvp?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作我的操作系统级的转让(POSIX和C),建设一个小型的外壳,我不知道如何解决以下问题:

我的迷你外壳不得不接受两个命令,例如 LS |用grep一个。对于我创建大小两个孩子的管道。孩子关闭所有它必须关闭,并打开自己的一切所有,打开(标准​​/管在与放大器;出)。随后,它执行的ls,使用execvp。我相信这效果很好。之后,父母关上了,打开输入和输出(我相信我做得很好),然后执行的grep一个

现在的问题是,这一进程的grep一个永远不会完成。同为尾-1 ,例如..然而,它确实工作头-1 。我认为这是因为的grep ,这是由母公司执行,等待更多的投入,即使孩子已经完成了它的操作。 LS |用grep一个产生正确的输出,在控制台上(管道的输出被设置为默认输出)显示,但是,正如我已经说过了,的grep一个未完成。

所以,我的问题是:我怎么能告知该管道已写完了父母,所以它可以完成的执行grep的一个例如

感谢您。

这里的code:

[fd是管道,它是在code pviously初始化$ P $。如果你能看到的任何东西不协调,请让我知道;我已经清理了code位,而这仅是有问题的一部分,因为你可以看到。]

  INT FD [2];
   管(FD);   如果((PID =叉())!= - 1){
     如果(PID == 0){/ *儿童执行* /
        关闭(FD [0]);
        关闭(1);
        DUP(FD [1]);
        关闭(FD [1]);
        execvp(argvv [0] [0],argvv [0]); / *这里的存储的第一条指令* /      }其他{/ *父执行* /
        等待(安培;状态);
        关闭(FD [1]);
        关闭(0);
        DUP(FD [0]);
        关闭(FD [0]);
        execvp(argvv [1] [0],argvv [1]); / *这里的存储第二指令* /
       }
   }


解决方案

如果在的grep 继续 LS后运行已退出,这表示你的的关闭,你需要关闭所有管道。

在具体地,其读端管道的写入端连接于的grep 过程仍在另一个进程打开。您将需要出示code知道更多。


在code你已经正确粘贴作品(当扩展到一个完整的程序,按照以下)。两种子退出就好了。

这意味着你已经消除了code当您创建的缩减版本,这里有问题 - 也许你有另一个叉()之间在管道()呼叫,这一叉()

 的#include<&unistd.h中GT;
#包括LT&; SYS / wait.h>诠释的main()
{
   将为pid_t PID;
   字符* argvv [2] [3] = {{LS,0,0},{grep的,一个,0}};
   INT状态;   INT FD [2];
   管(FD);   如果((PID =叉())!= - 1){
     如果(PID == 0){/ *儿童执行* /
        关闭(FD [0]);
        关闭(1);
        DUP(FD [1]);
        关闭(FD [1]);
        execvp(argvv [0] [0],argvv [0]); / *这里的存储的第一条指令* /      }其他{/ *父执行* /
        等待(安培;状态);
        关闭(FD [1]);
        关闭(0);
        DUP(FD [0]);
        关闭(FD [0]);
        execvp(argvv [1] [0],argvv [1]); / *这里的存储第二指令* /
       }
   }   返回0;
}

I am working on an assignment for my Operating System class (Posix & C), building a mini-shell, and I don't know how to solve the following problem:

My mini-shell has to accept two commands, for example ls | grep a. For that I create a pipe of size two and a child. The child closes all that it has to close and opens all that it has to open (standard/pipe's in & out). It then executes "ls," using execvp. I am sure this works well. After that, the parent shuts and opens inputs and outputs (I am sure I do it well), and then executes grep a.

Now, the problem is that the process grep a never finishes. Same for tail -1, e.g.. Yet it does work for head -1. I think that happens because grep and tail, which are executed by the parent, wait for more input, even though the child has finished its operation. ls | grep a produces the right output, displayed on the console (The pipe's output is set as default output), but, as I've said, grep a does not finish.

So, my question is: how can I inform the parent that the pipe has finished writing, so it can finish the execution of grep a for example?

Thank you.

Here's the code:

[fd is the pipe, it is initialized previously in the code. If you can see any incongruous thing, please let me know; I've cleaned the code a bit, and this is only the problematic part, as you can see.]

   int fd[2];
   pipe(fd);

   if ((pid = fork()) != -1){ 
     if(pid == 0){         /*Child executing */
        close(fd[0]);
        close(1);
        dup(fd[1]);
        close(fd[1]);
        execvp(argvv[0][0], argvv[0]); /* Here's stored the first instruction */

      } else{             /* Parent executing */
        wait(&status);
        close(fd[1]);
        close(0);
        dup(fd[0]); 
        close(fd[0]);
        execvp(argvv[1][0], argvv[1]); /* Here's stored the second instruction */
       }
   }  

解决方案

If the grep continues to run after the ls has exited, that indicates that you have not closed all the pipes that you need to close.

In particular, the write end of the pipe whose read end is attached to the grep process is still open in another process. You will need to show your code to know more.


The code you have pasted works correctly (when expanded to a full program, as per the below). Both subprocesses exit just fine.

This means that you've eliminated the code that has the problem when you created your cut-down version here - perhaps you have another fork() between the pipe() call and this fork()?

#include <unistd.h>
#include <sys/wait.h>

int main()
{
   pid_t pid;
   char *argvv[2][3] = { { "ls", 0, 0}, { "grep", "a", 0 } };
   int status;

   int fd[2];
   pipe(fd);

   if ((pid = fork()) != -1) {
     if(pid == 0){         /*Child executing */
        close(fd[0]);
        close(1);
        dup(fd[1]);
        close(fd[1]);
        execvp(argvv[0][0], argvv[0]); /* Here's stored the first instruction */

      } else{             /* Parent executing */
        wait(&status);
        close(fd[1]);
        close(0);
        dup(fd[0]);
        close(fd[0]);
        execvp(argvv[1][0], argvv[1]); /* Here's stored the second instruction */
       }
   }

   return 0;
}

这篇关于在管持续execvp?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆