1/* 2* Copyright (c) 2004, Bull S.A.. All rights reserved. 3* Created by: Sebastien Decugis 4 5* This program is free software; you can redistribute it and/or modify it 6* under the terms of version 2 of the GNU General Public License as 7* published by the Free Software Foundation. 8* 9* This program is distributed in the hope that it would be useful, but 10* WITHOUT ANY WARRANTY; without even the implied warranty of 11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12* 13* You should have received a copy of the GNU General Public License along 14* with this program; if not, write the Free Software Foundation, Inc., 59 15* Temple Place - Suite 330, Boston MA 02111-1307, USA. 16 17 18* This sample test aims to check the following assertion: 19* 20* The new process has only one thread. 21 22* The steps are: 23* -> create a thread. 24* -> fork 25* -> Check that the thread is not running in the new process image. 26 27* The test fails if the thread is executing in the child process. 28 29*/ 30 31 32/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 33#define _POSIX_C_SOURCE 200112L 34 35/********************************************************************************************/ 36/****************************** standard includes *****************************************/ 37/********************************************************************************************/ 38#include <pthread.h> 39 #include <stdarg.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <unistd.h> 44 45#include <sys/wait.h> 46 #include <errno.h> 47 48#include <semaphore.h> 49#include <fcntl.h> 50 51/********************************************************************************************/ 52/****************************** Test framework *****************************************/ 53/********************************************************************************************/ 54#include "testfrmw.h" 55 #include "testfrmw.c" 56/* This header is responsible for defining the following macros: 57 * UNRESOLVED(ret, descr); 58 * where descr is a description of the error and ret is an int (error code for example) 59 * FAILED(descr); 60 * where descr is a short text saying why the test has failed. 61 * PASSED(); 62 * No parameter. 63 * 64 * Both three macros shall terminate the calling process. 65 * The testcase shall not terminate in any other maneer. 66 * 67 * The other file defines the functions 68 * void output_init() 69 * void output(char * string, ...) 70 * 71 * Those may be used to output information. 72 */ 73 74/********************************************************************************************/ 75/********************************** Configuration ******************************************/ 76/********************************************************************************************/ 77#ifndef VERBOSE 78#define VERBOSE 1 79#endif 80 81/********************************************************************************************/ 82/*********************************** Test case *****************************************/ 83/********************************************************************************************/ 84 85sem_t * sem; 86 87/* Thread function */ 88void * threaded( void * arg ) 89{ 90 int ret = 0; 91 92 do 93 { 94 ret = sem_wait( sem ); 95 } 96 while ( ( ret != 0 ) && ( errno == EINTR ) ); 97 98 if ( ret != 0 ) 99 { 100 UNRESOLVED( errno, "failed to wait for the semaphore in child" ); 101 } 102 103 if ( *( pid_t * ) arg != getpid() ) 104 { 105 FAILED( "The thread is executing in the child process" ); 106 } 107 108 return NULL; 109} 110 111/* The main test function. */ 112int main( int argc, char * argv[] ) 113{ 114 int ret, status; 115 pid_t child, ctl; 116 pthread_t th; 117 118 /* Initialize output */ 119 output_init(); 120 121 ctl = getpid(); 122 123 /* Initialize the semaphore */ 124 sem = sem_open( "/fork_21_1", O_CREAT, O_RDWR, 0 ); 125 126 if ( sem == ( sem_t * ) SEM_FAILED ) 127 { 128 UNRESOLVED( errno, "Failed to open the semaphore" ); 129 } 130 131 sem_unlink( "/fork_21_1" ); 132 133 134 /* Create thread */ 135 ret = pthread_create( &th, NULL, threaded, &ctl ); 136 137 if ( ret != 0 ) 138 { 139 UNRESOLVED( ret, "Failed to create the thread" ); 140 } 141 142 143 /* Create the child */ 144 child = fork(); 145 146 if ( child == ( pid_t ) - 1 ) 147 { 148 UNRESOLVED( errno, "Failed to fork" ); 149 } 150 151 /* We post the semaphore twice */ 152 do 153 { 154 ret = sem_post( sem ); 155 } 156 while ( ( ret != 0 ) && ( errno == EINTR ) ); 157 158 if ( ret != 0 ) 159 { 160 UNRESOLVED( errno, "Failed to post the semaphore" ); 161 } 162 163 /* child */ 164 if ( child == ( pid_t ) 0 ) 165 { 166 /* sleep a little while to let the thread execute in case it exists */ 167 sleep( 1 ); 168 169 /* We're done */ 170 exit( PTS_PASS ); 171 } 172 173 /* Parent joins the child */ 174 ctl = waitpid( child, &status, 0 ); 175 176 if ( ctl != child ) 177 { 178 UNRESOLVED( errno, "Waitpid returned the wrong PID" ); 179 } 180 181 if ( ( !WIFEXITED( status ) ) || ( WEXITSTATUS( status ) != PTS_PASS ) ) 182 { 183 FAILED( "Child exited abnormally" ); 184 } 185 186 /* Destroy everything */ 187 ret = sem_close( sem ); 188 189 if ( ret != 0 ) 190 { 191 UNRESOLVED( errno, "Failed to close the semaphore" ); 192 } 193 194 ret = pthread_join( th, NULL ); 195 196 if ( ret != 0 ) 197 { 198 UNRESOLVED( ret, "Failed to join the thread in parent" ); 199 } 200 201 /* Test passed */ 202#if VERBOSE > 0 203 output( "Test passed\n" ); 204 205#endif 206 PASSED; 207} 208 209