Mailing List Archive

can waitpid() fail?
Hi,

src/log.c has the following construction:

while (waitpid(pid, &status, 0) != pid);

To my understanding, this will spin until waitpid() returns pid, but
it will spin forever if waitpid fails.

Shouldn't there be a check for error return, for example if the child
is already dead by the time we reach this code?

Greetings
Marc, by all means not a C programmer

--
-----------------------------------------------------------------------------
Marc Haber | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany | lose things." Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature | How to make an American Quilt | Fax: *49 621 72739835
Re: can waitpid() fail? [ In reply to ]
On Fri, 11 Mar 2005, Marc Haber wrote:

> src/log.c has the following construction:
>
> while (waitpid(pid, &status, 0) != pid);
>
> To my understanding, this will spin until waitpid() returns pid, but
> it will spin forever if waitpid fails.
>
> Shouldn't there be a check for error return, for example if the child
> is already dead by the time we reach this code?

If the child has already finished, waitpid will return its pid
immediately. Even when completed, children wait until their parent reaps
them (if created in the right way). These are so-called "zombie"
processes. Short of the whole OS going mad, I can't see how this can
fail. After all, the whole code is just a few lines long:

pid = fork();
if (pid == 0)
{ 3 lines of code }
while (waitpid(pid, &status, 0) != pid);

Er wait, I *can* see how it can go wrong. If fork() fails ...

Noted.

--
Philip Hazel University of Cambridge Computing Service,
ph10@cus.cam.ac.uk Cambridge, England. Phone: +44 1223 334714.
Get the Exim 4 book: http://www.uit.co.uk/exim-book
Re: can waitpid() fail? [ In reply to ]
> pid = fork();
> if (pid == 0)
> { 3 lines of code }
> while (waitpid(pid, &status, 0) != pid);
>
> Er wait, I *can* see how it can go wrong. If fork() fails ...

Don't forget EINTR, either.

I don't know how Exim deals with SIGCHLD, but from the Linux manual:

POSIX.1-2001 specifies that if the disposition of SIGCHLD is set to
SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD (see sigaction(2)),
then children that terminate do not become zombies and a call to wait()
or waitpid() will block until all children have terminated, and then
fail with errno set to ECHILD. (The original POSIX standard left the
behaviour of setting SIGCHLD to SIG_IGN unspecified.) Linux 2.6 con-
forms to this specification. However, Linux 2.4 (and earlier) does
not: if a wait() or waitpid() call is made while SIGCHLD is being
ignored, the call behaves just as though SIGCHLD were not being
ingored, that is, the call blocks until the next child terminates and
then returns the process ID and status of that child.

I can check a bunch other systems RSN, but to be safe, I suggest to just
deal with waitpid() returning -1, ignoring the condition for anything
but EINTR.

Michael
Re: can waitpid() fail? [ In reply to ]
Hi Philip,

thanks for considering.

On Fri, Mar 11, 2005 at 02:14:27PM +0000, Philip Hazel wrote:
> If the child has already finished, waitpid will return its pid
> immediately.

Only if the child has not yet been reaped by something else.

> Er wait, I *can* see how it can go wrong. If fork() fails ...
>
> Noted.

Thanks.

There is also similar code in src/deliver.c where the error checking
looks like it is not done as consequently as it should be.

Greetings
Marc

--
-----------------------------------------------------------------------------
Marc Haber | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany | lose things." Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature | How to make an American Quilt | Fax: *49 621 72739835
Re: can waitpid() fail? [ In reply to ]
On Fri, 11 Mar 2005, Marc Haber wrote:

> Only if the child has not yet been reaped by something else.

Well, yes, but who else is going to reap it?

> There is also similar code in src/deliver.c where the error checking
> looks like it is not done as consequently as it should be.

Thanks.

--
Philip Hazel University of Cambridge Computing Service,
ph10@cus.cam.ac.uk Cambridge, England. Phone: +44 1223 334714.
Get the Exim 4 book: http://www.uit.co.uk/exim-book
Re: can waitpid() fail? [ In reply to ]
On Fri, 11 Mar 2005, Michael Haardt wrote:

> > Er wait, I *can* see how it can go wrong. If fork() fails ...
>
> Don't forget EINTR, either.

That's the point of the loop.

> I don't know how Exim deals with SIGCHLD, but from the Linux manual:

That's what I was glossing over when I said "if it's created correctly";
I meant "with SIGCHLD suitably set up".

--
Philip Hazel University of Cambridge Computing Service,
ph10@cus.cam.ac.uk Cambridge, England. Phone: +44 1223 334714.
Get the Exim 4 book: http://www.uit.co.uk/exim-book
Re: can waitpid() fail? [ In reply to ]
Hi,

On Fri, Mar 11, 2005 at 04:55:46PM +0000, Philip Hazel wrote:
> On Fri, 11 Mar 2005, Marc Haber wrote:
> > Only if the child has not yet been reaped by something else.
>
> Well, yes, but who else is going to reap it?

We are currently experiencing endless loops in connection with
libnss-ldap, and there are known issues with that library. I do not
fully grasp the implications. Maybe a look at
http://bugs.debian.org/299051 helps the expert to judge.

Greetings
Marc

--
-----------------------------------------------------------------------------
Marc Haber | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany | lose things." Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature | How to make an American Quilt | Fax: *49 621 72739835