Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Aug 2011 22:56:09 +0200
From:      Jilles Tjoelker <jilles@stack.nl>
To:        Kostik Belousov <kostikbel@gmail.com>
Cc:        freebsd-stable@freebsd.org, Slawa Olhovchenkov <slw@zxy.spb.ru>
Subject:   Re: sigwait return 4
Message-ID:  <20110824205609.GA96070@stack.nl>
In-Reply-To: <20110824190703.GY17489@deviant.kiev.zoral.com.ua>
References:  <20110824181907.GA48394@zxy.spb.ru> <20110824190703.GY17489@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Aug 24, 2011 at 10:07:03PM +0300, Kostik Belousov wrote:
> On Wed, Aug 24, 2011 at 10:19:07PM +0400, Slawa Olhovchenkov wrote:
> > System is 8.2-RELEASE (GENERIC), amd64.
> > Application -- i386 for freebsd7.

> > In ktrace dump I find some strange result:

> >  22951 100556 kas-milter CALL  sigwait(0xffdfdf80,0xffdfdf7c)
> >  22951 100556 kas-milter RET   sigwait 4
> >  22951 100556 kas-milter PSIG  SIGUSR2 caught handler=0x804c0f0 mask=0x4003 code=0x0

> > RET   sigwait 4 confused me, and, I think, confused application too.

> > man sigwait:

> > ERRORS
> >      The sigwait() system call will fail if:

> >      [EINVAL]           The set argument specifies one or more invalid signal
> >                         numbers.

> >      [EFAULT]           Any arguments point outside the allocated address
> >                         space or there is a memory protection fault.

> > How sigwait can return '4'?
> > May be EINTR, converted from ERESTART? But kern_sigtimedwait from
> > sigwait must be called with timeout == NULL...

> What should the system do for a delivered signal not present in the set ?
> I guess this is the case of your ktrace.

> Looking at the SUSv4, I see no mention of the situation, but in Oracle
> SunOS 5.10 man page for sigwait(2), it is said explicitely
> EINTR The wait was interrupted by an unblocked, caught signal.

> So I think that we have a bug in the man page.

> diff --git a/lib/libc/sys/sigwait.2 b/lib/libc/sys/sigwait.2
> index 8c00cf4..b462201 100644
> --- a/lib/libc/sys/sigwait.2
> +++ b/lib/libc/sys/sigwait.2
> @@ -27,7 +27,7 @@
>  .\"
>  .\" $FreeBSD$
>  .\"
> -.Dd November 11, 2005
> +.Dd August 24, 2011
>  .Dt SIGWAIT 2
>  .Os
>  .Sh NAME
> @@ -94,6 +94,8 @@ The
>  .Fn sigwait
>  system call will fail if:
>  .Bl -tag -width Er
> +.It Bq Er EINTR
> +The system call was interrupted by an unblocked, caught signal.
>  .It Bq Er EINVAL
>  The
>  .Fa set

This patch would be wrong, except to document existing behaviour in
-stable branches.

sigwait() was fixed not to return EINTR in 9-current in r212405 (fixed
up in r219709). The discussion started at
http://lists.freebsd.org/pipermail/freebsd-threads/2010-September/004892.html

Solaris is simply wrong in the same way we were wrong. Although POSIX
may not be as clear on this as one may like, its intention is clear and
additionally not returning EINTR reduces subtle portability problems.

Note that sigwaitinfo() and sigtimedwait() may return EINTR. SA_RESTART
applies to sigwaitinfo() but not to sigtimedwait() (because the timeout
cannot be restarted).

-- 
Jilles Tjoelker



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110824205609.GA96070>