Skip to content
Advertisement

errno after accept in Linux socket programming

As stated in accept() man page in RETURN VALUE section:

Error handling
Linux accept() (and accept4()) passes already-pending network errors on the new socket as an error code from accept(). This behavior differs from other BSD socket implementations. For reliable operation the application should detect the network errors defined for the protocol after accept() and treat them like EAGAIN by retrying. In the case of TCP/IP, these are ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, and ENETUNREACH.

Does this mean one must check the value of errno right after the accept() returns and before checking the return value of accept() ? if yes, and if errno is set what steps must be taken?

here’s a snippet of my code handling accept() :

newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if((errno == ENETDOWN || errno == EPROTO || errno == ENOPROTOOPT || errno == EHOSTDOWN ||
    errno == ENONET || errno == EHOSTUNREACH || errno == EOPNOTSUPP || errno == ENETUNREACH))
    return;
if (newsockfd < 0)
{
    // error
}
else if(newsockfd > 0)
{
    // accepted a new connection
}
else
{
    // blah blah blah
}

I have concluded that in this case one might try again in a while. Is my conclusion correct?

Advertisement

Answer

First, you check accept() return value. If accept() return value is less than 0, then you should check errno. If it is ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, or ENETUNREACH, then you may call accept() again. Otherwise something bad has happened and you should stop calling accept() (you’ve passed bad listen socket as accept()‘s parameter, for example).

That’s how I understand the code.

And here is how the error handling may be done:

while (running) {
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
    if (newsockfd < 0)
    {
        // error
        perror ("accept");
        if((errno == ENETDOWN || errno == EPROTO || errno == ENOPROTOOPT || errno == EHOSTDOWN ||
            errno == ENONET || errno == EHOSTUNREACH || errno == EOPNOTSUPP || errno == ENETUNREACH)) {
            continue;
         }
         exit (EXIT_FAILURE);
    }

    // accepted a new connection
    // blah blah blah
}
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement