childs.c
author viric@llimona
Tue, 30 May 2006 12:34:25 +0200
changeset 57 de776a4548da
parent 51 a01abd65856a
permissions -rw-r--r--
Added the check for a pid file (syslog.pid by default).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
49
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
     1
#include <sys/types.h>
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
     2
#include <unistd.h>
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
     3
#include <errno.h>
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
     4
#include <signal.h>
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
     5
#include <string.h>
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
     6
#include <stdio.h>
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
     7
#include <sys/wait.h> // Per wait
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
     8
#include <assert.h> // Pels assert
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
     9
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    10
#include "syslog.h"
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    11
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    12
/* Variables */
50
6958ce45aa83 Changing to static an internal module variable.
viric@llimona
parents: 49
diff changeset
    13
static int childs_alive = 0;
49
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    14
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    15
static int child[MAX_CHILDS];
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    16
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    17
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    18
/* Prototypes */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    19
static void remove_child(const int pid);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    20
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    21
/* Code */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    22
void term_childs()
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    23
{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    24
	int res;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    25
	int i;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    26
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    27
	sigset_t tmp, normal;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    28
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    29
	/* block the child signals */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    30
	sigemptyset(&tmp);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    31
	sigaddset(&tmp, SIGCHLD);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    32
	sigprocmask(SIG_BLOCK, &tmp, &normal);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    33
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    34
	/* Send SIGTERM */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    35
	for(i=0;i<childs_alive;i++)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    36
	{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    37
		res = kill(child[i], SIGTERM);
51
a01abd65856a The tcp server listen() started working. By now the connections are closed at once.
viric@llimona
parents: 50
diff changeset
    38
		fprintf(stderr, "Sent SIGTERM to %i\n", child[i]);
49
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    39
		/* Accepting the res == -1 && errno == ESRCH saves us
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    40
		 * from the race condition possible kill error */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    41
		if (res == -1)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    42
			assert( errno == ESRCH );
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    43
	}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    44
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    45
	/* restore the mask */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    46
	sigprocmask(SIG_SETMASK, &normal, NULL);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    47
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    48
}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    49
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    50
void wait_childs_die()
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    51
{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    52
	/* Wait for the end */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    53
	while(childs_alive > 0)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    54
	{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    55
		sleep(1);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    56
	}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    57
}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    58
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    59
void child_handler(int parameter)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    60
{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    61
	pid_t pid;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    62
	int status;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    63
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    64
	do
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    65
	{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    66
		pid = waitpid(-1, &status, WNOHANG);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    67
		if (pid == -1)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    68
		{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    69
			if(errno == ECHILD)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    70
			{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    71
				/* We don't have more childs! */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    72
				fprintf(stderr, "We don't have more childs.\n");
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    73
				childs_alive = 0;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    74
				break;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    75
			} else
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    76
			{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    77
				fprintf(stderr, "waitpid failed. %s\n",
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    78
					strerror(errno));
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    79
				break;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    80
			}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    81
		}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    82
		/* Debug */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    83
		if (pid > 0)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    84
		{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    85
			fprintf(stderr, "Child %i died: 0x%08x\n",
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    86
				pid, status);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    87
			remove_child(pid);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    88
		}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    89
	} while(pid > 0);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    90
}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    91
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    92
int child_fork()
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    93
{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    94
	int pid;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    95
	sigset_t tmp, normal;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    96
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    97
	/* block the child signals */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    98
	sigemptyset(&tmp);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
    99
	sigaddset(&tmp, SIGCHLD);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   100
	sigprocmask(SIG_BLOCK, &tmp, &normal);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   101
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   102
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   103
	if (childs_alive < MAX_CHILDS)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   104
	{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   105
		pid = fork();
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   106
	}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   107
	else
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   108
	{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   109
		pid = -1;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   110
	}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   111
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   112
	if (pid > 0)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   113
	{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   114
		/* Parent */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   115
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   116
		/* MUTEX-ed actions with the SIGCHLD handler */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   117
		child[childs_alive++] = pid;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   118
	}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   119
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   120
	/* restore the mask */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   121
	sigprocmask(SIG_SETMASK, &normal, NULL);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   122
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   123
	return pid;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   124
}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   125
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   126
/* This will be called only from the SIGCHLD handler */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   127
static void remove_child(const int pid)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   128
{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   129
	int i;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   130
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   131
	/* We update the child status */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   132
	for(i=0;i<childs_alive;i++)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   133
	{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   134
		if(child[i] == pid)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   135
			break;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   136
	}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   137
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   138
	for(i = i; i < (childs_alive-1); i++)
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   139
	{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   140
		child[i] = child[i+1];
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   141
	}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   142
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   143
	childs_alive--;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   144
}
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   145
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   146
int get_childs_alive()
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   147
{
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   148
	int num;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   149
	sigset_t tmp, normal;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   150
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   151
	/* block the child signals */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   152
	sigemptyset(&tmp);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   153
	sigaddset(&tmp, SIGCHLD);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   154
	sigprocmask(SIG_BLOCK, &tmp, &normal);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   155
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   156
	num = childs_alive;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   157
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   158
	/* restore the mask */
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   159
	sigprocmask(SIG_SETMASK, &normal, NULL);
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   160
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   161
	return num;
ced312cc1eaa Separated the child handling in another module.
viric@llimona
parents:
diff changeset
   162
}