taskd.pl: avoid displaying spurious accept failed errors
When taskd.pl forks a child (using the spawn subroutine), it will
eventually reap it via SIGCHLD. This SIGCHLD will almost certainly
interrupt the accept() wait on new connections to the taskd socket
causing the accept() to return with an EINTR error which is then
reported. Since this is actually a normal condition in this case,
the error is simply spurious and should not be shown.
There are two problems that must be fixed to address this:
1) The SIGCHLD handler must preserve the Perl errno ($!) value so
that the EINTR error from accept() can be reliably detected. This
is accomplished by 'local $!' in the SIGCHLD handler. Otherwise
when the SIGCHLD handler calls waitpid() the $! that held the result
of the accept() call (which will be EINTR in this case) will be
replaced with the result of waitpid(). Since waitpid() is called in
a loop until it fails that result will usually be ECHILD after the
last zombie has been reaped.
2) When the accept() call fails and an EINTR state is detected, just
silently retry instead of displaying a spurious error message. It
was previously not possible to do this reliably without the fix
from (1).
With these fixes the spurious "accept failed: ..." messages are no
longer output by taskd.pl.