I have a program that sends data to a mobile phone with android. Let's iamgine
//EDIT
while(enviado < length) {
printf("SEND\n");
r = write(con, buff_enviar+enviado, length-enviado);
printf(" OK\n");
if (r > 0) enviado += r;
else if (r == 0) { printf(" * >> Socket cerrado [datos] (%d)\n",r); return r; }
else if (r == -1) { printf(" * >> Error [datos] (%d)\n",r); return r; }
}
When I'm out of this while, I change buff_enviar
values. When I cancel the transmission in my phone, by doing a successful socket.close(), the write
makes my program end for no reason. So the output of my program is:
SEND
OK
SEND
OK
SEND
I guess it's write
fault because it does not printf OK. ERRNO value is 61 (No data available)
I hope someone has encountered this problem before and solved it.
EDIT: Sometimes when I cancel, r = -1 so I can handle the error, but most of the time it just terminates the program. It's like randomly chosen. I'm confused :(
Kind regards, Raúl
You are writing to a closed socket, which by default generates a "broken pipe" signal (SIGPIPE
). To be able to reliably recover from write()
, you need to ignore EPIPE
by calling:
signal (SIGPIPE, SIG_IGN);
somewhere in your program, for example in main()
.
Though the chosen answer was to ignore signal process wide, there are other alternatives:
Using send
function with MSG_NOSIGNAL
:
send(con, buff_enviar+enviado, length-enviado, MSG_NOSIGNAL);
Disabling SIGPIPE
on socket level (not available on all kernels):
int flag = 1;
setsockopt(con, SOL_SOCKET, SO_NOSIGPIPE, &flag, sizeof(flag));
Disabling SIGPIPE
for caller thread:
sigset_t set;
sigemptyset (&set);
sigaddset (&set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &set, NULL);
And, finally, disabling signal process-wide (not recommended for libraries):
signal(SIGPIPE, SIG_IGN);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With