File: waitlib2.c

package info (click to toggle)
courier 0.60.0-2
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 52,288 kB
  • ctags: 12,677
  • sloc: ansic: 165,348; cpp: 24,820; sh: 16,410; perl: 6,839; makefile: 3,621; yacc: 289; sed: 16
file content (115 lines) | stat: -rw-r--r-- 2,018 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
** Copyright 2000-2006 Double Precision, Inc.
** See COPYING for distribution information.
*/

#include	"config.h"
#include	"waitlib.h"
#include	<stdlib.h>
#include	<sys/types.h>
#include	<string.h>
#include	<signal.h>
#if	HAVE_UNISTD_H
#include	<unistd.h>
#endif

static const char rcsid[]="$Id: waitlib2.c,v 1.2 2006/05/28 15:29:52 mrsam Exp $";

static pid_t *static_pid_buf=0;

static void start_reaper(pid_t pid, int exit_stat)
{
}

static RETSIGTYPE start_reap(int signum)
{
	wait_reap(start_reaper, start_reap);

#if	RETSIGTYPE != void
	return (0);
#endif
}

void wait_forchild( void (*)(pid_t, int), /* Reaper */
        RETSIGTYPE (*)(int));   /* Signal handler stub */

int wait_startchildren(unsigned nchildren, pid_t **pidptr)
{
int	pipefd[2];
pid_t	p;
unsigned i;

	if (!pidptr)
	{
		if (static_pid_buf)	free(static_pid_buf);
		static_pid_buf=0;
		pidptr= &static_pid_buf;
	}

	if (*pidptr == 0 && (*pidptr=malloc(nchildren * sizeof(pid_t))) == 0)
		return (-1);

	if (pipe(pipefd) < 0)	return (-1);

	signal(SIGCHLD, start_reap);
	wait_block();
	for (i=0; i<nchildren; i++)
	{
		p=fork();
		if (p < 0)
		{
			while (i)
			{
				kill( (*pidptr)[--i], SIGKILL);
				wait_forchild(start_reaper, start_reap);
			}
			close(pipefd[0]);
			close(pipefd[1]);
			wait_clear(start_reap);
			signal(SIGCHLD, SIG_DFL);
			return (-1);
		}

		if (p == 0)
		{
		char	buf;

			wait_restore();
			close(pipefd[1]);
			if (read(pipefd[0], &buf, 1) != 1)
				exit(1);
			close(pipefd[0]);
			return (1);
		}

		(*pidptr)[i]=p;
	}
	wait_restore();
	close(pipefd[0]);
	for (i=0; i<nchildren; i++)
		if (write(pipefd[1], "", 1) < 0)
			; /* Shut gcc up */
	close(pipefd[1]);
	return (0);
}

int wait_reforkchild(unsigned nchildren, pid_t *pidptr, pid_t pid)
{
unsigned i;

	for (i=0; i<nchildren; i++)
		if (pidptr[i] == pid)	break;

	if (i >= nchildren)	return (0);

	switch ((pidptr[i]=fork()))	{
	case 0:
		wait_restore();	/* Just in case */
		return (1);
	case -1:
		return (-1);
	default:
		break;
	}
	return (0);
}