public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* EINTR vs ERESTARTSYS, ERESTARTSYS not defined
@ 2001-11-22 14:36 Phil Howard
  2001-11-22 15:15 ` Andreas Schwab
  2001-11-26 19:59 ` Alan Cox
  0 siblings, 2 replies; 5+ messages in thread
From: Phil Howard @ 2001-11-22 14:36 UTC (permalink / raw)
  To: linux-kernel

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

2.  ERESTARTSYS can be seen from system call and is defined somewhere

In user space I have to define __KERNEL__ to get programs to compile
when coded to know about all possible (valid?) values of errno from
system calls.  As seen from strace:

+=============================================================================
| [pid  6453] accept(5, 0xbffff908, [16]) = ? ERESTARTSYS (To be restarted)
| [pid  6453] --- SIGALRM (Alarm clock) ---
| [pid  6453] getppid()                   = 6452
| [pid  6453] gettimeofday({1006439405, 5879}, NULL) = 0
| [pid  6453] setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={9, 994121}}, NULL) = 0
| [pid  6453] rt_sigreturn(0x5)           = -1 EINTR (Interrupted system call)
| [pid  6453] accept(5, 0xbffff908, [16]) = ? ERESTARTSYS (To be restarted)
| [pid  6453] --- SIGALRM (Alarm clock) ---
| [pid  6453] getppid()                   = 6452
| [pid  6453] gettimeofday({1006439415, 6422}, NULL) = 0
| [pid  6453] setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={9, 993578}}, NULL) = 0
| [pid  6453] rt_sigreturn(0x5)           = -1 EINTR (Interrupted system call)
| [pid  6453] accept(5, 0xbffff908, [16]) = ? ERESTARTSYS (To be restarted)
+=============================================================================

-- 
-----------------------------------------------------------------
| Phil Howard - KA9WGN |   Dallas   | http://linuxhomepage.com/ |
| phil-nospam@ipal.net | Texas, USA | http://phil.ipal.org/     |
-----------------------------------------------------------------

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: EINTR vs ERESTARTSYS, ERESTARTSYS not defined
  2001-11-22 14:36 Phil Howard
@ 2001-11-22 15:15 ` Andreas Schwab
  2001-11-22 18:05   ` Phil Howard
  2001-11-26 19:59 ` Alan Cox
  1 sibling, 1 reply; 5+ messages in thread
From: Andreas Schwab @ 2001-11-22 15:15 UTC (permalink / raw)
  To: Phil Howard; +Cc: linux-kernel

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.

|> 2.  ERESTARTSYS can be seen from system call and is defined somewhere
|> 
|> In user space I have to define __KERNEL__ to get programs to compile
|> when coded to know about all possible (valid?) values of errno from
|> system calls.  As seen from strace:

strace is special here, because it gets more information than the traced
program would get.

|> +=============================================================================
|> | [pid  6453] accept(5, 0xbffff908, [16]) = ? ERESTARTSYS (To be restarted)

At this point the accept syscall hasn't actually finished yet, but rather
suspended to let the program execute the signal handler.  As soon as the
signal handler returns the syscall will be restarted.

Andreas.

-- 
Andreas Schwab                                  "And now for something
Andreas.Schwab@suse.de				completely different."
SuSE Labs, SuSE GmbH, Schanzäckerstr. 10, D-90443 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: EINTR vs ERESTARTSYS, ERESTARTSYS not defined
       [not found] <20011122083623.A18057@vega.ipal.net.suse.lists.linux.kernel>
@ 2001-11-22 15:28 ` Andi Kleen
  0 siblings, 0 replies; 5+ messages in thread
From: Andi Kleen @ 2001-11-22 15:28 UTC (permalink / raw)
  To: Phil Howard; +Cc: linux-kernel

Phil Howard <phil-linux-kernel@ipal.net> writes:

> | 
> | /* Should never be seen by user programs */

This applies to user programs, but not to strace. Try it: the actual user
program doesn't see them. strace is not a ordinary user program here.


-Andi


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: EINTR vs ERESTARTSYS, ERESTARTSYS not defined
  2001-11-22 15:15 ` Andreas Schwab
@ 2001-11-22 18:05   ` Phil Howard
  0 siblings, 0 replies; 5+ messages in thread
From: Phil Howard @ 2001-11-22 18:05 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linux-kernel

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/     |
-----------------------------------------------------------------

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: EINTR vs ERESTARTSYS, ERESTARTSYS not defined
  2001-11-22 14:36 Phil Howard
  2001-11-22 15:15 ` Andreas Schwab
@ 2001-11-26 19:59 ` Alan Cox
  1 sibling, 0 replies; 5+ messages in thread
From: Alan Cox @ 2001-11-26 19:59 UTC (permalink / raw)
  To: Phil Howard; +Cc: linux-kernel

> In user space I have to define __KERNEL__ to get programs to compile
> when coded to know about all possible (valid?) values of errno from
> system calls.  As seen from strace:

Beware of strace data. Record the actual syscall returns in your program.
strace sees restarts, your app doesnt

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2001-11-26 19:52 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20011122083623.A18057@vega.ipal.net.suse.lists.linux.kernel>
2001-11-22 15:28 ` EINTR vs ERESTARTSYS, ERESTARTSYS not defined Andi Kleen
2001-11-22 14:36 Phil Howard
2001-11-22 15:15 ` Andreas Schwab
2001-11-22 18:05   ` Phil Howard
2001-11-26 19:59 ` Alan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox