0

I implement some parts of shell. One of them is a pipe. During the parsing I exec commands redirecting their input/output with dup2. Specifically I do the following (I don't write here error checking for simplicity, but I check for errors in my code). Before the parsing starts I have

int p[2];
pipe(p);
int stdin_copy = dup(0);
int stdout_copy = dup(1);

Execution of command:

dup2(p[1], 1);
// exec command with fork and execvp - it's all ok with this part
dup2(p[0], 0); // placed after exec in order to prevent redirect for first command
              // in pipe

When a pipe is processed, there is an output of last command in p, so I try to write it to stdout:

dup2(stdout_copy, 1);
dup2(stdin_copy, 0); // restore original stdin/stdout
char c;
while (read(p[0], &c, sizeof(char)) > 0)
    printf("%c", c);

But it writes an output and then loops forever, and I don't understand why. One solution is to save all commands and then do not redirect output for last one, but I want to exec them on the spot.

perlik
  • 93
  • 6
  • Are you sure it loops forever? According to [this](http://linux.die.net/man/3/read): _If `O_NONBLOCK` is clear, `read()` shall block the calling thread until some data becomes available._ – Austin Mullins Mar 17 '15 at 19:12
  • Are you sure it's looping forever and not just blocking on the `read(2)`? Remember that `fork(2)` duplicates the file descriptors from your pipe. You will need to `close(2)` the ends of the pipe you're not using in the parent and the child. Otherwise a file descriptor will remain open for the write end of the pipe so that end-of-file is never signaled. – Ulfalizer Mar 17 '15 at 19:14
  • Oh, thanks. The problem was in `read` indeed. I set `p[0]` to non-block mode, and it's ok now. – perlik Mar 17 '15 at 20:16

0 Answers0