From 94fc605a703cbfba6ee726eccc984bc4a267fecc Mon Sep 17 00:00:00 2001 From: Laurent Gomila Date: Fri, 14 Jun 2013 15:18:08 +0200 Subject: [PATCH] On Unix systems, a socket disconnection no longer stops the program with signal SIGPIPE (#72) --- src/SFML/Network/Socket.cpp | 8 ++++++++ src/SFML/Network/TcpSocket.cpp | 14 ++++++++++++-- src/SFML/Network/Unix/SocketImpl.cpp | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/SFML/Network/Socket.cpp b/src/SFML/Network/Socket.cpp index 2ab9815b..3e8489f3 100644 --- a/src/SFML/Network/Socket.cpp +++ b/src/SFML/Network/Socket.cpp @@ -108,6 +108,14 @@ void Socket::create(SocketHandle handle) err() << "Failed to set socket option \"TCP_NODELAY\" ; " << "all your TCP packets will be buffered" << std::endl; } + + // On Mac OS X, disable the SIGPIPE signal on disconnection + #ifdef SFML_SYSTEM_MACOS + if (setsockopt(m_socket, SOL_SOCKET, SO_NOSIGPIPE, reinterpret_cast(&yes), sizeof(yes)) == -1) + { + err() << "Failed to set socket option \"SO_NOSIGPIPE\"" << std::endl; + } + #endif } else { diff --git a/src/SFML/Network/TcpSocket.cpp b/src/SFML/Network/TcpSocket.cpp index 072a30c6..62761c28 100644 --- a/src/SFML/Network/TcpSocket.cpp +++ b/src/SFML/Network/TcpSocket.cpp @@ -38,6 +38,16 @@ #endif +namespace +{ + // Define the low-level send/receive flags, which depend on the OS + #ifdef SFML_SYSTEM_LINUX + const int flags = MSG_NOSIGNAL; + #else + const int flags = 0; + #endif +} + namespace sf { //////////////////////////////////////////////////////////// @@ -221,7 +231,7 @@ Socket::Status TcpSocket::send(const void* data, std::size_t size) for (int length = 0; length < sizeToSend; length += sent) { // Send a chunk of data - sent = ::send(getHandle(), static_cast(data) + length, sizeToSend - length, 0); + sent = ::send(getHandle(), static_cast(data) + length, sizeToSend - length, flags); // Check for errors if (sent < 0) @@ -246,7 +256,7 @@ Socket::Status TcpSocket::receive(void* data, std::size_t size, std::size_t& rec } // Receive a chunk of bytes - int sizeReceived = recv(getHandle(), static_cast(data), static_cast(size), 0); + int sizeReceived = recv(getHandle(), static_cast(data), static_cast(size), flags); // Check the number of bytes received if (sizeReceived > 0) diff --git a/src/SFML/Network/Unix/SocketImpl.cpp b/src/SFML/Network/Unix/SocketImpl.cpp index 706c269a..4a6b5087 100644 --- a/src/SFML/Network/Unix/SocketImpl.cpp +++ b/src/SFML/Network/Unix/SocketImpl.cpp @@ -90,6 +90,7 @@ Socket::Status SocketImpl::getErrorStatus() case ETIMEDOUT : return Socket::Disconnected; case ENETRESET : return Socket::Disconnected; case ENOTCONN : return Socket::Disconnected; + case EPIPE : return Socket::Disconnected; default : return Socket::Error; } }