The socket process handles interrupted system calls and the Accept function returns EINTR error handling

Source: Internet
Author: User
Tags error handling signal handler

Transfer from Http://blog.csdn.net/keshacookie/article/details/40717059?utm_source=tuicool

We use slow system calls to describe system calls (function calls) that may be blocked forever, such as Accept,read. A system call that is never blocked means that a call may never be returned, and most network support functions fall into this category. For example, if no customer is connected to the server, the server does not return a guarantee for the call to accept. Similarly, if a customer never sends a line of text that requires the server to be shot back, the server's call to read will never return. Other examples of slow system calls are the reading and writing of pipelines and end devices. One exception is disk IO, which he generally returns to the caller.

When a process jams and a slow system call captures a signal, the system call may return a EINTR error when the signal handler returns. Some cores automatically reboot some of the interrupted system calls. For portability, when we write a program that captures signals (most concurrent servers capture SIGCHLD), we must be prepared to return EINTR for slow system calls.

In order to handle an interrupted accept, we take care of the call to accept, and other slow system call functions can also be processed as follows:

The first method: use continue to enter for the next loop, thereby restarting the interrupted system call;

  1. for (;;)
  2. {
  3. Clilen = sizeof (CLIADDR);
  4. if (connfd = Accept (LISTENFD, (SA *) &cliaddr, &clilen)) < 0) {
  5. if (errno = = eintr)
  6. continue;
  7. Else
  8. Err_sys ("Accept error");
  9. }
  10. }


or use Goto to achieve the same function, but also let the interrupted system call restart;

  1. Again:
  2. for (;;)
  3. {
  4. Clilen = sizeof (CLIADDR);
  5. if (connfd = Accept (LISTENFD, (SA *) &cliaddr, &clilen)) < 0) {
  6. if (errno = = eintr)
  7. Goto Again;
  8. Else
  9. Err_sys ("Accept error");
  10. }
  11. }


It is also stated that:

The basic rule for slow system calls is that when a process blocking a slow system call captures a signal, the system call may return a EINTR error when the corresponding signal processing function is returned, and some system cores will automatically reboot some of the interrupted system calls;


In this code, all we do is reboot the interrupted system call, which is appropriate for the accept and other functions such as read,write,select and open, but there is a function we cannot restart by ourselves: Connect. If this function returns Inter, we can no longer call him or return an error. When the connet is interrupted by a captured signal and does not restart automatically, we must call Select to wait for the connection to complete.


Finally, when we write the final version of the TCP server that handles the Accept return EINTR error, there are a couple of questions to note first:

>>> When you fork a child process, you must capture the SIGCHLD signal (theSIGCHLD signal is the signal sent to the kernel when the child process ends)

>>> the interrupted system call must be processed when the signal is captured

>>> SIGCHLD Signal processing function (SIG_CHLD) must be correctly written, should use the Waitpid function to kill the zombie process;


The following is the final version of the TCP server program that handles the Accept function return EINTR error:

    1. #include <unp.h>
    2. Int
    3. Main (int argc, char **argv)
    4. {
    5. int LISTENFD, CONNFD;
    6. pid_t Child_pid;
    7. Socklen_t Clilen;
    8. struct sockaddr_in cliaddr, servaddr;
    9. void sig_chld (int);
    10. LISTENFD = Socket (af_inet, sock_stream, 0);
    11. Bzero (&servaddr, sizeof (SERVADDR));
    12. servaddr.sin_family = af_inet;
    13. SERVADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);
    14. Servaddr.sin_port = htons (Serv_port);
    15. Bind (LISTENFD, (SA *) &servaddr, sizeof (SERVADDR));
    16. Listen (LISTENFD, Listenq);
    17. Signal (SIGCHLD, SIG_CHLD);
    18. for (;;) {  
    19. Clilen = sizeof (CLIADDR);
    20. if (connfd = Accept (LISTENFD, (SA *) &cliaddr, &clilen)) < 0) {
    21. if (errno = = eintr)
    22. continue;
    23. Else
    24. Err_sys ("Accept error");
    25. }
    26. if ((Child_pid = Fork ()) = = 0) {
    27. Close (LISTENFD);
    28. STR_CLI (CONNFD);
    29. Exit (0);
    30. }
    31. Close (CONNFD);
    32. }
    33. }

The socket process handles interrupted system calls and the Accept function returns eintr error handling (RPM)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.