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* Opened semaphores are inherited in the child process.. 21 22* The steps are: 23* -> Open 2 named semaphores, then unlink one. 24* -> fork 25* -> The child tries and posts both semaphores, then terminates. 26* -> The parent waits for the child, then check the semaphores were posted 27 28* The test fails if any semaphore has not been posted in the child. 29 30*/ 31 32 33/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 34#define _POSIX_C_SOURCE 200112L 35 36/********************************************************************************************/ 37/****************************** standard includes *****************************************/ 38/********************************************************************************************/ 39#include <pthread.h> 40 #include <stdarg.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <unistd.h> 45 46#include <sys/wait.h> 47 #include <errno.h> 48 49#include <semaphore.h> 50#include <fcntl.h> 51 52/********************************************************************************************/ 53/****************************** Test framework *****************************************/ 54/********************************************************************************************/ 55#include "testfrmw.h" 56 #include "testfrmw.c" 57/* This header is responsible for defining the following macros: 58 * UNRESOLVED(ret, descr); 59 * where descr is a description of the error and ret is an int (error code for example) 60 * FAILED(descr); 61 * where descr is a short text saying why the test has failed. 62 * PASSED(); 63 * No parameter. 64 * 65 * Both three macros shall terminate the calling process. 66 * The testcase shall not terminate in any other maneer. 67 * 68 * The other file defines the functions 69 * void output_init() 70 * void output(char * string, ...) 71 * 72 * Those may be used to output information. 73 */ 74 75/********************************************************************************************/ 76/********************************** Configuration ******************************************/ 77/********************************************************************************************/ 78#ifndef VERBOSE 79#define VERBOSE 1 80#endif 81 82/********************************************************************************************/ 83/*********************************** Test case *****************************************/ 84/********************************************************************************************/ 85/* The main test function. */ 86int main( int argc, char * argv[] ) 87{ 88 int ret, status; 89 pid_t child, ctl; 90 91 sem_t * sem_linked, *sem_unlinked; 92 93 /* Initialize output */ 94 output_init(); 95 96 sem_linked = sem_open( "/fork_14_1a", O_CREAT, O_RDWR, 0 ); 97 98 if ( sem_linked == SEM_FAILED ) 99 { 100 UNRESOLVED( errno, "Failed to create the named semaphore" ); 101 } 102 103 sem_unlinked = sem_open( "/fork_14_1b", O_CREAT, O_RDWR, 0 ); 104 105 if ( sem_unlinked == SEM_FAILED ) 106 { 107 UNRESOLVED( errno, "Failed to create the named semaphore" ); 108 } 109 110 ret = sem_unlink( "/fork_14_1b" ); 111 112 if ( ret != 0 ) 113 { 114 UNRESOLVED( errno, "Failed to unlink the semaphore" ); 115 } 116 117 /* Create the child */ 118 child = fork(); 119 120 if ( child == ( pid_t ) - 1 ) 121 { 122 UNRESOLVED( errno, "Failed to fork" ); 123 } 124 125 /* child */ 126 if ( child == ( pid_t ) 0 ) 127 { 128 do 129 { 130 ret = sem_post( sem_linked ); 131 } 132 while ( ( ret != 0 ) && ( errno == EINTR ) ); 133 134 if ( ret != 0 ) 135 { 136 UNRESOLVED( errno, "Failed to post semaphore A" ); 137 } 138 139 do 140 { 141 ret = sem_post( sem_unlinked ); 142 } 143 while ( ( ret != 0 ) && ( errno == EINTR ) ); 144 145 if ( ret != 0 ) 146 { 147 UNRESOLVED( errno, "Failed to post semaphore B" ); 148 } 149 150 151 /* We're done */ 152 exit( PTS_PASS ); 153 } 154 155 /* Parent joins the child */ 156 ctl = waitpid( child, &status, 0 ); 157 158 if ( ctl != child ) 159 { 160 UNRESOLVED( errno, "Waitpid returned the wrong PID" ); 161 } 162 163 if ( ( !WIFEXITED( status ) ) || ( WEXITSTATUS( status ) != PTS_PASS ) ) 164 { 165 FAILED( "Child exited abnormally" ); 166 } 167 168 /* Check both semaphores have been posted */ 169 do 170 { 171 ret = sem_trywait( sem_linked ); 172 } 173 while ( ( ret != 0 ) && ( errno == EINTR ) ); 174 175 if ( ret != 0 ) 176 { 177 if ( errno == EAGAIN ) 178 { 179 FAILED( "Child did not inherit the semaphore A" ); 180 } 181 else 182 { 183 UNRESOLVED( errno, "sem_trywait failed" ); 184 } 185 } 186 187 do 188 { 189 ret = sem_trywait( sem_unlinked ); 190 } 191 while ( ( ret != 0 ) && ( errno == EINTR ) ); 192 193 if ( ret != 0 ) 194 { 195 if ( errno == EAGAIN ) 196 { 197 FAILED( "Child did not inherit the semaphore B" ); 198 } 199 else 200 { 201 UNRESOLVED( errno, "sem_trywait failed" ); 202 } 203 } 204 205 ret = sem_unlink( "/fork_14_1a" ); 206 207 if ( ret != 0 ) 208 { 209 UNRESOLVED( errno, "Failed to unlink semaphore A" ); 210 } 211 212 ret = sem_close( sem_linked ); 213 214 if ( ret != 0 ) 215 { 216 UNRESOLVED( errno, "Failed to close semaphore A" ); 217 } 218 219 ret = sem_close( sem_unlinked ); 220 221 if ( ret != 0 ) 222 { 223 UNRESOLVED( errno, "Failed to close semaphore B" ); 224 } 225 226 /* Test passed */ 227#if VERBOSE > 0 228 229 output( "Test passed\n" ); 230 231#endif 232 233 PASSED; 234} 235 236