3

distinguish stdout from stderr on pipe

So, related to the link above, I have a child who is executing tail and parent is reading its out put via a pipe.

dup2(pipefd[1], STDOUT_FILENO);
dup2(pipefd[1], STDERR_FILENO);

My question is, if somehow tail fails, what happens to the pipe from which I am reading? Do I get anything on stderr? Does tail terminate itself? or it may hang in there as defunct?

Community
  • 1
  • 1
hari
  • 9,439
  • 27
  • 76
  • 110
  • Since they are dup'ed, I would think that the child closing one would also close the other, causing subsequent writes to the other to fail. The parent would get end-of-file. But I'm not 100% certain. – wberry Aug 12 '11 at 21:54
  • @wberry: actually, closing is the one thing you can do with a dup'ed file descriptor and _not_ affect its other aliases. – hmakholm left over Monica Aug 12 '11 at 23:40

3 Answers3

2

The kernel will send a SIGPIPE signal to the other process on the pipe when tail has terminated. The default action for this signal (if a handler is not installed) is to terminate the process.

If you don't want to deal with signals, you can ignore SIGPIPE in the parent (so it doesn't terminate when tail has terminated), and instead check whether the value of errno is EPIPE after each read. Additionally, you'll have to call wait or waitpid from the parent to reap the zombie child.

Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
1

you don't get EPIPE when reading, only write will return EPIPE. You'll get EOF, indicated by read returning 0, and since you read stderr, you'll get the error message as well (before the EOF).

The process will become a zombie, and you can use wait/waitpid to get the exit status, which will be non-zero if there was an error.

Per Johansson
  • 6,697
  • 27
  • 34
1

If tail fails, any read on the read end of the pipe will return EOF. If tail fails, it has already terminated, the definition of "fail" being that it terminated with a non-zero exit status. It will remain in the process table (ie, "defunct") until the parent waits for it.

But why are you having tail use the same pipe for both stderr and stdout? Why not just make two pipes? It seems that this would eliminate the problem of distinguishing between the two output streams.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Thanks, I believe, now, I do not even need to read `stderr`. If `tail` fails, `stdout` will get an `EOF`, correct? And I am anyhow doing `wait` for child. So, it will be cleaned up. Does that sound correct? – hari Aug 14 '11 at 03:58