[comp.unix.programmer] possible race condition?

coleman@sundae10.DAB.GE.COM (Richard Coleman) (05/09/91)

I've been reading the book "Unix Network Programming" by
Richard Stevens.  On page 80 he is discussing a code fragment
having to do with a daemon skeleton for SystemV.

  if (fork() != 0)
     exit(0);              /* parent process exits */
  setpgrp();               /* change process group and lose control tty */
  signal(SIGHUP,SIG_IGN);
  if (fork() != 0)
    exit(0);               /* first child process exits */
  /* second child process continues as daemon */


Now my questions is this : when the parent process exits, it sends the
signal SIGHUP to all processes in its process group.  Is it possible for
this signal to reach the first child process before it executes setpgrp()
and changes its process group?  Am I missing something here?
-- 
Richard Coleman
GE Aerospace
Simulation & Control Systems Dept.
coleman@sunny.dab.ge.com

ronald@robobar.co.uk (Ronald S H Khoo) (05/10/91)

coleman@sunny.dab.ge.com (Richard Coleman) writes:

> 
>   if (fork() != 0)
>      exit(0);              /* parent process exits */
>   setpgrp();               /* change process group and lose control tty */
>   signal(SIGHUP,SIG_IGN);
 
> Now my questions is this : when the parent process exits, it sends the
> signal SIGHUP to all processes in its process group.  Is it possible for
> this signal to reach the first child process before it executes setpgrp()
> and changes its process group?  Am I missing something here?

Part of the System V interface definition apparently guarantees the
child to execute before the parent, I hear -- I'd like chapter and
verse from someone who has a copy, if that's not too much trouble.

Anyway, there are some System V variants, like the current 386 Xenix
which runs processes the other way round, where the hangup is
just about guaranteed to hit the child before the setpgrp.
So, in principle, yes, you're right, but the code works correctly
on "real" System V.
-- 
Ronald Khoo <ronald@robobar.co.uk> +44 81 991 1142 (O) +44 71 229 7741 (H)

dkeisen@leland.Stanford.EDU (Dave Eisen) (05/10/91)

In article <1991May9.144935.20078@ge-dab.GE.COM> coleman@sunny.dab.ge.com (Richard Coleman) writes:
>
>
>  if (fork() != 0)
>     exit(0);              /* parent process exits */
>  setpgrp();               /* change process group and lose control tty */
>  signal(SIGHUP,SIG_IGN);

>Now my questions is this : when the parent process exits, it sends the
>signal SIGHUP to all processes in its process group.  Is it possible for

This only happens if the parent process is a process group leader which 
won't ordinarily be the case. But, daemons should be paranoid, and
besides, this problem is easy to fix --- just move the signal call
above the first fork and the SIGHUP that might be generated when the
parent dies is safely ignored in the child.



-- 
Dave Eisen                           dkeisen@leland.Stanford.EDU
1101 San Antonio Raod, Suite 102     (Gang-of-Four is being taken off the net)
Mountain View, CA 94043
(415) 967-5644

berg@marvin.e17.physik.tu-muenchen.de (Stephen R. van den Berg) (05/10/91)

Richard Coleman writes:
>  if (fork() != 0)
>     exit(0);              /* parent process exits */
>  setpgrp();               /* change process group and lose control tty */
>  signal(SIGHUP,SIG_IGN);
>  if (fork() != 0)
>    exit(0);               /* first child process exits */
>  /* second child process continues as daemon */

Why not do it this way, and save a LOT of trouble:

  signal(SIGHUP,SIG_IGN);
  if (fork() != 0)
     exit(0);              /* parent process exits */
  setpgrp();               /* change process group and lose control tty */
  if (fork() != 0)
    exit(0);               /* first child process exits */
  /* second child process continues as daemon */

Just my $0.02
--
Sincerely,                 berg@marvin.e17.physik.tu-muenchen.de
           Stephen R. van den Berg.
"I code it in 5 min, optimize it in 90 min, because it's so well optimized:
it runs in only 5 min.  Actually, most of the time I optimize programs."

alex@am.sublink.org (Alex Martelli) (05/11/91)

ronald@robobar.co.uk (Ronald S H Khoo) writes:
	...
:Part of the System V interface definition apparently guarantees the
:child to execute before the parent, I hear -- I'd like chapter and
:verse from someone who has a copy, if that's not too much trouble.
Does not look that way to me - SVID 2, p.86, under fork(ba_os), says
"both processes will run as system resources become available".

:So, in principle, yes, you're right, but the code works correctly
:on "real" System V.
It's possibly that way depending on how it is *implemented*, but it
does not seem to me that you get any guarantee from the interface
*specification*.
-- 
Alex Martelli - (home snailmail:) v. Barontini 27, 40138 Bologna, ITALIA
Email: (work:) martelli@cadlab.sublink.org, (home:) alex@am.sublink.org
Phone: (work:) ++39 (51) 371099, (home:) ++39 (51) 250434; 
Fax: ++39 (51) 366964 (work only), Fidonet: 332/401.3 (home only).

md@sco.COM (Michael Davidson) (05/21/91)

alex@am.sublink.org (Alex Martelli) writes:

>ronald@robobar.co.uk (Ronald S H Khoo) writes:
>	...
>:Part of the System V interface definition apparently guarantees the
>:child to execute before the parent, I hear -- I'd like chapter and
>:verse from someone who has a copy, if that's not too much trouble.
>Does not look that way to me - SVID 2, p.86, under fork(ba_os), says
>"both processes will run as system resources become available".

>:So, in principle, yes, you're right, but the code works correctly
>:on "real" System V.
>It's possibly that way depending on how it is *implemented*, but it
>does not seem to me that you get any guarantee from the interface
>*specification*.

The SVID does *not* specify whether the child process or the
parent process must execute first. Unfortunately many of the
SVVS tests are rather badly written and have unpleasant timing
windows in them - something you find out as soon as you try to
run SVVS on a multiprocessor system where it is quite possible
that the parent and child will run simultaneously on different
processors.