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 opened directory streams are copied to the child process. 21* Positionning information may be shared between both processes. 22 23* The steps are: 24* -> Open the current directory, 25* -> Count the directory entries, then rewind. 26* -> create a child 27* -> The child counts the directory entries. 28 29* The test fails if the directory is read in the parent and not in the child. 30 31*/ 32 33 34/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 35#define _POSIX_C_SOURCE 200112L 36 37/********************************************************************************************/ 38/****************************** standard includes *****************************************/ 39/********************************************************************************************/ 40#include <pthread.h> 41 #include <stdarg.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <unistd.h> 46 47#include <sys/wait.h> 48 #include <errno.h> 49 50#include <dirent.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 86int count( DIR * thedir ) 87{ 88 int counter = 0; 89 90 struct dirent *dp; 91 92 rewinddir( thedir ); 93 94 /* Count the directory entries */ 95 96 do 97 { 98 dp = readdir( thedir ); 99 100 if ( dp != NULL ) 101 counter++; 102 } 103 while ( dp != NULL ); 104 105 return counter; 106} 107 108/* The main test function. */ 109int main( int argc, char * argv[] ) 110{ 111 int ret, status; 112 pid_t child, ctl; 113 114 int counted; 115 116 /* the '.' directory pointers */ 117 DIR *dotdir; 118 119 /* Initialize output */ 120 output_init(); 121 122 /* Open the directory */ 123 dotdir = opendir( "." ); 124 125 if ( dotdir == NULL ) 126 { 127 UNRESOLVED( errno, "opendir failed" ); 128 } 129 130 /* Count entries */ 131 counted = count( dotdir ); 132 133#if VERBOSE > 0 134 135 output( "Found %d entries in current dir\n", counted ); 136 137#endif 138 139 /* Create the child */ 140 child = fork(); 141 142 if ( child == ( pid_t ) - 1 ) 143 { 144 UNRESOLVED( errno, "Failed to fork" ); 145 } 146 147 /* child */ 148 if ( child == ( pid_t ) 0 ) 149 { 150 /* Count in child process */ 151 counted = count( dotdir ); 152 153#if VERBOSE > 0 154 155 output( "Found %d entries in current dir from child\n", counted ); 156#endif 157 158 ret = closedir( dotdir ); 159 160 if ( ret != 0 ) 161 { 162 UNRESOLVED( errno, "Failed to close dir in child" ); 163 } 164 165 /* We're done */ 166 exit( PTS_PASS ); 167 } 168 169 /* Parent joins the child */ 170 ctl = waitpid( child, &status, 0 ); 171 172 if ( ctl != child ) 173 { 174 UNRESOLVED( errno, "Waitpid returned the wrong PID" ); 175 } 176 177 if ( ( !WIFEXITED( status ) ) || ( WEXITSTATUS( status ) != PTS_PASS ) ) 178 { 179 FAILED( "Child exited abnormally -- dir stream not copied?" ); 180 } 181 182 /* close the directory stream */ 183 ret = closedir( dotdir ); 184 185 if ( ret != 0 ) 186 { 187 UNRESOLVED( errno, "Failed to closedir in parent" ); 188 } 189 190 /* Test passed */ 191#if VERBOSE > 0 192 output( "Test passed\n" ); 193 194#endif 195 196 PASSED; 197} 198 199 200