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