Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Jul 1996 22:36:01 +0000 ()
From:      James Raynard <fqueries@jraynard.demon.co.uk>
To:        Gordon Beck <gordon@galisant.demon.co.uk>
Cc:        questions@freebsd.org
Subject:   Re: killing child processes
Message-ID:  <199607282236.WAA03556@jraynard.demon.co.uk>
In-Reply-To: <838578160snx@galisant.demon.co.uk> from "Gordon Beck" at Jul 28, 96 11:22:40 am

next in thread | previous in thread | raw e-mail | index | archive | help
> 
> 
> I have a monitor daemon which forks and runs an application.
> 
> 
> If the application dies then the daemon get to know about it.
> However, if the daemon dies or is killed, then the child continues to run.
 
Yep, this is normal behaviour - the child becomes a child of init
instead of its original parent.

> I had expected the child to get a SIGHUP, which it is not blocking.
> However, I think that SIGHUP is only generated if the daemon is
> a process group leader and had a control terminal whose TGRP matched
> the process group (?).
>  
> 
> If a daemon process issues setpgrp then it can on longer acquire a control
> terminal(?), which is cache 22.
 
>From what I understand of it, this sounds like you're expecting the 
SVR3 behaviour, where a "process group" corresponds loosely to all 
the commands started in a login session. FreeBSD follows POSIX, where 
a "process group" corresponds to a job and the login session is 
referred to as a "session" (the difference is necessary to add 
support for BSD-style job control).
 
Under FreeBSD, logging in creates a new session, whose controlling 
terminal is whichever one you logged in to.  Every time you type a
command at the shell's command prompt, it forms a new process group:-

$ ls			# A process group
$ prog1 | prog2		# Another process group
$ prog3 | prog4 &	# A process group in the background

Each process group has a process group ID which is equal to the PID
of the first process in the job.  They will also have a session ID,
which is the same for all processes in a login session unless a 
program calls setsid() to detach itself from the controlling terminal.
Such a process will start a new session, with its own session ID, and
will be the session leader.  It can acquire a new controlling terminal
simply by opening one (either a real terminal or a pseudo-terminal for
a network connection).

If the controlling terminal is lost for some reason (eg user logging out
or a dropped connection on a dialup link), SIGHUP is sent only to the 
session leader for that terminal, unlike SVR3 where it was sent to every 
process attached to the terminal.  Typically, this will be the user's 
login shell or something like a PPP process which should know how
to do the right thing.

setpgrp() has been superseded on FreeBSD by POSIX's setpgid(), which 
is mainly used by shells to implement job control.

> Anyone have clues/pointers/source code for a general or specific solution
> to this problem

The only circumstances I know where a child is signalled by a parent
terminating is if the child is stopped; in this case, it receives a
SIGHUP followed by a SIGCONT.  to verify this, change the 'if (0)'
to 'if(1)' in the example below (loosely adapted from "Advanced
Programming in the Unix Environment" by Stevens).  If the child is
not stopped, the best way to inform the child of the parent's 
impending demise is probably for the parent to send it a signal.

#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

static void sig_hup(int);

int main() {
	pid_t pid;

	if ((pid = fork()) < 0)
		perror("fork");
	else if (pid > 0) {	/* parent */
		setsid();
		sleep(10);
		exit(0);
	} else {		/* child */
		signal(SIGHUP, sig_hup);
		if (0)
			kill(getpid(), SIGTSTP);	/* stop ourselves */
		else
			sleep(20);
		exit(0);
	}
}

void sig_hup(int signo) {
	printf("SIGHUP received, pid = %ld\n", (unsigned long)getpid());
}




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199607282236.WAA03556>