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

Source: Internet
Author: User
Tags goto signal handler

We use slow system calls to describe the system calls (function calls) that may be blocked forever, such as accept. Read and so on. A system call that is never blocked means that a call may never be returned. Most network support functions fall into this category. For example, if no client is connected to the server, the server's call to accept does not return a guarantee. Similar to. Suppose 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. Examples of other slow system calls are read and write to pipelines and end devices.

One exception is disk IO. He usually returns to the caller.

A signal is captured when a process is blocked with a slow system call. When the signal handler returns, the system call may return a EINTR error. Some cores themselves proactively 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 for a slow system call to return to EINTR.

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 the next loop for the for, restarting 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");}    }

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

Again:for (;;) {    Clilen = sizeof (CLIADDR);    if (CONNFD = Accept (LISTENFD, (SA *) &cliaddr, &clilen)) < 0) {        if (errno = = eintr)             goto Again;        else             Err_sys ("Accept Error");}    }

It is also stated that:

The basic rule for slow system calls is that when a process that plugs into a slow system call captures a signal tangent to the corresponding signal processing function return, the system call may return a EINTR error, while some system cores will voluntarily reboot some of the interrupted system calls;


In this code, all we do is restart the interrupted system call, for accept and other such as read. Write The functions of Select and open are appropriate, but there is a function that we cannot restart ourselves: connect. Suppose this function returns Inter. We can't call him again, or we'll return an error.

When the connet is interrupted by a captured signal and does not voluntarily restart itself, we must call Select to wait for the connection to complete.


At last. When we write the TCPServer finally version number that handles the Accept return EINTR error. There are a few questions to note first:

>>> When you fork a child process, you must capture the SIGCHLD signal (the SIGCHLD signal is the end of the child process. Signals sent to the kernel )

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

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


Here's the "TCPServer program that handles the Accept function return EINTR error" finally version number:

#include <unp.h>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);}    }

Recently are busy reading, so little time to write blog and brush the question ~ ~

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

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.