I recently found out that having a certain php script connect to my server makes it crash due to a broken pipe error. As I understand, these are caused by writing to a closed socket. Is there a way I can check a socket's integrity before making the send statement? Or is there any other way to keep the broken pipe from shutting down the whole program?
#include <poll.h> // For poll()
bool is_client_closed(int cs)
{
pollfd pfd;
pfd.fd = cs;
pfd.events = POLLIN | POLLHUP | POLLRDNORM;
pfd.revents = 0;
while(pfd.revents == 0)
{
// call poll with a timeout of 100 ms
if(poll(&pfd, 1, 100) > 0)
{
// if result > 0, this means that there is either data available on the
// socket, or the socket has been closed
char buffer[32];
if(recv(cs, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0)
{
// if recv returns zero, that means the connection has been closed:
returntrue;
}
}
}
returnfalse;
}
Alright, it seems to solve the broken pipe error, but it seems like it causes other problems, such as not giving the message it's supposed to when the user first connects. I'll have to see what I can do to work around it. Thanks for your help.
EDIT: It's possible that the function's not the cause. I'll report back later after more experimentation.
Ok, from what I can tell calling that function is what's causing my problems, but not because of false positives. Is it possible that the recv call is eating input despite the MSG_PEEK?
It works if I take out all the polling stuff and just use this
1 2 3 4 5 6
char buffer[32];
if(recv(cs, buffer, sizeof(buffer), MSG_PEEK) == 0) //the socket's already nonblocking, so I took out the "don't wait"
{
// if recv returns zero, that means the connection has been closed:
returntrue;
}
I would think that send() would return -1 with errno=ENOTCONN.
You need to handle SIGPIPE. That is what is causing the program to abort.
You should be able to ignore the signal, then recv() would return -1 with
errno=EPIPE I think (OTOMH).