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