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 #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