The Socket process handles interrupted system calls and EINTR error handling returned by the Accept Function

Source: Internet
Author: User

The Socket process handles interrupted system calls and EINTR error handling returned by the Accept Function
We use slow system calls to describe system calls (function calls) that may be blocked forever, such as accept and read. Permanent blocking of system calls means that calls may never return. Most network-supported functions belong to this type. For example, if no customer connects to the server, the server does not return a guarantee for the accept call. Similarly, if a customer never sends a line of text that requires server bounce, the server will never return a read call. Other examples of slow system calls are the reading and writing of the pipe and terminal devices. One exception is disk IO, which generally returns to the caller.

A system call may return an EINTR error when a process is blocked or slow. Some kernels Automatically Restart some interrupted system calls. For ease of transplantation, when we write a program to capture signals (most concurrent servers capture SIGCHLD), we must be prepared for the slow system call to return EINTR.

In order to handle an interrupted accept, we have made every effort to handle the accept call. Other slow System Call functions can also be handled in this way:

Method 1: use continue to enter the next loop of for, and restart the interrupted system call;

for( ; ; ) {    clilen = sizeof(cliaddr);    if((connfd = accept(listenfd, (SA *)&cliaddr, &clilen)) < 0) {        if(errno == EINTR)             continue;        else             err_sys("accept error");    }}

You can also use goto to implement the same function and restart the interrupted system call;

Again:for( ; ; ) {    clilen = sizeof(cliaddr);    if((connfd = accept(listenfd, (SA *)&cliaddr, &clilen)) < 0) {        if(errno == EINTR)             goto Again;        else             err_sys("accept error");    }}

It should also be noted that:

The basic rule for slow system calls is: when a process blocked by a slow System Call captures a signal and switches the corresponding signal processing function to return, the system call may return an EINTR error; some system kernels Automatically Restart some interrupted system calls;


In this Code, what we do is to restart the interrupted system call. This is suitable for accept and other functions such as read, write, select, and open, but there is a function that we cannot restart ourselves: connect. If this function returns an INTER, we cannot call it any more. Otherwise, an error is returned. When 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 writing the final version of the TCP server for processing the accept returned EINTR error, pay attention to the following questions:

>>> When fork sub-processes, the SIGCHLD signal must be captured (the SIGCHLD signal is the signal sent to the kernel when the sub-process ends)

>>> When a signal is captured, the interrupted system call must be processed.

>>> The SIGCHLD signal processing function (sig_chld) must be correctly written. The waitpid function should be used to kill dead processes;


The following is the "final version of the TCP server program for processing the accept function to return an EINTR error ":

#include 
 
  intmain(int argc, char **argv){    int listenfd, connfd;    pid_t child_pid;    socklen_t clilen;    struct sockaddr_in cliaddr, servaddr;    void sig_chld(int);        listenfd = Socket(AF_INET, SOCK_STREAM, 0);    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    servaddr.sin_port = htons(SERV_PORT);        Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));    listen(listenfd, LISTENQ);    Signal(SIGCHLD, sig_chld);        for( ; ; ) {        clilen = sizeof(cliaddr);        if( (connfd = accept(listenfd, (SA *)&cliaddr, &clilen)) < 0 ) {            if(errno == EINTR)                 continue;            else                 err_sys("accept error");        }        if( (child_pid = Fork()) == 0 ) {            Close(listenfd);            str_cli(connfd);            exit(0);        }        Close(connfd);    }}
 

I have been busy reading books recently, so I have little time to write blogs and refresh questions ~~

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.