lkml.org 
[lkml]   [2001]   [Nov]   [22]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
/
DateThu, 22 Nov 2001 12:05:42 -0600
FromPhil Howard <>
SubjectRe: EINTR vs ERESTARTSYS, ERESTARTSYS not defined
On Thu, Nov 22, 2001 at 04:15:40PM +0100, Andreas Schwab wrote:

| Phil Howard <phil-linux-kernel@ipal.net> writes:
| 
| |> The accept() call does indeed return errno==ERESTARTSYS to user space
| |> when coming back from signal handling, even though other things like
| |> poll() return errno==EINTR.  This would not really be a problem except
| |> for this in include/linux/errno.h starting at line 6:
| |> 
| |> +=============================================================================
| |> | #ifdef __KERNEL__
| |> | 
| |> | /* Should never be seen by user programs */
| |> | #define ERESTARTSYS     512
| |> | #define ERESTARTNOINTR  513
| |> | #define ERESTARTNOHAND  514     /* restart if no handler.. */
| |> | #define ENOIOCTLCMD     515     /* No ioctl command */
| |> +=============================================================================
| |> 
| |> So which way is it _supposed_ to be (so someone can patch things up
| |> to make it consistent):
| |> 
| |> 1.  User space should never see ERESTARTSYS from any system call
| 
| Yes.  The kernel either transforms it to EINTR, or restarts the syscall
| when the signal handler returns.

This code periodically quits because sometimes there is an unknown errno.

            for (;;) {
                memset( arg_sock_addr, 0, * arg_sock_addrlen );
                new_fd = accept( arg_sockfd_list[fd_index], arg_sock_addr, arg_sock_addrlen );
                if ( new_fd >= 0 ) break;
                if ( errno == EINTR ) continue;
                if ( errno == ECONNABORTED ) continue;
                break;
            }
            if ( new_fd <= 2 ) {
                perror( "daemon_accept: accept" );
                if ( fd_count > 1 ) continue;
                _exit( 1 ); // not very graceful
            }
Then strace showed ERESTARTSYS happening, and when I changed the code to:

            for (;;) {
                memset( arg_sock_addr, 0, * arg_sock_addrlen );
                new_fd = accept( arg_sockfd_list[fd_index], arg_sock_addr, arg_sock_addrlen );
                if ( new_fd >= 0 ) break;
                if ( errno == EINTR ) continue;
                if ( errno == ERESTARTSYS ) continue;
                if ( errno == ECONNABORTED ) continue;
                break;
            }
            if ( new_fd <= 2 ) {
                perror( "daemon_accept: accept" );
                if ( fd_count > 1 ) continue;
                _exit( 1 ); // not very graceful
            }
it started working solidly.  I had to define __KERNEL__ to get it.  But I don't
want to leave that in there for portable code.

Could this be an unintended leak of ERESTARTSYS?  I take it that what the comments
say is what is intended, and that what I actually get isn't.

-- 
-----------------------------------------------------------------
| Phil Howard - KA9WGN |   Dallas   | http://linuxhomepage.com/ |
| phil-nospam@ipal.net | Texas, USA | http://phil.ipal.org/     |
-----------------------------------------------------------------
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 13:13    [from the cache]
©2003-2008