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 file locks are not inherited by the child process. 21 22* The steps are: 23* -> lock stdout 24* -> fork 25* -> child creates a thread 26* -> child thread trylock stdout 27* -> join the child 28 29* The test fails if the child thread cannot lock the file 30* -- this would mean the child process got stdout file lock ownership. 31 32*/ 33 34 35/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 36#define _POSIX_C_SOURCE 200112L 37 38/********************************************************************************************/ 39/****************************** standard includes *****************************************/ 40/********************************************************************************************/ 41#include <pthread.h> 42 #include <stdarg.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <unistd.h> 47 48#include <sys/wait.h> 49 #include <errno.h> 50 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/* Thread function */ 86void * threaded( void * arg ) 87{ 88 int ret; 89 ret = ftrylockfile( stdout ); 90 91 if ( ret != 0 ) 92 { 93 FAILED( "The child process is owning the file lock." ); 94 } 95 96#if VERBOSE > 1 97 98 output( "The file lock was not inherited in the child process\n" ); 99 100#endif 101 102 return NULL; 103} 104 105/* The main test function. */ 106int main( int argc, char * argv[] ) 107{ 108 int ret, status; 109 pid_t child, ctl; 110 pthread_t ch; 111 112 /* Initialize output */ 113 output_init(); 114 115 /* lock the stdout file */ 116 flockfile( stdout ); 117 118 /* Create the child */ 119 child = fork(); 120 121 if ( child == ( pid_t ) - 1 ) 122 { 123 UNRESOLVED( errno, "Failed to fork" ); 124 } 125 126 /* child */ 127 if ( child == ( pid_t ) 0 ) 128 { 129 130 ret = pthread_create( &ch, NULL, threaded, NULL ); 131 132 if ( ret != 0 ) 133 { 134 UNRESOLVED( ret, "Failed to create a thread" ); 135 } 136 137 ret = pthread_join( ch, NULL ); 138 139 if ( ret != 0 ) 140 { 141 UNRESOLVED( ret, "Failed to join the thread" ); 142 } 143 144 /* We're done */ 145 exit( PTS_PASS ); 146 } 147 148 /* Parent sleeps for a while to create contension in case the file lock is inherited */ 149 sleep( 1 ); 150 151 funlockfile( stdout ); 152 153 /* Parent joins the child */ 154 ctl = waitpid( child, &status, 0 ); 155 156 if ( ctl != child ) 157 { 158 UNRESOLVED( errno, "Waitpid returned the wrong PID" ); 159 } 160 161 if ( ( !WIFEXITED( status ) ) || ( WEXITSTATUS( status ) != PTS_PASS ) ) 162 { 163 FAILED( "Child exited abnormally" ); 164 } 165 166 /* Test passed */ 167#if VERBOSE > 0 168 169 output( "Test passed\n" ); 170 171#endif 172 173 PASSED; 174} 175 176 177