diff --git a/slsSupportLib/include/sls/DataSocket.h b/slsSupportLib/include/sls/DataSocket.h index 31d9afa72..5d591d204 100644 --- a/slsSupportLib/include/sls/DataSocket.h +++ b/slsSupportLib/include/sls/DataSocket.h @@ -88,6 +88,8 @@ class DataSocket { private: int sockfd_ = -1; int fnum_{0}; + + std::string_view errno_name(int e); }; }; // namespace sls diff --git a/slsSupportLib/src/DataSocket.cpp b/slsSupportLib/src/DataSocket.cpp index 4b90aa293..fbeacab29 100644 --- a/slsSupportLib/src/DataSocket.cpp +++ b/slsSupportLib/src/DataSocket.cpp @@ -73,7 +73,7 @@ int DataSocket::Receive(void *buffer, size_t size) { if (this_read == 0) ss << ": connection closed by peer (EOF)"; else if (this_read < 0) - ss << ": read error: " << std::strerror(err); + ss << ": read error: " << std::strerror(err) << " (" << errno_name(err) << ")"; ss << " after " << timer.elapsed_ms() << " ms"; throw SocketError(ss.str()); } @@ -165,4 +165,49 @@ void DataSocket::shutDownSocket() { void DataSocket::shutdown() { ::shutdown(sockfd_, SHUT_RDWR); } +std::string_view DataSocket::errno_name(int e) { + switch (e) { +#ifdef EACCES + case EACCES: return "EACCES"; +#endif +#ifdef EAGAIN + case EAGAIN: return "EAGAIN"; +#endif +#ifdef EBADF + case EBADF: return "EBADF"; +#endif +#ifdef ECONNABORTED + case ECONNABORTED: return "ECONNABORTED"; +#endif +#ifdef ECONNREFUSED + case ECONNREFUSED: return "ECONNREFUSED"; +#endif +#ifdef ECONNRESET + case ECONNRESET: return "ECONNRESET"; +#endif +#ifdef EINPROGRESS + case EINPROGRESS: return "EINPROGRESS"; +#endif +#ifdef EINTR + case EINTR: return "EINTR"; +#endif +#ifdef EINVAL + case EINVAL: return "EINVAL"; +#endif +#ifdef EPIPE + case EPIPE: return "EPIPE"; +#endif +#ifdef ETIMEDOUT + case ETIMEDOUT: return "ETIMEDOUT"; +#endif +#ifdef EWOULDBLOCK +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: return "EWOULDBLOCK"; +#endif +#endif + default: + return "UNKNOWN_ERRNO"; + } +} + } // namespace sls diff --git a/slsSupportLib/tests/test-Sockets.cpp b/slsSupportLib/tests/test-Sockets.cpp index 825d66c12..c1826bcca 100644 --- a/slsSupportLib/tests/test-Sockets.cpp +++ b/slsSupportLib/tests/test-Sockets.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace sls { @@ -24,6 +25,18 @@ std::vector echo_server(uint16_t port, size_t bytes_to_send, std::vector buffer(100, '\0'); s.Receive(buffer.data(), buffer.size()); + if (port==1960){ + struct linger ling = { + .l_onoff = 1, + .l_linger = 0 + }; + + auto fd = s.getSocketId(); + setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof ling); + close(fd); + return buffer; + } + if (bytes_to_send > 0) { std::vector to_send(bytes_to_send, '\0'); to_send[0] = 'O'; @@ -126,4 +139,26 @@ TEST_CASE("Receiving with a socket error throws and reports the error", CHECK_THAT(error_message, Catch::Matchers::Contains("read error:")); } + +TEST_CASE("Socket crash?", "[support]") { + std::vector received_message(100, '\0'); + std::vector sent_message(100, '\0'); + const char m[]{"some message"}; + std::copy(std::begin(m), std::end(m), sent_message.data()); + + auto s = std::async(std::launch::async, echo_server, 1960, 100, + std::chrono::milliseconds(0)); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + auto client = DetectorSocket("localhost", 1960); + client.Send(sent_message.data(), sent_message.size()); + + + REQUIRE_THROWS(client.Receive(received_message.data(), received_message.size())); + // client.close(); + + + +} + + } // namespace sls