Home | History | Annotate | Download | only in fork
      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