Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check for a broken pipe before trying to write to it? [duplicate]

Is it possible to check if a pipe is broken before trying to write/read to it, so I can just skip it and continue with the program?

I'm utilizing a while loop to write to pipes communicating from the Parent to multiple Children. Over the course of the loop, several of the children will close. When the loop comes around and tries to write to them again, my program shuts down because it is killed by SIGPIPE since the pipe is broken. I know the pipe is broken, I programmed the children to close their pipes and exit (necessary). I still want to finish the loop and move on with the program. I'd like it to check if the pipe is broken, skip over it if broken (without an error output), and move on with the program (the other children still need to be written to).

So, is it possible? An example in c would be great.

Here's a simple pseudocode representation of what I'm asking:

int i = 0;

while(i != 5)
{
    if (mypipe[WRITE] is BROKEN)
        //Do Nothing ---Basically Skip

    else if (some condition)
        write(mypipe[WRITE]);

    i++;
}

This question is related to a previous post of mine, though the context of my question is different. You can review the code for the actual program there.

like image 682
LazyBear Avatar asked Oct 14 '14 13:10

LazyBear


2 Answers

my program shuts down because it is killed by SIGPIPE

You can change that behavior if you install a signal handler that ignores SIGPIPE, that way the write() call to the pipe returns an error instead of killing your program:

  signal(SIGPIPE, SIG_IGN);

Then you simple check

ssize_t rc;
rc = write(...);
if (rc == -1) {
    if (errno == EPIPE) {
         //it's broken
    }
 //some other error occured.
}
like image 187
nos Avatar answered Oct 17 '22 02:10

nos


You can set up a signal handler to ignore SIGPIPE, and then write to the buffer and check the error code:

/* initialization */
signal(SIGPIPE, SIG_IGN);
...

/* try writing to pipe and detect broken pipe */
ssize_t written = write(mypipe[WRITE], buf, size);
if (written == -1 && errno == EPIPE)
  ... remove pipe from the list and continue processing
like image 22
user4815162342 Avatar answered Oct 17 '22 01:10

user4815162342