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 *
19 * NAME
20 * fork10.c
21 *
22 * DESCRIPTION
23 * Check inheritance of file descriptor by children, they
24 * should all be refering to the same file.
25 *
26 * ALGORITHM
27 * Child reads several chars and exits.
28 * Parent forks another child, have the child and parent attempt to use
29 * that location
30 *
31 * USAGE
32 * fork10
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 <fcntl.h>
45 #include <stdio.h>
46 #include <errno.h>
47 #include "test.h"
48
49 char *TCID = "fork10";
50 int TST_TOTAL = 1;
51
52 static void setup(void);
53 static void cleanup(void);
54
55 static char pidbuf[10];
56 static char fnamebuf[40];
57
main(int ac,char ** av)58 int main(int ac, char **av)
59 {
60 int status, pid, fildes;
61 char parchar[2];
62 char chilchar[2];
63
64 int lc;
65
66 fildes = -1;
67
68 tst_parse_opts(ac, av, NULL, NULL);
69
70 setup();
71
72 for (lc = 0; TEST_LOOPING(lc); lc++) {
73 tst_count = 0;
74
75 fildes = creat(fnamebuf, 0600);
76 if (fildes < 0)
77 tst_brkm(TBROK | TERRNO, cleanup,
78 "Parent: cannot open %s for " "write",
79 fnamebuf);
80 write(fildes, "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", 27);
81 close(fildes);
82
83 fildes = open(fnamebuf, 0);
84 if (fildes == -1)
85 tst_brkm(TBROK, cleanup, "Parent: cannot open %s for "
86 "reading", fnamebuf);
87
88 pid = fork();
89 if (pid == -1)
90 tst_brkm(TBROK, cleanup, "fork() #1 failed");
91
92 if (pid == 0) { /* child */
93 tst_resm(TINFO, "fork child A");
94 if (lseek(fildes, 10L, 0) == -1L) {
95 tst_resm(TFAIL, "bad lseek by child");
96 exit(1);
97 }
98 exit(0);
99 } else { /* parent */
100 wait(&status);
101
102 /* parent starts second child */
103 pid = fork();
104 if (pid == -1)
105 tst_brkm(TBROK, cleanup, "fork() #2 failed");
106
107 if (pid == 0) { /* child */
108 if (read(fildes, chilchar, 1) <= 0) {
109 tst_resm(TFAIL, "Child can't read "
110 "file");
111 exit(1);
112 } else {
113 if (chilchar[0] != 'K') {
114 chilchar[1] = '\n';
115 exit(1);
116 } else {
117 exit(0);
118 }
119 }
120 } else { /* parent */
121 (void)wait(&status);
122 if (status >> 8 != 0) {
123 tst_resm(TFAIL, "Bad return from "
124 "second child");
125 continue;
126 }
127 /* parent reads */
128 if (read(fildes, parchar, 1) <= 0) {
129 tst_resm(TFAIL, "Parent cannot read "
130 "file");
131 continue;
132 } else {
133 write(fildes, parchar, 1);
134 if (parchar[0] != 'L') {
135 parchar[1] = '\n';
136 tst_resm(TFAIL, "Test failed");
137 continue;
138 }
139 }
140 }
141 }
142 tst_resm(TPASS, "test 1 PASSED");
143 }
144
145 close(fildes);
146 cleanup();
147 tst_exit();
148 }
149
setup(void)150 static void setup(void)
151 {
152 tst_sig(FORK, DEF_HANDLER, cleanup);
153 umask(0);
154 TEST_PAUSE;
155 tst_tmpdir();
156
157 strcpy(fnamebuf, "fork10.");
158 sprintf(pidbuf, "%d", getpid());
159 strcat(fnamebuf, pidbuf);
160 }
161
cleanup(void)162 static void cleanup(void)
163 {
164 tst_rmdir();
165 }
166