1185695Sganbold/*-
2185695Sganbold * Copyright (c) 2008 Ganbold Tsagaankhuu
3185695Sganbold * All rights reserved.
4185695Sganbold *
5185695Sganbold * Redistribution and use in source and binary forms, with or without
6185695Sganbold * modification, are permitted provided that the following conditions
7185695Sganbold * are met:
8185695Sganbold * 1. Redistributions of source code must retain the above copyright
9185695Sganbold *    notice, this list of conditions and the following disclaimer
10185695Sganbold *    in this position and unchanged.
11185695Sganbold * 2. Redistributions in binary form must reproduce the above copyright
12185695Sganbold *    notice, this list of conditions and the following disclaimer in the
13185695Sganbold *    documentation and/or other materials provided with the distribution.
14185695Sganbold *
15185695Sganbold * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16185695Sganbold * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17185695Sganbold * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18185695Sganbold * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19185695Sganbold * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20185695Sganbold * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21185695Sganbold * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22185695Sganbold * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23185695Sganbold * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24185695Sganbold * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25185695Sganbold * SUCH DAMAGE.
26185695Sganbold *
27185695Sganbold */
28185695Sganbold
29185695Sganbold#include <sys/cdefs.h>
30185695Sganbold__FBSDID("$FreeBSD: releng/11.0/tools/test/pthread_vfork/pthread_vfork_test.c 246119 2013-01-30 13:14:34Z kib $");
31185695Sganbold
32246119Skib#include <sys/types.h>
33246119Skib#include <sys/wait.h>
34185695Sganbold#include <err.h>
35185695Sganbold#include <pthread.h>
36185695Sganbold#include <signal.h>
37185695Sganbold#include <stdio.h>
38185695Sganbold#include <stdlib.h>
39185695Sganbold#include <string.h>
40185695Sganbold#include <unistd.h>
41185695Sganbold
42185695Sganbold#define NUM_THREADS 100
43185695Sganbold
44246119Skibstatic void *
45246119Skibvfork_test(void *threadid __unused)
46185695Sganbold{
47246119Skib	pid_t pid, wpid;
48246119Skib	int status;
49185695Sganbold
50185695Sganbold	for (;;) {
51185695Sganbold		pid = vfork();
52185695Sganbold		if (pid == 0)
53185695Sganbold			_exit(0);
54185695Sganbold		else if (pid == -1)
55185695Sganbold			err(1, "Failed to vfork");
56246119Skib		else {
57246119Skib			wpid = waitpid(pid, &status, 0);
58246119Skib			if (wpid == -1)
59246119Skib				err(1, "waitpid");
60246119Skib		}
61185695Sganbold	}
62185695Sganbold	return (NULL);
63185695Sganbold}
64185695Sganbold
65246119Skibstatic void
66246119Skibsighandler(int signo __unused)
67246119Skib{
68246119Skib}
69246119Skib
70185695Sganbold/*
71185695Sganbold * This program invokes multiple threads and each thread calls
72185695Sganbold * vfork() system call.
73185695Sganbold */
74185695Sganboldint
75185695Sganboldmain(void)
76185695Sganbold{
77185695Sganbold	pthread_t threads[NUM_THREADS];
78185695Sganbold	struct sigaction reapchildren;
79246119Skib	sigset_t sigchld_mask;
80185695Sganbold	int rc, t;
81185695Sganbold
82185695Sganbold	memset(&reapchildren, 0, sizeof(reapchildren));
83246119Skib	reapchildren.sa_handler = sighandler;
84185695Sganbold	if (sigaction(SIGCHLD, &reapchildren, NULL) == -1)
85185695Sganbold		err(1, "Could not sigaction(SIGCHLD)");
86185695Sganbold
87246119Skib	sigemptyset(&sigchld_mask);
88246119Skib	sigaddset(&sigchld_mask, SIGCHLD);
89246119Skib	if (sigprocmask(SIG_BLOCK, &sigchld_mask, NULL) == -1)
90246119Skib		err(1, "sigprocmask");
91246119Skib
92185695Sganbold	for (t = 0; t < NUM_THREADS; t++) {
93246119Skib		rc = pthread_create(&threads[t], NULL, vfork_test, &t);
94185695Sganbold		if (rc)
95185695Sganbold			errc(1, rc, "pthread_create");
96185695Sganbold	}
97246119Skib	pause();
98185695Sganbold	return (0);
99185695Sganbold}
100