Socket: do not crash on writing to broken pipe.
Writing to a closed socket on all Unix/Linux systems raises a SIGPIPE signal which immediately closes the program. Disabling raising of SIGPIPE allows proper error handling by checking the return values of send/sendto and getting the EPIPE in errno.
This commit is contained in:
parent
becbad7ea4
commit
d82c8eb945
@ -454,6 +454,23 @@ bool Socket::open ( bool stream )
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SO_NOSIGPIPE
|
||||||
|
// Do not generate SIGPIPE signal (which immediately terminates the program),
|
||||||
|
// instead ::send() will return -1 and errno will be set to EPIPE.
|
||||||
|
// SO_NOSIGPIPE should be available on Mac/BSD systems, but is not available
|
||||||
|
// within Posix/Linux.
|
||||||
|
// This only works for calls to ::send() but not for ::write():
|
||||||
|
// http://freebsd.1045724.n5.nabble.com/is-setsockopt-SO-NOSIGPIPE-work-tp4011054p4011055.html
|
||||||
|
int set = 1;
|
||||||
|
setsockopt(handle, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(set));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MSG_NOSIGNAL
|
||||||
|
# define MSG_NOSIGNAL 0
|
||||||
|
#endif
|
||||||
|
// TODO supress SIGPIPE if neither SO_NOSIGPIPE nor MSG_NOSIGNAL is available
|
||||||
|
// http://krokisplace.blogspot.co.at/2010/02/suppressing-sigpipe-in-library.html
|
||||||
|
|
||||||
return (handle != -1);
|
return (handle != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,7 +609,7 @@ int Socket::connect ( IPAddress* addr )
|
|||||||
int Socket::send (const void * buffer, int size, int flags)
|
int Socket::send (const void * buffer, int size, int flags)
|
||||||
{
|
{
|
||||||
assert ( handle != -1 ) ;
|
assert ( handle != -1 ) ;
|
||||||
return ::send (handle, (const char*)buffer, size, flags);
|
return ::send (handle, (const char*)buffer, size, flags | MSG_NOSIGNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -600,8 +617,12 @@ int Socket::sendto ( const void * buffer, int size,
|
|||||||
int flags, const IPAddress* to )
|
int flags, const IPAddress* to )
|
||||||
{
|
{
|
||||||
assert ( handle != -1 ) ;
|
assert ( handle != -1 ) ;
|
||||||
return ::sendto(handle,(const char*)buffer,size,flags,
|
return ::sendto( handle,
|
||||||
(const sockaddr*) to->getAddr(), to->getAddrLen());
|
(const char*)buffer,
|
||||||
|
size,
|
||||||
|
flags | MSG_NOSIGNAL,
|
||||||
|
(const sockaddr*)to->getAddr(),
|
||||||
|
to->getAddrLen() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user