#include <err.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>

#define N 10
static size_t n[N];

void *
thr_func(void *arg)
{
	char buf[100];
	int t = *(int *)arg;
	int status;
	pid_t pid;

	for (int i = 0;;) {
		switch (vfork()) {
		case -1:
			write(STDERR_FILENO, buf,
			    snprintf(buf, sizeof(buf), "vfork %d\n", t));
			_exit(1);
		case 0:
			/* child */
			execl("/bin/sleep", "sleep", "1", NULL);
			write(STDERR_FILENO, buf, 
			    snprintf(buf, sizeof(buf), "execl %d\n", t));
		default:
			pid = waitpid(-1, &status, 0);
			n[t]++;
			/* parent */
			write(STDERR_FILENO, buf,
			    snprintf(buf, sizeof(buf), "silent %d %d\n",
			    pid, t));
			break;
		}
	}
}

static void
out(int s)
{
	for (size_t i = 0; i < N; i++)
		printf("%zu %zu\n", i, n[i]);
	exit(s);
}

int
main(void)
{
	pthread_t thr;

	signal(SIGINT, out);
	/* fork 10 threads looping and printing */
	for (int t = 0; t < N; t++) {
		errno = pthread_create(&thr, NULL, thr_func, &t);
		if (errno)
			err(1, "pthread_create failed");
	}
	pthread_join(thr, NULL);

	return 0;
}