I read the man
pages, and my understanding is that if write()
fails and sets the errno
to EAGAIN
or EINTR
, I may perform the write()
again, so I came up with the following code:
ret = 0;
while(ret != count) {
write_count = write(connFD, (char *)buf + ret, count);
while (write_count < 0) {
switch(errno) {
case EINTR:
case EAGAIN:
write_count = write(connFD, (char *)buf + ret, count -ret);
break;
default:
printf("\n The value of ret is : %d\n", ret);
printf("\n The error number is : %d\n", errno);
ASSERT(0);
}
}
ret += write_count;
}
I am performing read()
and write()
on sockets and handling the read()
similarly as above. I am using Linux, with gcc
compiler.
Clean coding improves dependability, extensibility, and performance all around. One of the founding principles of the clean coding movement is a simple fact: Far more time is spent reading code than writing it.
You have a bit of a "don't repeat yourself" problem there - there's no need for two separate calls to write
, nor for two nested loops.
My normal loop would look something like this:
for (int n = 0; n < count; ) {
int ret = write(fd, (char *)buf + n, count - n);
if (ret < 0) {
if (errno == EINTR || errno == EAGAIN) continue; // try again
perror("write");
break;
} else {
n += ret;
}
}
// if (n < count) here some error occurred
EINTR
and EAGAIN
handling should often be slightly different. EAGAIN
is always some kind of transient error representing the state of the socket buffer (or perhaps, more precisely, that your operation may block).
Once you've hit an EAGAIN
you'd likely want to sleep a bit or return control to an event loop (assuming you're using one).
With EINTR
the situation is a bit different. If your application is receiving signals non-stop, then it may be an issue in your application or environment, and for that reason I tend to have some kind of internal eintr_max
counter so I am not stuck in the theoretical situation where I just continue infinitely looping on EINTR
.
Alnitak's answer (sufficient for most cases) should also be saving errno
somewhere, as it may be clobbered by perror()
(although it may have been omitted for brevity).
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