2

I researched and found that signal interruption can happen when programming with sockets. I have searched and found that in case of signal interruption, we should retry. That is, I have to catch the error and retry. I have to create socket like this.

int create_sock()
{
    int sock;

    while (1)
    {
        sock = socket(AF_INET, SOCK_STREAM, 0);

        if (sock == -1)
        {
            if (errno == EINTR)
            {
                continue;
            }
            else
            {
                perror("create_sock");
                exit(-1);
            }
        }

        break;
    }

    return sock;

}

Should I follow the above procedure in case of close, send and connect function?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Nayan
  • 151
  • 9
  • `EINTR` can definitely happen during `send`. You should read the 'man pages' for each of those syscalls; they will detail each of the error cases, and any special requirements. E.g., IIRC, for `send`, you have to pass exactly the same args when you retry. – lockcmpxchg8b Sep 01 '18 at 17:34
  • 2
    For `connect()` and `send()` and other similar operations (including `read()` and `write()`), you should consider wrapping the functions in a retry loop. The case of `close()` is trickier — it's probably best to assume that it succeeded and the descriptor isn't available when the call returns, even if `errno == EINTR`. I don't think your loop structure is good; it should be more like `while ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { if (errno != EINTR) { perror("…"); exit(1); } }`. That has 5 lines in the body of the loop instead of 14 (ignoring the braces around the body of the loop). – Jonathan Leffler Sep 01 '18 at 17:42
  • 1
    See [`close()` is not closing socket properly](https://stackoverflow.com/questions/12730477/close-is-not-closing-socket-properly) and [If `close(2)` fails with EIO, will the file descriptor still be deleted](https://stackoverflow.com/questions/7297001/if-close2-fails-with-eio-will-the-file-descriptor-still-be-deleted). There may also be other relevant Q&A on SO. – Jonathan Leffler Sep 01 '18 at 18:06
  • Note: [`socket()`](http://man7.org/linux/man-pages/man2/socket.2.html) will not be interrupted by a signal in any [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html)y system. For Linux in particular, you can check the [man pages](http://man7.org/linux/man-pages/index.html) whether a call can return with an EINTR error or not. – Nominal Animal Sep 01 '18 at 19:32

1 Answers1

4

Is checking EINTR necessary for all operation of socket? Yes, ideally you should check. Not only socket() there are many system call which reports EINTR ERRORS if signal occurred while the system call was in progress.

From manual page of signal(7)

Interruption of system calls and library functions by signal handlers If a signal handler is invoked while a system call or library function call is blocked, then either:

   * the *call is automatically  restarted  after  the  signal
     handler returns*; or

   * the call fails with the error **EINTR**.

If a blocked call to one of the following interfaces is interrupted by a signal handler, then the call will be automatically restarted after the signal handler returns if the SA_RESTART flag was used; otherwise the call will fail with the error EINTR: Socket interfaces: accept(2), connect(2), recv(2), recvfrom(2), recvmsg(2), send(2), sendto(2), and sendmsg(2), unless a timeout has been set on the socket (see below).

Gil Hamilton
  • 11,973
  • 28
  • 51
Achal
  • 11,821
  • 2
  • 15
  • 37
  • That is true for many system calls (and, as cited, most socket-related system calls), but *not* for `socket(2)` in particular. The general rule of thumb for system calls is: if it may block for some indefinite period of time, then `EINTR` is a potential cause of error. But `socket(2)` never has reason to block since it is simply allocating some control structures within the kernel. As @lockcmpxchg8b noted in a comment under the question above, check the manual page for each system call. – Gil Hamilton Sep 01 '18 at 18:39