linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* accept() and signals
@ 2004-03-31 20:59 Cesar Rincon
  2004-03-31 22:21 ` Glynn Clements
  0 siblings, 1 reply; 5+ messages in thread
From: Cesar Rincon @ 2004-03-31 20:59 UTC (permalink / raw)
  To: linux-c-programming

Hi.

I have a program that installs a handler for SIGINT and SIGTERM (using
signal(), not sigaction()).  This handler only sets a global flag and
returns.  The flag is checked elsewhere to initiate a graceful
shutdown.  The program is not multithreaded.

When the program is blocked on a call to accept(), and a signal is
received, I would expect my handler to execute, and also accept() to
return immediately with EINTR, allowing me to check my flag, etc.
Actually, when compiled in AIX, it behaves precisely that way.

However, in Linux (2.6.3), the handler is in fact executed, but
accept() does not seem to unblock.  Thus my program does not shutdown
until a new connection is accepted.

I feel like I fell into some obvious and documented gotcha, but I
really can not see what it is that I'm doing wrong, and Google is not
helping.  Is this the expected behaviour of accept(), in Linux?

 -CR

-- 
Ceterum censeo: SCO delenda est.

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

* Re: accept() and signals
  2004-03-31 20:59 accept() and signals Cesar Rincon
@ 2004-03-31 22:21 ` Glynn Clements
  2004-03-31 23:54   ` Cesar Rincon
  0 siblings, 1 reply; 5+ messages in thread
From: Glynn Clements @ 2004-03-31 22:21 UTC (permalink / raw)
  To: Cesar Rincon; +Cc: linux-c-programming


Cesar Rincon wrote:

> I have a program that installs a handler for SIGINT and SIGTERM (using
> signal(), not sigaction()).  This handler only sets a global flag and
> returns.  The flag is checked elsewhere to initiate a graceful
> shutdown.  The program is not multithreaded.
> 
> When the program is blocked on a call to accept(), and a signal is
> received, I would expect my handler to execute, and also accept() to
> return immediately with EINTR, allowing me to check my flag, etc.
> Actually, when compiled in AIX, it behaves precisely that way.
> 
> However, in Linux (2.6.3), the handler is in fact executed, but
> accept() does not seem to unblock.  Thus my program does not shutdown
> until a new connection is accepted.
> 
> I feel like I fell into some obvious and documented gotcha, but I
> really can not see what it is that I'm doing wrong, and Google is not
> helping.  Is this the expected behaviour of accept(), in Linux?

There are two distinct flavours of signal() semantics: BSD and SysV. 
The BSD version is equivalent to using sigaction() with an sa_flags
value of SA_RESTART, while the SysV version is equivalent to using
sigaction() with an sa_flags value of SA_RESETHAND|SA_NODEFER.

The default behaviour of signal() in GNU libc 2.x is the BSD
behaviour, i.e. interrupted system calls are automatically restarted,
and the handler isn't reset upon receipt of a signal. If you want
system calls such as accept() to be interrupted, you should use
sigaction() without the SA_RESTART flag.

More generally, the safest approach is to always use sigaction()
rather than to assume a particular behaviour from signal().

-- 
Glynn Clements <glynn.clements@virgin.net>

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

* Re: accept() and signals
  2004-03-31 22:21 ` Glynn Clements
@ 2004-03-31 23:54   ` Cesar Rincon
  2004-04-01  0:58     ` Glynn Clements
  0 siblings, 1 reply; 5+ messages in thread
From: Cesar Rincon @ 2004-03-31 23:54 UTC (permalink / raw)
  To: Glynn Clements; +Cc: linux-c-programming

Ipsissima verba Glynn Clements:
> The default behaviour of signal() in GNU libc 2.x is the BSD
> behaviour, i.e. interrupted system calls are automatically
> restarted, and the handler isn't reset upon receipt of a signal. If
> you want system calls such as accept() to be interrupted, you should
> use sigaction() without the SA_RESTART flag.

Which works perfectly, thank you very much.

> More generally, the safest approach is to always use sigaction()
> rather than to assume a particular behaviour from signal().

And it says that much in the manual, duh.  It's just that I was using
Spanish-translated dev manpages, which are, now I know, ahem, a bit
outdated.  E.g., sigaction(2) says that SA_RESETHAND is the default
behaviour of signal()...

Oh, well.  Firing up a mail to the translators.

Thanks again.

 -CR

-- 
Ceterum censeo: SCO delenda est.

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

* Re: accept() and signals
  2004-03-31 23:54   ` Cesar Rincon
@ 2004-04-01  0:58     ` Glynn Clements
  2004-04-01  3:08       ` Cesar Rincon
  0 siblings, 1 reply; 5+ messages in thread
From: Glynn Clements @ 2004-04-01  0:58 UTC (permalink / raw)
  To: Cesar Rincon; +Cc: linux-c-programming


Cesar Rincon wrote:

> > The default behaviour of signal() in GNU libc 2.x is the BSD
> > behaviour, i.e. interrupted system calls are automatically
> > restarted, and the handler isn't reset upon receipt of a signal. If
> > you want system calls such as accept() to be interrupted, you should
> > use sigaction() without the SA_RESTART flag.
> 
> Which works perfectly, thank you very much.
> 
> > More generally, the safest approach is to always use sigaction()
> > rather than to assume a particular behaviour from signal().
> 
> And it says that much in the manual, duh.  It's just that I was using
> Spanish-translated dev manpages, which are, now I know, ahem, a bit
> outdated.  E.g., sigaction(2) says that SA_RESETHAND is the default
> behaviour of signal()...

It used to be. Versions of libc based upon GNU libc 1.x (i.e. up to
and including libc-5) used the SysV semantics by default. It was
changed because:

1. Resetting the signal disposition (i.e. the SysV semantics or the
SA_RESETHAND flag) is the wrong thing to do more often than it is the
right thing to do.

2. Interrupting system calls (i.e. the SysV semantics) is probably the
wrong thing to do at least as often as it is the right thing to do.

3. Interrupting system calls when the programmer wasn't expecting it
is arguably worse than not interrupting them when the programmer was
expecting it. In the latter case, the programmer will probably
discover (and presumably fix) the problem fairly quickly. In the
former case, the program will survive cursory testing but may fail in
actual use.

Actually, my signal(2) manpage (English, supplied with RedHat 6.2,
which uses GNU libc 2.1.3) says:

       Unlike  on  BSD  systems, signals under Linux are reset to
       their default  behavior  when  raised.   However,  if  you
       include  <bsd/signal.h>  instead of <signal.h> then signal
       is redefined as __bsd_signal and signal has the BSD seman­
       tics.   Both versions of signal are library routines built
       on top of sigaction(2).

Which is incorrect. So it may not be just the translation which is
outdated.

A large part of the problem is that the GNU project officially favours
texinfo documentation over traditional manual pages. The manpages for
most of the libc functions were written by third parties (and some of
them are taken directly from BSD).

-- 
Glynn Clements <glynn.clements@virgin.net>
-
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: accept() and signals
  2004-04-01  0:58     ` Glynn Clements
@ 2004-04-01  3:08       ` Cesar Rincon
  0 siblings, 0 replies; 5+ messages in thread
From: Cesar Rincon @ 2004-04-01  3:08 UTC (permalink / raw)
  To: Glynn Clements; +Cc: linux-c-programming

Ipsissima verba Glynn Clements:
> It used to be. Versions of libc based upon GNU libc 1.x (i.e. up to
> and including libc-5) used the SysV semantics by default. It was
> changed because:
...

Sounds reasonable.

> Actually, my signal(2) manpage (English, supplied with RedHat 6.2,
> which uses GNU libc 2.1.3) says:
> 
>        Unlike  on  BSD  systems, signals under Linux are reset to
>        their default  behavior  when  raised.   However,  if  you
>        include  <bsd/signal.h>  instead of <signal.h> then signal
>        is redefined as __bsd_signal and signal has the BSD seman­
>        tics.   Both versions of signal are library routines built
>        on top of sigaction(2).
>
> Which is incorrect. So it may not be just the translation which is
> outdated.

For what it's worth, my English manpage (supplied by Debian Sid, libc
2.3.2), does not include that text.  It pretty much explains what
you've told me here, and other interesting information (including the
list of POSIX "safe functions" for use in signal handlers).

And my Spanish manpage (btw, a *completely* different one) actually
says that from libc6 on, signal() uses BSD semantics, and points to
"sysv_signal()" if SysV semantics are required (which the English
manpage qualifies as "not recommended").  The sigaction(2) manpage,
though, seems to be much older.

> A large part of the problem is that the GNU project officially
> favours texinfo documentation over traditional manual pages. The
> manpages for most of the libc functions were written by third
> parties (and some of them are taken directly from BSD).

I see.  This is, IMO, somewhat unfortunate.  I never really got the
hang of the texinfo thing.  But, given the state of the manpages, I
think I better teach me to like it soon :-/

 -CR

-- 
Ceterum censeo: SCO delenda est.
-
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2004-04-01  3:08 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-31 20:59 accept() and signals Cesar Rincon
2004-03-31 22:21 ` Glynn Clements
2004-03-31 23:54   ` Cesar Rincon
2004-04-01  0:58     ` Glynn Clements
2004-04-01  3:08       ` Cesar Rincon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).