From: David Schwartz on
On Dec 3, 5:56 am, Ralf Fassel <ralf...(a)gmx.de> wrote:

> On my Opensuse 11.1, getppid() returns 1 (== init) when the parent has
> exited, which could be used as an indicator "parent has gone".  The
> manpage says nothing about that scenario so I don't know how portable
> that would be.

You can call 'getppid' on startup and check if it changes or is
equivalent to one. I guess this creates a narrow window in which your
parent could die, you could get reparented to something other than
init, and then you call getppid the first time.
From: junky_fellow on
On Dec 3, 8:43 pm, David Schwartz <dav...(a)webmaster.com> wrote:
> On Dec 3, 5:56 am, Ralf Fassel <ralf...(a)gmx.de> wrote:
>
> > On my Opensuse 11.1, getppid() returns 1 (== init) when the parent has
> > exited, which could be used as an indicator "parent has gone".  The
> > manpage says nothing about that scenario so I don't know how portable
> > that would be.
>
> You can call 'getppid' on startup and check if it changes or is
> equivalent to one. I guess this creates a narrow window in which your
> parent could die, you could get reparented to something other than
> init, and then you call getppid the first time.

Guys, thanks a lot for your suggestions.
However, all the solutions suggested require regular polling, which I
want to avoid. Is there any way, where I can do this without polling?
Isn't this a very common requirement ?


From: Lew Pitcher on
On December 3, 2009 04:42, in comp.unix.programmer, junky_fellow(a)yahoo.co.in
(junky_fellow(a)yahoo.co.in) wrote:

> Guys,
>
> I am writing an application where the parent (daemon) forks few
> child processes.
> My requirement is that when the parent process exits/killed/crashed,
> all its child processes should also exit. Can someone suggest some way
> of doing it.

Make the parent process a "process group leader" before it forks off it's
children. Signals delivered to the "process group leader" are also
delivered to all of it's children.

A process that does not self-terminate (i.e. call exit() or equivalent)
terminates by signal. A "crash" condition causes the kernel to deliver one
of a select few signals to the process (SIGSEGV, for instance). If the
process is "killed" by another process, a signal is delivered to the
process.

The only real problem (in using a process group leader here) is that
self-termination usually does not involve signals, so there is no signal to
deliver to the child processes. However, since you have control over the
design and development of the parent process, you can incorporate a
signal-delivery-mechanism into your daemon's self-termination. Just before
calling exit() (or what ever you /do/ within the daemon to terminate it's
process), send a signal to all the children.

On the child process side, set up a signal handler that will terminate the
process cleanly when the appropriate signal is received. Include handling
for all the usual "kill" and "crash" signals, as well as for the signal
that you designate the parent to send (likely SIGHUP or SIGQUIT).

> Problematic scenario is the one where the parent crashed or killed
> (SIGKILL) and desn't get any chance for cleanup.

Signals delivered to the process group take care of this problem nicely.

> thanks for any help..

HTH
--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
Me: http://pitcher.digitalfreehold.ca/ | Just Linux: http://justlinux.ca/
---------- Slackware - Because I know what I'm doing. ------


From: Eric Sosman on
junky_fellow(a)yahoo.co.in wrote:
> On Dec 3, 8:43 pm, David Schwartz <dav...(a)webmaster.com> wrote:
>> On Dec 3, 5:56 am, Ralf Fassel <ralf...(a)gmx.de> wrote:
>>
>>> On my Opensuse 11.1, getppid() returns 1 (== init) when the parent has
>>> exited, which could be used as an indicator "parent has gone". The
>>> manpage says nothing about that scenario so I don't know how portable
>>> that would be.
>> You can call 'getppid' on startup and check if it changes or is
>> equivalent to one. I guess this creates a narrow window in which your
>> parent could die, you could get reparented to something other than
>> init, and then you call getppid the first time.
>
> Guys, thanks a lot for your suggestions.
> However, all the solutions suggested require regular polling, which I
> want to avoid. Is there any way, where I can do this without polling?

Using Rainer Weikusat's suggestion of a pipe written ("not")
by the parent and read by the children, you could dedicate a
thread in each child process to sit in a (blocking) read on the
pipe and shut things down when the read returns end-of-input.

If you don't like the idea of multi-threading, you could
write a single-threaded helper program that would be the child
of the parent, and would launch the "payload" program as the
parent's grandchild. After fork, the helper would then block
reading the pipe, and kill the grandchild when the read completes.

> Isn't this a very common requirement ?

Hard to say, but the available evidence suggests "No."

--
Eric Sosman
esosman(a)ieee-dot-org.invalid
From: Rainer Weikusat on
Lew Pitcher <lpitcher(a)teksavvy.com> writes:
> On December 3, 2009 04:42, in comp.unix.programmer, junky_fellow(a)yahoo.co.in
> (junky_fellow(a)yahoo.co.in) wrote:
>
>> Guys,
>>
>> I am writing an application where the parent (daemon) forks few
>> child processes.
>> My requirement is that when the parent process exits/killed/crashed,
>> all its child processes should also exit. Can someone suggest some way
>> of doing it.
>
> Make the parent process a "process group leader" before it forks off it's
> children. Signals delivered to the "process group leader" are also
> delivered to all of it's children.

This is wrong: Signals which are generated by the terminal driver in
response to user input (SIGINT, SIGQUIT and SIGTSTP) are sent to all processes
in the current foreground process group associated with a particular
terminal. This can be verified by running the program included below
in a shell with job-control support. Such a shell will put each 'new
job' into a process group of its own, so that SIGTSTP stops
'everything', which means the original process will be a process group
leader. After the sleep it does an invalid memory access and the
kernel terminates it with SIGSEGV. The the pausing children remain
running.

-------
#include <stdio.h>
#include <unistd.h>

int main(void)
{
int rc;

if (fork() == 0) pause();
if (fork() == 0) pause();

fprintf(stderr, "%d\n", getpid() == getpgrp());
sleep(1);

*(int *)-1 = 3;
return 0;
}