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 #include "safe_macros.h"
49
50 char *TCID = "fork10";
51 int TST_TOTAL = 1;
52
53 static void setup(void);
54 static void cleanup(void);
55
56 static char pidbuf[10];
57 static char fnamebuf[40];
58
main(int ac,char ** av)59 int main(int ac, char **av)
60 {
61 int status, pid, fildes;
62 char parchar[2];
63 char chilchar[2];
64
65 int lc;
66
67 fildes = -1;
68
69 tst_parse_opts(ac, av, NULL, NULL);
70
71 setup();
72
73 for (lc = 0; TEST_LOOPING(lc); lc++) {
74 tst_count = 0;
75
76 fildes = SAFE_CREAT(cleanup, fnamebuf, 0600);
77 write(fildes, "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", 27);
78 close(fildes);
79
80 fildes = SAFE_OPEN(cleanup, fnamebuf, 0);
81
82 pid = fork();
83 if (pid == -1)
84 tst_brkm(TBROK, cleanup, "fork() #1 failed");
85
86 if (pid == 0) { /* child */
87 tst_resm(TINFO, "fork child A");
88 if (lseek(fildes, 10L, 0) == -1L) {
89 tst_resm(TFAIL, "bad lseek by child");
90 exit(1);
91 }
92 exit(0);
93 } else { /* parent */
94 wait(&status);
95
96 /* parent starts second child */
97 pid = fork();
98 if (pid == -1)
99 tst_brkm(TBROK, cleanup, "fork() #2 failed");
100
101 if (pid == 0) { /* child */
102 if (read(fildes, chilchar, 1) <= 0) {
103 tst_resm(TFAIL, "Child can't read "
104 "file");
105 exit(1);
106 } else {
107 if (chilchar[0] != 'K') {
108 chilchar[1] = '\n';
109 exit(1);
110 } else {
111 exit(0);
112 }
113 }
114 } else { /* parent */
115 (void)wait(&status);
116 if (status >> 8 != 0) {
117 tst_resm(TFAIL, "Bad return from "
118 "second child");
119 continue;
120 }
121 /* parent reads */
122 if (read(fildes, parchar, 1) <= 0) {
123 tst_resm(TFAIL, "Parent cannot read "
124 "file");
125 continue;
126 } else {
127 write(fildes, parchar, 1);
128 if (parchar[0] != 'L') {
129 parchar[1] = '\n';
130 tst_resm(TFAIL, "Test failed");
131 continue;
132 }
133 }
134 }
135 }
136 tst_resm(TPASS, "test 1 PASSED");
137 }
138
139 close(fildes);
140 cleanup();
141 tst_exit();
142 }
143
setup(void)144 static void setup(void)
145 {
146 tst_sig(FORK, DEF_HANDLER, cleanup);
147 umask(0);
148 TEST_PAUSE;
149 tst_tmpdir();
150
151 strcpy(fnamebuf, "fork10.");
152 sprintf(pidbuf, "%d", getpid());
153 strcat(fnamebuf, pidbuf);
154 }
155
cleanup(void)156 static void cleanup(void)
157 {
158 tst_rmdir();
159 }
160