How to tell if a downstream process in a Unix pipe has crashed

435 Views Asked by At

I have a Linux process (let's call it the main process) whose standard output is piped to another process (called the downstream process) by means of the shell's pipe operator (|). The main process is set up to receive SIGPIPE signals if the downstream process crashes. Unfortunately, SIGPIPE is not raised until the main process writes to stdout. Is there a way to tell sooner that the downstream process has terminated?

One approach is to write continuously to the downstream process, but that seems wasteful. Another approach is to have a separate watchdog process that monitors all relevant processes, but that is complex. Or perhaps there is some way to use select() to trigger the signal. I am hoping that the main process can do all this itself.

2

There are 2 best solutions below

0
On BEST ANSWER

It appears the stdout file descriptor becomes "ready for reading" when the receiver crashes:

$ gcc -Wall select-downstream-crash.c -o select-downstream-crash
$ gcc -Wall crash-in-five-seconds.c -o crash-in-five-seconds
$ ./select-downstream-crash | ./crash-in-five-seconds
    ... five seconds pass ...
stdout is ready for reading
Segmentation fault

select-downstream-crash.c

#include <err.h>
#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>

int main(void)
{
    fd_set readfds;
    int rc;

    FD_ZERO(&readfds);
    FD_SET(STDOUT_FILENO, &readfds);

    rc = select(STDOUT_FILENO + 1, &readfds, NULL, NULL, NULL);
    if (rc < 0)
        err(1, "select");

    if (FD_ISSET(STDOUT_FILENO, &readfds))
        fprintf(stderr, "stdout is ready for reading\n");

    return 0;
}

crash-in-five-seconds.c

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    sleep(5);
    putchar(*(char*)NULL);
    return 0;
}

I tried this on Linux, but don't know if it'll work elsewhere. It would be nice to find some documentation explaining this observation.

1
On

If the main process forks the other processes, then it will get SIGCHLD notifications when they exit.