3

I am using following system calls in my program:

recvfrom
sendto
sendmsg

And from each system call mentioned above I check if it completes with out any interruption and in case if it is interrupted, I retry.

Ex:

recvagain:     
    len = recvfrom(fd, response, MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen);
    if (errno == EINTR) {
           syslog(LOG_NOTICE, "recvfrom interrupted: %s", strerror(errno));
           goto recvagain;
    }

Problem here is that do I need to reset errno value to 0 each and every time it fails. Or if recvfrom() is successful, does it reset errno to 0?

recvfrom() man page says:

Upon successful completion, recvfrom() returns the length of the message in bytes. If no messages are available to be received and the peer has performed an orderly shutdown, recvfrom() returns 0. Otherwise the function returns -1 and sets errno to indicate the error.

same case with sendto and sendmsg.

I can n't really check this now as I don't have access to server-client setup. Any idea?

Thanks

alk
  • 69,737
  • 10
  • 105
  • 255
Ram
  • 1,153
  • 4
  • 16
  • 34

2 Answers2

7

recvfrom returns -1 if it is interrupted (and sets errno to EINTR). Therefore, you should just check len:

if(len == -1) {
    if(errno == EINTR) {
        syslog(LOG_NOTICE, "recvfrom interrupted");
        goto recvagain;
    } else {
        /* some other error occurred... */
    }
}
nneonneo
  • 171,345
  • 36
  • 312
  • 383
4

The errno pseudo "variable" may not change on successful syscalls. So you could clear it either before your recvfrom, or when len<0 and having tested its value.

See errno(3) man page for more.

Actually, as Robert Xiao (nneonneo) commented, you should not write errno and just test it when the syscall has failed (in that case, the C function -e.g. recvfrom etc...- wrapping that syscall would have written errno before returning -1).

nneonneo
  • 171,345
  • 36
  • 312
  • 383
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 2
    You rarely need to clear `errno`; I don't think this is one of those times. – nneonneo Oct 17 '12 at 06:20
  • The man reason for clearing `errno` is to cover the case when it was previously set (some time ago) by an unrelated syscall. – Basile Starynkevitch Oct 17 '12 at 07:17
  • 1
    You normally shouldn't care. As I indicated in my answer, the correct solution is to check `len` to see if an error actually occurred. – nneonneo Oct 17 '12 at 07:18
  • @BasileStarynkevitch But it’s normally not needed, because you should _always_ check the return value _before_ looking at errno. It is only necessary when calling functions in which the value indicating an error condition (e.g. -1 for getpriority(2), or NULL for readdir(3)) is also a valid response from the function (nice value -1 or end of directory stream, respectively). – Dato Sep 05 '17 at 14:02