summaryrefslogtreecommitdiffstats
path: root/waitlib/testwait.c
blob: a720e49a678e0926204b03a88e92e54ac1f7dfe2 (plain)
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
/*
** Copyright 1998 - 2020 Double Precision, Inc.
** See COPYING for distribution information.
*/

#include	"waitlib.h"
#if	HAVE_UNISTD_H
#include	<unistd.h>
#endif
#include	<stdio.h>
#include	<stdlib.h>
#include	<signal.h>
#include	<pthread.h>

/* Stress test waitlib.c */

#define	NUMCHILDREN	100		/* Start 100 child processes */
#define	INITCHILDREN	10		/* Start with these many child procs */

static unsigned started;
static int reap_pipefd[2];

static void reap_child(pid_t p, int dummy)
{
	if (write(reap_pipefd[1], "", 1) < 0)
		; /* shut up gcc */
}

static RETSIGTYPE sighandler(int sig)
{
	wait_reap(&reap_child, &sighandler);
#if	RETSIGTYPE != void
	return (0);
#endif
}

static pid_t start_child()
{
pid_t	p;

	wait_block();
	while ((p=fork()) == (pid_t)-1)
	{
		perror("fork");
		sleep(3);
	}
	++started;
	if (p == 0)
	{
		wait_restore();
	}
	else
		wait_clear(&sighandler);
	return (p);
}

extern void foobar();

int	main()
{
int	pipefd[2];
int	pipefd2[2];
char	c;
unsigned finished=0;

	if (pipe(reap_pipefd) || pipe(pipefd) || pipe(pipefd2))
	{
		perror("pipe");
		exit(1);
	}

	signal(SIGCHLD, sighandler);

	started=0;
	while (started < INITCHILDREN)
	{
		if (start_child() == 0)
		{
			close(pipefd2[0]);
			close(pipefd2[1]);
			close(pipefd[1]);
			if (read(pipefd[0], &c, 1) != 1)
				; /* Shut gcc up */
			close(pipefd[0]);
			_exit(0);
		}
	}
	close(pipefd2[1]);
	close(pipefd[0]);
	if (read(pipefd2[0], &c, 1) != 1)
		; /* Shut gcc up */
	close(pipefd[1]);
	close(pipefd2[0]);
	while (started < NUMCHILDREN)
		if (start_child() == 0)
			_exit(0);

	alarm(30);
	while (finished < started)
	{
		char c;
		int n=read(reap_pipefd[0], &c, 1);

		if (n <= 0)
		{
			fprintf(stderr, "pipe error\n");
			exit(1);
		}
		++finished;
	}
	exit(0);
}