xref: /freebsd/tools/test/stress2/misc/fork.sh (revision 10ff414c)
1#!/bin/sh
2
3#
4# Copyright (c) 2014 EMC Corp.
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28
29# The test program calls fork(2) from a multi-threaded process.
30# Test program stuck in uwrlck seen.
31# Fixed in r266609.
32
33# Note that program erroneously calls exit(3) and not _exit(2).
34
35. ../default.cfg
36
37here=`pwd`
38cd /tmp
39sed '1,/^EOF/d' < $here/$0 > fork.c
40mycc -o fork -Wall -Wextra -O2 -g fork.c -lpthread || exit 1
41
42for i in `jot 100`; do
43	/tmp/fork &
44done
45while ! pgrep -q fork; do
46	sleep .2
47done
48for i in `jot 30`; do
49	pgrep -q fork || break
50	sleep 1
51done
52if pgrep -q fork; then
53	echo FAIL
54	exit 1
55fi
56wait
57
58rm -f /tmp/fork /tmp/fork.c
59exit 0
60EOF
61
62/*
63 * Written by Love Hrnquiststrand <lha@NetBSD.org>, March 2003.
64 * Public domain.
65 */
66
67#include <sys/types.h>
68#include <sys/wait.h>
69
70#include <err.h>
71#include <errno.h>
72#include <pthread.h>
73#include <signal.h>
74#include <stdio.h>
75#include <stdlib.h>
76#include <string.h>
77#include <unistd.h>
78
79static pid_t parent;
80static int thread_survived = 0;
81
82static void *
83print_pid(void *arg __unused)
84{
85	sleep(3);
86
87	thread_survived = 1;
88	if (parent != getpid()) {
89		exit(1);
90	}
91	return NULL;
92}
93
94int
95main(void)
96{
97	int r;
98	pthread_t p;
99	pid_t fork_pid;
100
101	parent = getpid();
102
103	r = pthread_create(&p, NULL, print_pid, NULL);
104	if (r != 0)
105		errx(1, "r = %d", r);
106
107	fork_pid = fork();
108	if (fork_pid == -1)
109		err(1, "fork");
110
111	if (fork_pid) {
112		int status;
113
114		r = pthread_join(p, NULL);
115		if (r != 0)
116			errx(1, "r = %d", r);
117		if (thread_survived == 0)
118			errx(1, "thread did not survive in parent");
119
120		waitpid(fork_pid, &status, 0);
121		if (WIFEXITED(status) != 1)
122			printf("WIFEXITED(status) = %d\n", WIFEXITED(status));
123		if (WEXITSTATUS(status) != 0)
124		printf("WEXITSTATUS(status) = %d\n", WEXITSTATUS(status));
125	} else {
126		sleep(5);
127		exit(thread_survived ? 1 : 0);
128	}
129}
130