2

When I test my program using a web browser I can write to the socket/FD just fine so i decided to loop it and cut the connection mid-connection and I noticed a problem. send() is capable of closing down the entire program when the socket is unavailable. I thought the problem was that the program caught itself in a catch-22 and closed itself. So I set the socket to not block. No change. Any ideas of why this is happening?

else if ( b->temp_socket_list[read].revents & POLLOUT ) {  
    printf ( "#Write#\n" );  
    char *done = "Done!";  
    int sent = send ( sock, done, 5, 0 );  
    printf ( "end\n", sent );  
}  
Jay
  • 77
  • 3
  • 5
    Post some code demonstrating the behaviour. – NPE Apr 12 '11 at 20:34
  • 2
    And, additionally, run `strace` with the program, so that we can see what really happens. – Roland Illig Apr 12 '11 at 20:37
  • @Roland +1. This was the only way I could figure out a process was getting a SIGPIPE some months ago. It simply seemed to die shortly after system initialization. – Jeff Apr 12 '11 at 20:49
  • As an alternative to ignoring the SIGPIPE, [this post](https://stackoverflow.com/q/108183/631065) has some good answers on how to avoid them. – Jeff Apr 12 '11 at 20:35

3 Answers3

5

This is likely due to the default action of the SIGPIPE signal. To ignore this signal, use something like:

signal(SIGPIPE, SIG_IGN);

Socket errors will then be reported as return values from socket functions, rather than a signal.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Note that you cannot do this from library code, which should not be modifying the caller's signal dispositions, at least not without documenting it and including a big warning. However if you use `sendto` rather than send, you can specify a flag indicating that you don't want `SIGPIPE` to be generated. I believe there's also a solution involving `setsockopt` and, and using `pthread_sigmask` and `sigtimedwait` to block and clear the pending `SIGPIPE`. – R.. GitHub STOP HELPING ICE Apr 12 '11 at 21:53
3

Which platform is this?

On UNIX in some cases you can get a signal when the connection goes down (SIGPIPE) and this terminates the program by default... the solution is to install a signal handler for SIGPIPE that does nothing.

Antti Huima
  • 25,136
  • 3
  • 52
  • 71
0

Try this:

sigset_t set, oldset;
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &set, &oldset);
/* use send all you like here */
sigtimedwait(&set, 0, (struct timespec [1]){0});
pthread_sigmask(SIG_SETMASK, &oldset, 0);

I'm not 100% sure it works, but I believe it should, and if it's correct then it's a solution that can be used from library code without messing up the state of the caller or other potentially-signal-using threads.

Also note that if the program (or even just the current thread) does not want to make use of SIGPIPE, you can simplify this a lot by just leaving SIGPIPE permanently blocked:

sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &set, &oldset);
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711