I have a Socket library, written in C++, in which the method used to send data never has the opportunity to handle an errno of SIGPIPE. Thus I thought perhaps I should setup a signal handler to receive the signal, but this too is not being called.
Is there something that I am missing or doing that is completely wrong? Below is the relevant code. Note that a SIGPIPE signal is generated when the Server is unable to send data to the Client (e.g. the client has terminated).
Server code:
Code:
#include <TCPServerSocket.hpp>
#include <string>
#include <iostream>
#include <unistd.h>
int main()
{
using namespace socketpp;
using namespace std;
try
{
TCPServerSocket server;
server.bind(9000);
server.listen();
TCPSocketPtr client = server.accept();
client->setNonBlocking();
string message = "Hello";
while (true)
{
*client << message; // send data
sleep(1);
}
}
catch (SocketException& e)
{
cerr << "Exception -- " << e.what() << endl;
return -1;
}
return 0;
}
In the constructor for TCPSocket, which above is noted as TCPSocketPtr (a boost shared ptr), I have the following code:
Code:
TCPSocket::TCPSocket(int domain, int type, int protocol)
: Socket(domain, type, protocol)
{
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = sigHandler;
sigaction(SIGPIPE, &act, NULL);
}
...
void
TCPSocket::sigHandler(int signo)
{
throw SocketException("TCPSocket: Signal received.", signo);
}
And finally, the code that sends the data:
Code:
TCPSocket&
operator<<(TCPSocket& sock, const std::string& msg)
{
sock.send(msg.c_str(), msg.size());
return sock;
}
...
void
TCPSocket::send(const char* msg, size_t msgLen)
{
size_t bytesSent = 0;
while (bytesSent != msgLen)
{
int rtn = ::send(m_Socket, msg + bytesSent, msgLen - bytesSent, 0);
if (rtn < 0 && (errno == EAGAIN || errno == EINTR)) // This point never reached when SIGPIPE signal is issued.
{
continue;
}
if (rtn < 0)
{
throw SocketException("Error occurred while attempting to send data", errno);
}
bytesSent += rtn;
}
}
P.S. I assume it is a SIGPIPE signal that is killing my Server, because that is what gdb reported when I was debugging via ddd.