Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Q]: What socket caused SIG_PIPE?

0 views
Skip to first unread message

Jeff Dickson

unread,
Oct 13, 1994, 1:07:40 PM10/13/94
to
In article <CxJA8...@cfanews.harvard.edu> pana...@cfauvcs6.harvard.edu (Alexander Panasyuk) writes:
>>I have process which opens several (AF_INET,SOCK_STREAM) sockets with
>>SO_KEEPALIVE option and installs SIG_PIPE handler. Is there any way to
>>determine which socket caused SIG_PIPE without trying to write to each
>>one?
>bar...@nic.near.net (Barry Margolin) wrote:
>Call select(2). It should return immediately, and the socket that caused
>the SIGPIPE should be included among the writable sockets. Determining
>which of them is the one may still require trying to write to each of them.
>Maybe a zero-length write() will still signal an error on the broken one.
>Or there might be some ioctls that could be useful for this.

I was curious about this too. The solution I thought to try was to test if
an exceptional condition was pending via select(). I put together a little
test program to prove/disprove my theory. I didn't think to test if the
file descriptor in question was marked writeable instead, until Barry Margolin
shed some light. So I revamped my test program and it worked. Now I'm wondering
what the win is? Afterall I would have found out that the file descriptor was
unwritable in the natural course of trying to write data anyways. I'm also won-
dering what are considered exceptional conditions? Here is my test program.

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

int handler();

main() {

int pid, fda[2];
fd_set fds;

signal(SIGPIPE, handler);
if (pipe(fda) != -1) {
close(fda[0]);
write(fda[1], "x", 1);
FD_ZERO(&fds);
FD_SET(fda[1], &fds);
select(getdtablesize(), 0L, &fds, 0L, 0L);
if (FD_ISSET(fda[1], &fds))
printf("The pipe is broken\n");
close(fda[1]);
}
}

handler() {

printf("SIGPIPE occurred\n");
}


The problem with this example and the O.S. whole handling of this situation
is that select() will mark the file descriptor as writeable regardless if a
malattempt to write is made and thus a SIGPIPE signal generated. I'm really
disappointed how poorly this was implemented. Why couldn't a write on a sin-
gle ended pipe be treated as an exceptional condition? At least that way you
could determine exactly which file descriptor caused the signal to be gener-
ated instead of the round about fashion we have to go through now.

Jeff S. Dickson
jdic...@vtol.jpl.nasa.gov


Casper H.S. Dik

unread,
Oct 14, 1994, 6:27:25 AM10/14/94
to
jdic...@nemesis.jpl.nasa.gov (Jeff Dickson) writes:

>The problem with this example and the O.S. whole handling of this situation
>is that select() will mark the file descriptor as writeable regardless if a
>malattempt to write is made and thus a SIGPIPE signal generated. I'm really
>disappointed how poorly this was implemented. Why couldn't a write on a sin-
>gle ended pipe be treated as an exceptional condition? At least that way you
>could determine exactly which file descriptor caused the signal to be gener-
>ated instead of the round about fashion we have to go through now.

I don't see why it is difficult. The only time your process gets a SIGPIPE
is during a write. What you do then is install a signal handler for SIGPIPE:

signal(SIGPIPE< SIG_IGN);

and by magic, the write call will return -1, errno = EPIPE.

And since this value is returned by write you no the fd responsible.

Casper

Jeff Dickson

unread,
Oct 14, 1994, 2:31:11 PM10/14/94
to

Yeah, but you still have to attempt a write() on all the file descriptors
that potentially could have generated the SIGPIPE signal to determine which
one. There's no way to tell from the select() call alone since this condition
and the ability to write are indistinguishable. If on the other hand select()
differeniated between the willingness to accept data and an exceptional con-
dition such as a broken pipe determing which file descriptor incurred the
error would be much more straight forward. You only need test if the partic-
ular file descriptor was included in the set of file descriptors that had
exceptional conditions pending. Pretty much a simple if-else FD_ISSET(bla, bla)
arrangement. Much cleaner than the brute-force method we have to undertake now.

Jeff S. Dickson
jdic...@vtol.jpl.nasa.gov

0 new messages