15c52a798SGanbold Tsagaankhuu /*-
25c52a798SGanbold Tsagaankhuu * Copyright (c) 2008 Ganbold Tsagaankhuu
35c52a798SGanbold Tsagaankhuu * All rights reserved.
45c52a798SGanbold Tsagaankhuu *
55c52a798SGanbold Tsagaankhuu * Redistribution and use in source and binary forms, with or without
65c52a798SGanbold Tsagaankhuu * modification, are permitted provided that the following conditions
75c52a798SGanbold Tsagaankhuu * are met:
85c52a798SGanbold Tsagaankhuu * 1. Redistributions of source code must retain the above copyright
95c52a798SGanbold Tsagaankhuu * notice, this list of conditions and the following disclaimer
105c52a798SGanbold Tsagaankhuu * in this position and unchanged.
115c52a798SGanbold Tsagaankhuu * 2. Redistributions in binary form must reproduce the above copyright
125c52a798SGanbold Tsagaankhuu * notice, this list of conditions and the following disclaimer in the
135c52a798SGanbold Tsagaankhuu * documentation and/or other materials provided with the distribution.
145c52a798SGanbold Tsagaankhuu *
155c52a798SGanbold Tsagaankhuu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
165c52a798SGanbold Tsagaankhuu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
175c52a798SGanbold Tsagaankhuu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
185c52a798SGanbold Tsagaankhuu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
195c52a798SGanbold Tsagaankhuu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
205c52a798SGanbold Tsagaankhuu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
215c52a798SGanbold Tsagaankhuu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
225c52a798SGanbold Tsagaankhuu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
235c52a798SGanbold Tsagaankhuu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
245c52a798SGanbold Tsagaankhuu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
255c52a798SGanbold Tsagaankhuu * SUCH DAMAGE.
265c52a798SGanbold Tsagaankhuu *
275c52a798SGanbold Tsagaankhuu */
285c52a798SGanbold Tsagaankhuu
29*9005607cSKonstantin Belousov #include <sys/types.h>
30*9005607cSKonstantin Belousov #include <sys/wait.h>
315c52a798SGanbold Tsagaankhuu #include <err.h>
325c52a798SGanbold Tsagaankhuu #include <pthread.h>
335c52a798SGanbold Tsagaankhuu #include <signal.h>
345c52a798SGanbold Tsagaankhuu #include <stdio.h>
355c52a798SGanbold Tsagaankhuu #include <stdlib.h>
365c52a798SGanbold Tsagaankhuu #include <string.h>
375c52a798SGanbold Tsagaankhuu #include <unistd.h>
385c52a798SGanbold Tsagaankhuu
395c52a798SGanbold Tsagaankhuu #define NUM_THREADS 100
405c52a798SGanbold Tsagaankhuu
41*9005607cSKonstantin Belousov static void *
vfork_test(void * threadid __unused)42*9005607cSKonstantin Belousov vfork_test(void *threadid __unused)
435c52a798SGanbold Tsagaankhuu {
44*9005607cSKonstantin Belousov pid_t pid, wpid;
45*9005607cSKonstantin Belousov int status;
465c52a798SGanbold Tsagaankhuu
475c52a798SGanbold Tsagaankhuu for (;;) {
485c52a798SGanbold Tsagaankhuu pid = vfork();
495c52a798SGanbold Tsagaankhuu if (pid == 0)
505c52a798SGanbold Tsagaankhuu _exit(0);
515c52a798SGanbold Tsagaankhuu else if (pid == -1)
525c52a798SGanbold Tsagaankhuu err(1, "Failed to vfork");
53*9005607cSKonstantin Belousov else {
54*9005607cSKonstantin Belousov wpid = waitpid(pid, &status, 0);
55*9005607cSKonstantin Belousov if (wpid == -1)
56*9005607cSKonstantin Belousov err(1, "waitpid");
57*9005607cSKonstantin Belousov }
585c52a798SGanbold Tsagaankhuu }
595c52a798SGanbold Tsagaankhuu return (NULL);
605c52a798SGanbold Tsagaankhuu }
615c52a798SGanbold Tsagaankhuu
62*9005607cSKonstantin Belousov static void
sighandler(int signo __unused)63*9005607cSKonstantin Belousov sighandler(int signo __unused)
64*9005607cSKonstantin Belousov {
65*9005607cSKonstantin Belousov }
66*9005607cSKonstantin Belousov
675c52a798SGanbold Tsagaankhuu /*
685c52a798SGanbold Tsagaankhuu * This program invokes multiple threads and each thread calls
695c52a798SGanbold Tsagaankhuu * vfork() system call.
705c52a798SGanbold Tsagaankhuu */
715c52a798SGanbold Tsagaankhuu int
main(void)725c52a798SGanbold Tsagaankhuu main(void)
735c52a798SGanbold Tsagaankhuu {
745c52a798SGanbold Tsagaankhuu pthread_t threads[NUM_THREADS];
755c52a798SGanbold Tsagaankhuu struct sigaction reapchildren;
76*9005607cSKonstantin Belousov sigset_t sigchld_mask;
775c52a798SGanbold Tsagaankhuu int rc, t;
785c52a798SGanbold Tsagaankhuu
795c52a798SGanbold Tsagaankhuu memset(&reapchildren, 0, sizeof(reapchildren));
80*9005607cSKonstantin Belousov reapchildren.sa_handler = sighandler;
815c52a798SGanbold Tsagaankhuu if (sigaction(SIGCHLD, &reapchildren, NULL) == -1)
825c52a798SGanbold Tsagaankhuu err(1, "Could not sigaction(SIGCHLD)");
835c52a798SGanbold Tsagaankhuu
84*9005607cSKonstantin Belousov sigemptyset(&sigchld_mask);
85*9005607cSKonstantin Belousov sigaddset(&sigchld_mask, SIGCHLD);
86*9005607cSKonstantin Belousov if (sigprocmask(SIG_BLOCK, &sigchld_mask, NULL) == -1)
87*9005607cSKonstantin Belousov err(1, "sigprocmask");
88*9005607cSKonstantin Belousov
895c52a798SGanbold Tsagaankhuu for (t = 0; t < NUM_THREADS; t++) {
90*9005607cSKonstantin Belousov rc = pthread_create(&threads[t], NULL, vfork_test, &t);
915c52a798SGanbold Tsagaankhuu if (rc)
925c52a798SGanbold Tsagaankhuu errc(1, rc, "pthread_create");
935c52a798SGanbold Tsagaankhuu }
94*9005607cSKonstantin Belousov pause();
955c52a798SGanbold Tsagaankhuu return (0);
965c52a798SGanbold Tsagaankhuu }
97