How to set up signal handling in UNIX to kill a daemon process and children

How to set up signal handling in UNIX to kill a daemon process and children

Post by Keld Wesenberg Lyngs » Wed, 30 Jun 1999 04:00:00



Hello,

I am a  newbie with signal handling i unix, so hopefully someone is able

to help with my problem.

I have to create a daemon process, which then again start one or more
child process. All of these
processes are started within the same processgroup.

Graphical it look like something like this:

                                daemon - process
                                    /     |              \
                        Child 1   child 2 ....  child N processes.

My problem is that I will like to setup the signal handling so that when

the daemon process
receives a SIGKILL signal - then all its children are also killed.

How do I setup signal handling within unix in order to obtain this ?

Or do anyone know a web-site where i can get a hold of some information
about signal handling ?

Below I have attached a small sample program which shows the way the
daemon process is
started.

Thanks in advance.

Best regards,
Keld

/*========================================================================*\

                         Includes
\*========================================================================*/

/* Init a daemon process */

#include <sys/file.h>
#include <sys/param.h>
#include <sys/wait.h>
#include <syslog.h>
#include <sys/ioctl.h>

#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#include <unistd.h>

void DaemonStart(int ignsigcld)
{
 int childpid,fd,i;
 pid_t   group;

 if (getpid() == -1)
  goto out;       /*DoTheStuff();*/

 if ((childpid = fork()) < 0) {
  i = errno;
  fprintf(stderr,"Can't fork first child errno=%d\n",i);
 } else
  if (childpid > 0)
   exit(0);  /* parent */
 if (setpgrp() == -1) {
  i = errno;
  fprintf(stderr,"Can't change process group(2) errno=%d\n",i);
 }

 signal(SIGHUP, SIG_IGN);

 if ((childpid = fork()) < 0) {
  i = errno;
  fprintf(stderr,"Can't fork second child errno=%d\n",i);
 } else
  if (childpid > 0)
   exit(0);  /* first child */

 /* second child */

out:
 /* Close any file descriptors */
 for (fd=0; fd < NOFILE; fd++)
  close(fd);

 errno = 0;

 chdir("/");

 umask(0);

 if (ignsigcld)
 {
  signal(SIGCLD, SIG_IGN); /* System V */
 }

Quote:}

/*------------------------------------------------------------------------*\

                         spawnClient
\*------------------------------------------------------------------------*/

int spawnClient()
{
 int returnValue = 1;
 char command[2048];
 pid_t pid;
 extern char ** environ;

 sprintf(command,"%s/testclt", getenv("TESTDIR"));

    if ((pid = fork()) < 0) {
  /* failed */
  fprintf(stderr,"Cannot fork to start client\n");
  returnValue = 0;
    }
 else if (pid == 0) {
  /* child process */
  const char * newArgv[2];

  newArgv[0] = command;
  newArgv[1] = NULL;

  execve(command, (char * const *)newArgv, environ);

  /* we failed, so make it fail badly... */
  _exit(127);
 }
 else {
  /* parent process, pid is a real child process id */
  fprintf(stderr, "Client (pid %d) started\n", pid);
 }

   return returnValue;

Quote:}

/*------------------------------------------------------------------------*\

                         main_UNIX
\*------------------------------------------------------------------------*/

main(int argc, char * argv[])
{
      pid_t pid;
      int i;
      FILE *f;

      DaemonStart(1);

      if (f == NULL) {
  /* We have a problem now.... */
  /* Just exit with 9 */
  exit(9);
      }
      dup(fileno(f)); /* stdout */
      dup(fileno(f)); /* stderr */

      if (spawnClient())
          fprintf(stderr,"Client spawned\n");
      else
          fprintf(stderr,"Client WASN'T spawned\n");

      for (i=1;0 == 0;i=0)
         if (i == 1)
   fprintf(stderr,"daemon testing pid is %ld og pgrp is %ld \n",
getpid(),getpgrp());

      return 0;

Quote:}

--
----------------------------------------------------------------------------

Keld Wesenberg Lyngs?
Pine Tree                                 Tel:   +45 75724477
Damhaven 5D                               Fax:   +45 75725208

Denmark                                   WWW:   http:\\www.pine.dk
----------------------------------------------------------------------------

 
 
 

How to set up signal handling in UNIX to kill a daemon process and children

Post by Ronal » Thu, 01 Jul 1999 04:00:00


On Tue, 29 Jun 1999 12:22:32 +0200, Keld Wesenberg Lyngs? wrote

Quote:

> Hello,

> I am a  newbie with signal handling i unix, so hopefully someone is able

> to help with my problem.

> I have to create a daemon process, which then again start one or more child
snip
> My problem is that I will like to setup the signal handling so that when

> the daemon process receives a SIGKILL signal - then all its children are
> also killed.

You can catch SIGCHLD in the daemon. When you received the signal you could send a SIGTERM to your children using kill().
--
Ronald - certified Oracle DBA http://home.wxs.nl/~ronr/professional.html
       - unix/sa              http://www.tresco.nl/dcl.html
       - Middleware programmer/


 
 
 

How to set up signal handling in UNIX to kill a daemon process and children

Post by John D. Hicki » Thu, 01 Jul 1999 04:00:00



> On Tue, 29 Jun 1999 12:22:32 +0200, Keld Wesenberg Lyngs? wrote

> > I have to create a daemon process, which then again start one or more child
> snip
> > My problem is that I will like to setup the signal handling so that when

> > the daemon process receives a SIGKILL signal - then all its children are
> > also killed.

> You can catch SIGCHLD in the daemon. When you received the signal you could send a SIGTERM to your children using kill().

The problem with this is that the daemon won't be around to catch
SIGCHLD in the case where it is sent a SIGKILL.

On the assumption that the child processes have some sort of event loop
or can dedicate a thread or _background task_ to polling the parent
process id, you can cope:

        if ( getppid() == 1 ) goodBye(); // parent died; child was inherited by
init

 
 
 

How to set up signal handling in UNIX to kill a daemon process and children

Post by Karsten Span » Fri, 02 Jul 1999 04:00:00



> I have to create a daemon process, which then again start one or more
> child process. All of these
> processes are started within the same processgroup.
> My problem is that I will like to setup the signal handling so that when

> the daemon process
> receives a SIGKILL signal - then all its children are also killed.

If you know the process group ID of the daemon, you can send the signal
to all the processes using kill(-pgid,SIGTERM)

If you don't know the process grouip ID, you may obtain it from the daemon
process ID, using getpgid(pid). This call is in the Unix 98 specification,
on older systems, you may have to use getpgrp2(pid) instead.

The other solution is to keep track of the PIDs of the children, recording
them on fork(), deleting them again in a SIGCHLD handler. Then in a SIGTERM
handler, kill() them all. Alternatively, do a kill(-getpgrp(),SIGTERM) in the
signal handler, but remember to ignore SIGTERM first.

Note that you cannot use SIGKILL for this, SIGKILL kills the process without
calling any signal handlers. SIGKILL should only be used as a last resort,
when a process does not exit on SIGTERM.

Karsten
--
Karsten Spang
Senior Software Developer, Ph.D.
Belle Systems

Tel.: +45 59 44 25 00

 
 
 

How to set up signal handling in UNIX to kill a daemon process and children

Post by Ronal » Fri, 02 Jul 1999 04:00:00


On Thu, 1 Jul 1999 4:02:38 +0200, John D. Hickin wrote


>> On Tue, 29 Jun 1999 12:22:32 +0200, Keld Wesenberg Lyngs? wrote (in

>>> I have to create a daemon process, which then again start one or more
snip
>>> My problem is that I will like to setup the signal handling so that when

>>> the daemon process receives a SIGKILL signal - then all its children are
>>> also killed.

>> You can catch SIGCHLD in the daemon. When you received the signal you
>> could send a SIGTERM to your children using kill().

> The problem with this is that the daemon won't be around to catch SIGCHLD in
> the case where it is sent a SIGKILL.
snip
>    if ( getppid() == 1 ) goodBye(); // parent died; child was inherited by
> init

Oops, did not notice the SIGKILL. Are the children reading from a pipe from the
parent ? In that case they should read EOF == parent gone if I am not mistaken.
--
Ronald - certified Oracle DBA http://home.wxs.nl/~ronr/professional.html
       - unix/sa              http://www.tresco.nl/dcl.html
       - Middleware programmer/

 
 
 

1. how to kill a child process that runs other children processes

here's my problem:  i am spawning a child process using spawnv in c,
launching an executable and passing some arguments to it.  then, in another
thread i wait for a certain amount of time and if the first thread reaches a
certain threshold, i kill the spawned child process.  this works total okay
but because the executable that i run in the spawned process launches some
other programs on its own, they continue to run regardless of the fact that
i killed their parent process.  to make things clear:  i spawn process A.
process A is an executable and i don't have its source.  process A launches
a bunch of other processes B, C and D ( they are also separate executables
w/o source code ).  when i kill process A, it dies but processes B, C and D
continue to run.

so, the question is:  is there a way to kill the children of a child process
( i.e. grandchildren ) without actually knowing their pids explicitly, i.e.
can i say to a process "die and kill all your children, too" *without*
modifying the code for that child process?

thanx in advance...

2. Printing problems: ghostview and printcap entries

3. How can kill all child processes without killing parent process ?

4. Linux on s/390 is cute

5. kill child and its all grad child processes?

6. Mosaic 2.2 problem

7. UNIX signal handling and the kill system call

8. How to make mail batch uucp requests? (on A/UX 2.0)

9. killing a shell script is not killing child processes

10. Can a process kill its child if it's killed -9

11. Parent process also terminating after killing child process in SIGINT