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 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 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 156 static void cleanup(void) 157 { 158 tst_rmdir(); 159 } 160