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 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 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 162 static void cleanup(void) 163 { 164 tst_rmdir(); 165 } 166