From: Stephen Hocking on
Hi all,

In my efforts to make the xrdp port more robust under FreeBSD, I have
discovered that sigwait (kind of an analogue to select(2), but for
signals rather than I/O) re-enables ignored signals in its list under
Linux, but not FreeBSD. The sesman daemon uses SIGCHLD to clean up
after a session has exited. Under Linux this works OK, under FreeSBD
it doesn't. I have worked around it in a very hackish manner (define a
dummy signal handler and enable it using signal, which means that the
sigwait call can then be unblocked by it), but am wondering if anyone
else has run across the same problem, and if so, if they fixed it in
an elegant manner. Also, does anyone know the correct semantics of
sigwait under this situation?


Stephen
_______________________________________________
freebsd-ports(a)freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ports
To unsubscribe, send any mail to "freebsd-ports-unsubscribe(a)freebsd.org"

From: Matthias Andree on
Stephen Hocking schrieb:
> Hi all,
>
> In my efforts to make the xrdp port more robust under FreeBSD, I have
> discovered that sigwait (kind of an analogue to select(2), but for
> signals rather than I/O) re-enables ignored signals in its list under
> Linux, but not FreeBSD.

If the application relies on sigwait() to wait for and extract an ignored signal
(SIG_IGN), it is non-portable, as it expects non-POSIX semantics, and should be
fixed by the upstream maintainer (I haven't checked that).

Note: Linux has the same semantics, quoting its manual page (on Ubuntu 9.10 beta):

sigwait suspends the calling thread until one of the signals in set is
delivered to the calling thread. It then stores the number of the sig‐
> nal received in the location pointed to by sig and returns. The signals
> in set must be blocked and not ignored on entrance to sigwait. If the
delivered signal has a signal handler function attached, that function
is not called.

> The sesman daemon uses SIGCHLD to clean up after a session has exited. Under
> Linux this works OK, under FreeSBD it doesn't.

Not sure I understand. How can it clean up if it's not made aware of child's
termination? Or do some Linux kernels behave in another way?

Setting SIGCHLD to SIG_IGN (default) means that the kernel will let go of the
child processes as they exit, rather than turn them into zombies. You cannot
wait() for them though.

> I have worked around it in a very hackish manner (define a
> dummy signal handler and enable it using signal, which means that the
> sigwait call can then be unblocked by it), but am wondering if anyone
> else has run across the same problem, and if so, if they fixed it in
> an elegant manner. Also, does anyone know the correct semantics of
> sigwait under this situation?

That is not a hackish workaround, but one of the few safe ways to sigwait() for
SIGCHLD. A version fixed thus should still work on Linux, so that fix should be
made by xrdp upstream.


The canonical reference would be the POSIX standard (IEEE Std 1003.1).

2008: http://www.opengroup.org/onlinepubs/9699919799/

2001, 2004 edition: http://www.opengroup.org/onlinepubs/000095399/

The latter is also known as the Single Unix Specification v3 (SUSv3).

HTH
_______________________________________________
freebsd-ports(a)freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ports
To unsubscribe, send any mail to "freebsd-ports-unsubscribe(a)freebsd.org"

From: Stephen Hocking on
On Thu, Oct 8, 2009 at 10:38 PM, Matthias Andree <matthias.andree(a)gmx.de> wrote:
> Stephen Hocking schrieb:
>> Hi all,
>>
>> In my efforts to make the xrdp port more robust under FreeBSD, I have
>> discovered that sigwait (kind of an analogue to select(2), but for
>> signals rather than I/O) re-enables ignored signals in its list under
>> Linux, but not FreeBSD.
>
> If the application relies on sigwait() to wait for and extract an ignored signal
> (SIG_IGN), it is non-portable, as it expects non-POSIX semantics, and should be
> fixed by the upstream maintainer (I haven't checked that).
>
> Note: Linux has the same semantics, quoting its manual page (on Ubuntu 9.10 beta):
>
>       sigwait  suspends the calling thread until one of the signals in set is
>       delivered to the calling thread. It then stores the number of the  sig‐
>>      nal received in the location pointed to by sig and returns. The signals
>>      in set must be blocked and not ignored on entrance to sigwait.  If  the
>       delivered  signal has a signal handler function attached, that function
>       is not called.
>
>> The sesman daemon uses SIGCHLD to clean up after a session has exited. Under
>> Linux this works OK, under FreeSBD it doesn't.
>
> Not sure I understand. How can it clean up if it's not made aware of child's
> termination? Or do some Linux kernels behave in another way?

It appears as if the documentation does not match up with the reality
in Linux's case. That's what the empirical evidence suggests anyway.
The code does does a waitpid after receiving the SIGCHLD to determine
what child process has exited and then searches its list of sessions
looking for that particular pid, so as to tidy up.

I can to some degree understand that implementation of sigwait, as if
you state your intention to wait for a particular signal, that means
that you don't wish to ignore it.

>
> Setting SIGCHLD to SIG_IGN (default) means that the kernel will let go of the
> child processes as they exit, rather than turn them into zombies. You cannot
> wait() for them though.
>
>> I have worked around it in a very hackish manner (define a
>> dummy signal handler and enable it using signal, which means that the
>> sigwait call can then be unblocked by it), but am wondering if anyone
>> else has run across the same problem, and if so, if they fixed it in
>> an elegant manner. Also, does anyone know the correct semantics of
>> sigwait under this situation?
>
> That is not a hackish workaround, but one of the few safe ways to sigwait() for
> SIGCHLD. A version fixed thus should still work on Linux, so that fix should be
> made by xrdp upstream.
>
>
> The canonical reference would be the POSIX standard (IEEE Std 1003.1).
>
> 2008: http://www.opengroup.org/onlinepubs/9699919799/
>
> 2001, 2004 edition: http://www.opengroup.org/onlinepubs/000095399/
>
> The latter is also known as the Single Unix Specification v3 (SUSv3).

Thanks for the references.
_______________________________________________
freebsd-ports(a)freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ports
To unsubscribe, send any mail to "freebsd-ports-unsubscribe(a)freebsd.org"

From: "Matthias Andree" on
Am 09.10.2009, 03:38 Uhr, schrieb Stephen Hocking
<stephen.hocking(a)gmail.com>:

> It appears as if the documentation does not match up with the reality
> in Linux's case. That's what the empirical evidence suggests anyway.
> The code does does a waitpid after receiving the SIGCHLD to determine
> what child process has exited and then searches its list of sessions
> looking for that particular pid, so as to tidy up.

My reception is: if the process wants SIGCHLD, it will have to install its
own handler, because the default disposition for this signal is SIG_IGN (=
discard signal and do not turn child process into a zombie).

So use your patch for FreeBSD, feed it to the upstream maintainer with a
copy of this thread and relevant quotes from the standard and manpage and
move on. :)

The alternative is to do away with SIGCHLD and use waitpid((pid_t)-1,
WNOHANG) to poll for children that have exited.

> I can to some degree understand that implementation of sigwait, as if
> you state your intention to wait for a particular signal, that means
> that you don't wish to ignore it.

That's outside the standard. If it works on a particular Linux kernel
version that doesn't mean it will work on every other. Why lose yourself
in empirical programming if there are standards?

--
Matthias Andree
_______________________________________________
freebsd-ports(a)freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ports
To unsubscribe, send any mail to "freebsd-ports-unsubscribe(a)freebsd.org"

From: Jilles Tjoelker on
On Thu, Oct 08, 2009 at 01:02:09PM +0300, Kostik Belousov wrote:
> On Thu, Oct 08, 2009 at 11:53:21AM +1100, Stephen Hocking wrote:
> > In my efforts to make the xrdp port more robust under FreeBSD, I have
> > discovered that sigwait (kind of an analogue to select(2), but for
> > signals rather than I/O) re-enables ignored signals in its list under
> > Linux, but not FreeBSD. The sesman daemon uses SIGCHLD to clean up
> > after a session has exited. Under Linux this works OK, under FreeSBD
> > it doesn't. I have worked around it in a very hackish manner (define a
> > dummy signal handler and enable it using signal, which means that the
> > sigwait call can then be unblocked by it), but am wondering if anyone
> > else has run across the same problem, and if so, if they fixed it in
> > an elegant manner. Also, does anyone know the correct semantics of
> > sigwait under this situation?

> ports@ is the wrong list to discuss the issue in the base system.

> Solaris 10 sigwait(2) manpage says the following:
> If sigwait() is called on an ignored signal, then the occurrence of the
> signal will be ignored, unless sigaction() changes the disposition.

> We have the same behaviour as Solaris, ingored signals are not queued or
> recorded regardeless of the presence of sigwaiting thread.

POSIX permits both behaviours here: a blocked and ignored signal may or
may not be discarded immediately on generation. Making this depend on
whether there is a sigwaiting thread seems broken, and I don't think
Linux does that.

I think your "very hackish" approach is correct: set up a dummy signal
handler after blocking the signal.

Additionally, POSIX requires applications to set the SA_SIGINFO flag if
they want queuing. This applies even if the signals are blocked and
received using sigwaitinfo(2) or sigtimedwait(2). The SA_SIGINFO flag
can only be set by setting a handler using sigaction(2). (Note, this
does not mean that all signals are queued if SA_SIGINFO is set. It means
that signals may not be queued if SA_SIGINFO is not set.)

--
Jilles Tjoelker
_______________________________________________
freebsd-ports(a)freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ports
To unsubscribe, send any mail to "freebsd-ports-unsubscribe(a)freebsd.org"