1#!/bin/sh 2 3# 4# Copyright (c) 2009 Peter Holm <pho@FreeBSD.org> 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# Regression test for panic in semexit_myhook 30# Test scenario by kib@ 31 32. ../default.cfg 33 34odir=`pwd` 35 36cd /tmp 37sed '1,/^EOF/d' < $odir/$0 > sem.c 38mycc -o sem -Wall sem.c 39rm -f sem.c 40 41cd $RUNDIR/.. 42for i in `jot 5`; do 43 /tmp/sem& 44done 45for i in `jot 5`; do 46 wait 47done 48 49rm -f /tmp/sem 50 51exit 52EOF 53#include <stdio.h> 54#include <stdlib.h> 55#include <unistd.h> 56#include <sys/types.h> 57#include <sys/param.h> 58#include <sys/ipc.h> 59#include <sys/msg.h> 60#include <sys/shm.h> 61#include <sys/sem.h> 62#include <signal.h> 63#include <sys/wait.h> 64#include <sched.h> 65#include <errno.h> 66#include <err.h> 67 68int semid = -1; 69key_t semkey; 70struct sembuf sop[2]; 71 72size_t pgsize; 73pid_t pid; 74 75void 76random_work(void) 77{ 78 int i, n; 79 80 n = (arc4random() % 5000) + 200; 81 for (i = 0; i < n; i++) 82 (void) getpid(); 83} 84 85int 86main() 87{ 88 int i, j, seed, status; 89 90 seed = getpid(); 91 semkey = ftok("/", seed); 92 93 for (i = 0; i < 5000; i++) { 94 95 pid = fork(); 96 if (pid == -1) { 97 perror("fork"); 98 exit(2); 99 } 100 101 if (pid == 0) { /* child */ 102 j = 0; 103 /* get sem */ 104 do { 105 sched_yield(); 106 semid = semget(semkey, 0, 0); 107 } while (semid == -1 && j++ < 10000); 108 if (semid == -1) 109 exit(1); 110 111 /* 112 * Attempt to acquire the semaphore. 113 */ 114 sop[0].sem_num = 0; 115 sop[0].sem_op = -1; 116 sop[0].sem_flg = SEM_UNDO; 117 118 semop(semid, sop, 1); 119 random_work(); 120 _exit(0); 121 122 } else { /* parent */ 123 /* create sem */ 124 if ((semid = semget(semkey, 1, IPC_CREAT | 010640)) == -1) 125 err(1, "semget (%s:%d)", __FILE__, __LINE__); 126 usleep(2000); 127 128 sop[0].sem_num = 0; 129 sop[0].sem_op = 1; 130 sop[0].sem_flg = 0; 131 if (semop(semid, sop, 1) == -1) 132 warn("init: semop (%s:%d)", __FILE__, __LINE__); 133 134 random_work(); 135 if (semctl(semid, 0, IPC_RMID, 0) == -1 && errno != EINVAL) 136 warn("shmctl IPC_RMID (%s:%d)", __FILE__, __LINE__); 137 138 } 139 waitpid(pid, &status, 0); 140 } 141 return (0); 142} 143