• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   Copyright (c) International Business Machines  Corp., 2001
3  *
4  *   This program is free software;  you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation; either version 2 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12  *   the GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program;  if not, write to the Free Software
16  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * NAME
19  *	fork08.c
20  *
21  * DESCRIPTION
22  *	Check if the parent's file descriptors are affected by
23  *	actions in the child; they should not be.
24  *
25  * ALGORITHM
26  *	Parent opens a file.
27  *	Forks a child which closes a file.
28  *	Parent forks a second child which attempts to read the (closed)
29  *	file.
30  *
31  * USAGE
32  *	fork08
33  *
34  * HISTORY
35  *	07/2001 Ported by Wayne Boyer
36  *
37  * RESTRICTIONS
38  *	None
39  */
40 
41 #include <sys/types.h>
42 #include <sys/wait.h>
43 #include <sys/stat.h>
44 #include <stdio.h>
45 #include "test.h"
46 
47 char *TCID = "fork08";
48 int TST_TOTAL = 1;
49 
50 static void setup(void);
51 static void cleanup(void);
52 
53 static char pbuf[10];
54 static char fnamebuf[40];
55 
main(int ac,char ** av)56 int main(int ac, char **av)
57 {
58 	int status, count, forks, pid1;
59 	int ch_r_stat;
60 	FILE *rea, *writ;
61 
62 	int lc;
63 
64 	tst_parse_opts(ac, av, NULL, NULL);
65 
66 	setup();
67 
68 	for (lc = 0; TEST_LOOPING(lc); lc++) {
69 		tst_count = 0;
70 
71 		writ = fopen(fnamebuf, "w");
72 		if (writ == NULL)
73 			tst_resm(TFAIL, "failed to fopen file for write");
74 		rea = fopen(fnamebuf, "r");
75 		if (rea == NULL)
76 			tst_resm(TFAIL, "failed to fopen file for read");
77 
78 		fprintf(writ, "abcdefghijklmnopqrstuv");
79 		fflush(writ);
80 		sleep(1);
81 
82 		if ((getc(rea)) != 'a')
83 			tst_resm(TFAIL, "getc from read side was confused");
84 
85 		forks = 0;
86 
87 forkone:
88 		++forks;
89 
90 		pid1 = fork();
91 		if (pid1 != 0) {
92 			tst_resm(TINFO, "parent forksval: %d", forks);
93 
94 			if ((pid1 != (-1)) && (forks < 2))
95 				goto forkone;
96 			else if (pid1 < 0)
97 				tst_resm(TINFO, "Fork failed");
98 		} else {	/* child */
99 			/*
100 			 * If first child close the file descriptor for the
101 			 * read stream
102 			 */
103 			if (forks == 1) {
104 				if ((fclose(rea)) == -1) {
105 					tst_resm(TFAIL, "error in first child"
106 						 " closing fildes");
107 				}
108 				_exit(0);
109 			}
110 
111 			/*
112 			 * If second child attempt to read from the file
113 			 */
114 			else if (forks == 2) {
115 				ch_r_stat = getc(rea);
116 				tst_resm(TINFO, "second child got char: %c",
117 					 ch_r_stat);
118 				if (ch_r_stat == 'b') {
119 					tst_resm(TPASS, "Test passed in child"
120 						 "number %d", forks);
121 					exit(0);
122 				} else if (ch_r_stat == EOF) {
123 					tst_resm(TFAIL, "Second child got "
124 						 "EOF");
125 					exit(-1);
126 				} else {
127 					tst_resm(TFAIL, "test failed in child"
128 						 "no %d", forks);
129 					exit(-1);
130 				}
131 			} else {	/* end of second child */
132 				tst_resm(TINFO, "forksnumber: %d", forks);
133 				exit(3);
134 			}
135 		}
136 
137 		for (count = 0; count <= forks; count++) {
138 			wait(&status);
139 			tst_resm(TINFO, "exit status of wait "
140 				 " expected 0 got %d", status);
141 			status >>= 8;
142 			if (status == 0)
143 				tst_resm(TPASS, "parent test PASSED");
144 			else
145 				tst_resm(TFAIL, "parent test FAILED");
146 		}
147 
148 		tst_resm(TINFO, "Number of processes forked is %d", forks);
149 		fclose(rea);
150 		fclose(writ);
151 	}
152 
153 	cleanup();
154 	tst_exit();
155 }
156 
setup(void)157 static void setup(void)
158 {
159 	tst_sig(FORK, DEF_HANDLER, cleanup);
160 	umask(0);
161 	TEST_PAUSE;
162 	tst_tmpdir();
163 
164 	strcpy(fnamebuf, "fork07.");
165 	sprintf(pbuf, "%d", getpid());
166 	strcat(fnamebuf, pbuf);
167 }
168 
cleanup(void)169 static void cleanup(void)
170 {
171 	tst_rmdir();
172 }
173