xref: /aosp_15_r20/external/ltp/testcases/open_posix_testsuite/conformance/interfaces/fork/6-1.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
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.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 
17 * This sample test aims to check the following assertion:
18 *
19 * The opened directory streams are copied to the child process.
20 * Positionning information may be shared between both processes.
21 
22 * The steps are:
23 * -> Open the current directory,
24 * -> Count the directory entries, then rewind.
25 * -> create a child
26 * -> The child counts the directory entries.
27 
28 * The test fails if the directory is read in the parent and not in the child.
29 
30 */
31 
32 
33 #include <pthread.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39 
40 #include <sys/wait.h>
41 #include <errno.h>
42 
43 #include <dirent.h>
44 
45 #include "../testfrmw/testfrmw.h"
46 #include "../testfrmw/testfrmw.c"
47 
48 #ifndef VERBOSE
49 #define VERBOSE 1
50 #endif
51 
count(DIR * thedir)52 static int count(DIR * thedir)
53 {
54 	int counter = 0;
55 
56 	struct dirent *dp;
57 
58 	rewinddir(thedir);
59 
60 	/* Count the directory entries */
61 
62 	do {
63 		dp = readdir(thedir);
64 
65 		if (dp != NULL)
66 			counter++;
67 	}
68 	while (dp != NULL);
69 
70 	return counter;
71 }
72 
main(void)73 int main(void)
74 {
75 	int ret, status;
76 	pid_t child, ctl;
77 
78 	int counted;
79 
80 	/* the '.' directory pointers */
81 	DIR *dotdir;
82 
83 	output_init();
84 
85 	/* Open the directory */
86 	dotdir = opendir(".");
87 
88 	if (dotdir == NULL) {
89 		UNRESOLVED(errno, "opendir failed");
90 	}
91 
92 	/* Count entries */
93 	counted = count(dotdir);
94 
95 #if VERBOSE > 0
96 
97 	output("Found %d entries in current dir\n", counted);
98 
99 #endif
100 
101 	/* Create the child */
102 	child = fork();
103 
104 	if (child == -1) {
105 		UNRESOLVED(errno, "Failed to fork");
106 	}
107 
108 	/* child */
109 	if (child == 0) {
110 		/* Count in child process */
111 		counted = count(dotdir);
112 
113 #if VERBOSE > 0
114 
115 		output("Found %d entries in current dir from child\n", counted);
116 #endif
117 
118 		ret = closedir(dotdir);
119 
120 		if (ret != 0) {
121 			UNRESOLVED(errno, "Failed to close dir in child");
122 		}
123 
124 		/* We're done */
125 		exit(PTS_PASS);
126 	}
127 
128 	/* Parent joins the child */
129 	ctl = waitpid(child, &status, 0);
130 
131 	if (ctl != child) {
132 		UNRESOLVED(errno, "Waitpid returned the wrong PID");
133 	}
134 
135 	if (!WIFEXITED(status) || (WEXITSTATUS(status) != PTS_PASS)) {
136 		FAILED("Child exited abnormally -- dir stream not copied?");
137 	}
138 
139 	/* close the directory stream */
140 	ret = closedir(dotdir);
141 
142 	if (ret != 0) {
143 		UNRESOLVED(errno, "Failed to closedir in parent");
144 	}
145 
146 #if VERBOSE > 0
147 	output("Test passed\n");
148 
149 #endif
150 
151 	PASSED;
152 }
153