pipe_test_02.c revision 2c28215423293e443469a07ae7011135d058b671
1d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*
2450ff20648579497cb788007438625aa74518d20subrata_modak *   Copyright (C) Bull S.A. 1996
3d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   Copyright (c) International Business Machines  Corp., 2001
4d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
5d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   This program is free software;  you can redistribute it and/or modify
6d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   it under the terms of the GNU General Public License as published by
7d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   the Free Software Foundation; either version 2 of the License, or
8d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   (at your option) any later version.
9d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
10d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   This program is distributed in the hope that it will be useful,
11d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   the GNU General Public License for more details.
14d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
15d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   You should have received a copy of the GNU General Public License
16d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   along with this program;  if not, write to the Free Software
17d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */
19d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
20d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                            pipe_test_02                              |
21d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
22d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
23d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Description:  Max data transfer through pipe interprocess channel    |
24d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               in non-blocking mode                                   |
25d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
26d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Algorithm:    o  Create a pipe                                       |
27d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               o  Make write & read end of pipe non-blocking          |
28d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               o  Spawn a child process                               |
29d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               o  parent:                                             |
30d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  -  create & send data packets to the child          |
31d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  -  compute checksum on sent packets                 |
32d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               o  child:                                              |
33d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  -  recieve packets from parent & compute checksum   |
34d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  -  send final checksum to parent                    |
35d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               o  parent:                                             |
36d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  -  compare checksum of sent packets with the        |
37d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                     child's checksum                                 |
38d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
39d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| System calls: The following system calls are tested:                 |
40d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
41d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               pipe () - Creates an interprocess channel              |
42d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               fork () - Creates a new process                        |
43d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               fcntl () -                                             |
44d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               waitpid () - Waits for a child process to stop or      |
45d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
46d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Usage:        pipe_test_02                                           |
47d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
48d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| To compile:   cc -o pipe_test_02 pipe_test_02.c                      |
49d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
50d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Last update:   Ver. 1.3, 3/3/94 12:06:38                           |
51d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
52d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Change Activity                                                      |
53d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
54d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|   Version  Date    Name  Reason                                      |
55d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|    0.1     010393  DJK   Initial version for AIX 4.1                 |
56d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|    1.2     021394  DJK   Move to "prod" directory                    |
57d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
58d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
59d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
60d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <errno.h>
61d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <fcntl.h>
62d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <signal.h>
63d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <stdio.h>
64f3a83d59cce260ab513313b2c43c41fc16983959robbiew#include <stdlib.h>
65d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <string.h>
66d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <sys/types.h>
67d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <sys/wait.h>
68d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <unistd.h>
69d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
70d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/* Defines:
71d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
72d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * MB: one megabyte (MB)
73d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
74d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * VALID_PACKET: value sent with each packet, used to verify that the
75d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * packets contents were not garbled.
764bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak *
77d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * DEFAULT_NUM_CHILDREN: default number of child processes spawned
782c28215423293e443469a07ae7011135d058b671Garrett Cooper *
79d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * DEFAULT_PACKETS_TO_SEND: default number of packets sent to each child
80d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * process.
81d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
82d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * MAXCHILD: maximum number of child processes which may be spawned
83d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * (based upon the number of file descriptors that a process may use)
842c28215423293e443469a07ae7011135d058b671Garrett Cooper *
85d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * USAGE: usage statement
86d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */
87d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#define MB			(1024*1024)
88d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#define DEFAULT_PACKETS_TO_SEND 1024
89d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#define DEFAULT_NUM_CHILDREN	1
9028e814915bc75e3ee3184c2bdf17d7a6edffcb1asubrata_modak#define OPEN_MAX		256
91d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#define MAXCHILD 		(OPEN_MAX/2 - 2)
92bdbaec51a423e715c2b03ed9e497e9a1fba6103esubrata_modak#define VALID_PACKET		0xabcdef01
93d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#define USAGE	"\nUsage: %s [-n] [-p nprocs] [{-m totmegs | -b totbytes}]\n\n" \
94d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		"\t-n          transfer data with NON-BLOCKING reads & writes\n" \
95d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		"\t-p nprocs   number of child processes to spawn\n" \
96d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		"\t-m totmegs  number of MB to send through pipe\n" \
97d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		"\t-b totmegs  number of bytes to send through pipe\n" \
98d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		"\t                  (must be less than %d)\n\n"
99d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
100d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*
101d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Function Prototypes:
1022c28215423293e443469a07ae7011135d058b671Garrett Cooper *
103d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * setup (): Parse command line arguments and intialize variables
104d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * child (): Child process
105d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * cleanup (): Close all pipes and kill child processes
106d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * sys_error (): System error message function
107d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * error (): Error message function
108d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * setup_signal_handlers (): Sets up signal catching functions
109d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * handler (): Signal catching function
110d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */
111d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid setup (int, char **);
112d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid child (int [], int []);
113d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid cleanup ();
114d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid sys_error (const char *, int);
115d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid error (const char *, int);
116d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid setup_signal_handlers ();
117d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid handler (int, int, struct sigcontext *);
118d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
119d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*
120d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Structures & Global variables
1214bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak *
1224bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * num_children: number of child processes to be spawned
1234bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak *
124d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * num_packets: number of packets to be sent to each child process
125d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
1264bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * non_blocking_flag: uses NON-BLOCKING
127d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
128d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * pid: process id's of the spawned processes
129d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
130d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * p2child: half duplex pipes from parent to child (parent writes,
131d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *          child reads).
132d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
133d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * p2parent: half duplex pipe from child to parent (child writes,
134d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *           parent reads).
135d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */
136d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
137d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojenum { READ, WRITE };		/* Pipe read & write end indices */
138d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
139d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojstruct data_packet {
140d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	pid_t		pid;		/* Child process id */
141d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	int 		last;		/* Indicates last packet when set */
142d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	long 		valid;		/* Insure packet was not garbled */
143d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	long 		seq_number;	/* Packet sequence number */
144d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	unsigned long	checksum;	/* Cumulative checksum so far */
145d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	unsigned char	data;		/* Data sent in packet */
146d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj};
147d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojtypedef struct data_packet data_packet;
148d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
149d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojint     num_children = DEFAULT_NUM_CHILDREN;
150d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojlong	num_packets  = DEFAULT_PACKETS_TO_SEND;
151d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojint	non_blocking_flag = 0;	/* Uses NON-BLOCKING pipes when set */
152d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojint	bflg = 0;		/* Data quantity flag (MB) */
153d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojint	mflg = 0;		/* Data quantity flag (bytes) */
154d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
155d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojpid_t	parent_pid;		/* Parent's process id */
156d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojpid_t	pid [MAXCHILD];		/* Process id's of spawned processes */
157d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojint	p2child [MAXCHILD][2]; 	/* Pipes from parent to child processes */
158d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojint	p2parent [2];  		/* Pipe from child processes to parent */
159d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojchar	err_msg [256];		/* Generic error message buffer */
160d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
161d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
162d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                               main ()                                |
163d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
164d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
165d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Main program  (see prolog for more details)               |
166d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
167d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Returns:   (0)  Successful completion                                |
168d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            (-1) Error occurred                                       |
169d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
170d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
171d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojint main (int argc, char **argv)
172d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
173d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	int 	i;
174d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	int 	n;		/* Number of bytes written */
175d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	int	status;		/* Child's exit status */
176d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	long	packets_sent;
177d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	unsigned char 	data;
178d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	unsigned long 	cksum_parent = 0;
179d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	data_packet	packet;
180d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
181d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/*
182d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Parse command line arguments, initialize global variables and
183d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * print program header
184d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
185d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	setup (argc, argv);
186d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("%s: IPC Pipe TestSuite program\n", *argv);
187d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	fflush (stdout);
1882c28215423293e443469a07ae7011135d058b671Garrett Cooper
1894bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	/*
1902c28215423293e443469a07ae7011135d058b671Garrett Cooper	 * Create two sets of half duplex pipes:
1914bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
1924bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * p2child: for sending packets from the parent process to the child
193d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *          processes and
1944bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * p2parent: for sending checksums from the child processes to the
195d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *           parent
1964bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
197d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * If the non-blocking command line option was specified, use fcntl ()
198d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * to set the O_NONBLOCK file descriptor status flags.  This will
199d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * prevent reads & and writes from blocking if the data is not yet
200d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * available
201d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
202d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("\n\tCreating pipes...\n");
203d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	fflush (stdout);
204d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
2054bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	if (pipe (p2parent) < 0)
206d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("pipe failed", __LINE__);
207d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
208d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (non_blocking_flag) {
209d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		printf ("\n\tSending data NON-BLOCKING!\n");
210d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		fflush (stdout);
211d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
212d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
213d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	for (i=0; i<num_children; i++) {
2144bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak		if (pipe (&p2child [i][0]) < 0)
215d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			sys_error ("pipe failed", __LINE__);
216d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if (non_blocking_flag) {
217d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			if (fcntl (p2child [i][READ], F_SETFL, O_NONBLOCK) < 0)
218d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				sys_error ("fcntl (O_NONBLOCK) failed", __LINE__);
219d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			if (fcntl (p2child [i][WRITE], F_SETFL, O_NONBLOCK) < 0)
220d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				sys_error ("fcntl (O_NONBLOCK) failed", __LINE__);
221d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		}
222d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
223d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
224d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/*
225d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Spawn num_children processes
2264bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
227d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Fork of the child process & record the newly created process's
2282c28215423293e443469a07ae7011135d058b671Garrett Cooper	 * id for future reference.
2292c28215423293e443469a07ae7011135d058b671Garrett Cooper	 *
2304bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * Then close the READ end of the p2child pipe, since the parent
231d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * process will be writing into this pipe rather than reading.
2324bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * Also close the WRITE end of the p2parent pipe, for just the
233d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * the reverse reasons...
234d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
235d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("\n\tSpawning %d child processes ... \n", num_children);
236d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	fflush (stdout);
237d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
238d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	for (i=0; i<num_children; i++) {
239d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
240d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if ((pid [i] = fork()) == 0) {
241d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
242d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			/* Child process */
243d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			child (&p2child[i][0], p2parent);
244d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			exit (0);
245d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
246d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		} else if (pid [i] < (pid_t)0)
247d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			sys_error ("fork failed", __LINE__);
248d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
249d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if (close (p2child [i][READ]) < 0)
250d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			sys_error ("close failed", __LINE__);
251d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
252d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (close (p2parent [WRITE]) < 0)
253d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("close failed", __LINE__);
254d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
255d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/*
256d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Send data packets to the child processes
2574bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
258d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Build packets (initialize all of the packets fields) and then
259d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * send the packets to all of the child processes.
2604bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
2614bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * Might have to make several attempts with the NON-BLOCKING writes
262d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * if the resource is not immediately available.
263d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
2644bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	printf ("\n\tParent: sending %ld packets (%ld bytes) to child processes ...\n",
265d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		num_packets, num_packets * sizeof (struct data_packet));
266d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
267d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	packet.last = 0;
268d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	packet.valid = VALID_PACKET;
269d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
270d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	for (packets_sent = data = 0; num_packets > 0; num_packets--) {
271d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
272d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		packet.seq_number = ++packets_sent;
273d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		packet.data = data++;
274d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		packet.pid = pid [i];
275d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		packet.checksum = cksum_parent += packet.data;
276d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
277f3a83d59cce260ab513313b2c43c41fc16983959robbiew		for (i=0; i<num_children; i++) {
278d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			try_write_ETXN_again:
279045fd16a63837924a0f20d2419fbd497f8e36764robbiew			if ((n = write (p2child [i][WRITE], &packet,
280045fd16a63837924a0f20d2419fbd497f8e36764robbiew					sizeof (packet))) < 0) {
281045fd16a63837924a0f20d2419fbd497f8e36764robbiew				if (non_blocking_flag && errno == EAGAIN) {
282d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj					goto try_write_ETXN_again;
283045fd16a63837924a0f20d2419fbd497f8e36764robbiew				} else {
284d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj					sys_error ("write failed", __LINE__);
285045fd16a63837924a0f20d2419fbd497f8e36764robbiew				}
286045fd16a63837924a0f20d2419fbd497f8e36764robbiew			}
287f3a83d59cce260ab513313b2c43c41fc16983959robbiew		}
288d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
289d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
290d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/*
291d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Send the last packet to the child processes
2924bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
293d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * [ Upon receiving this packet, the child process will know that all
2944bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *   of the packets have been sent and that the parent process is
295d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *   expecting the child to send it's checksum back. ]
2964bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
297d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * After sending the last packet, close the WRITE end of the p2child
298d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * pipe as we are finish sending packets to the child processes.
2992c28215423293e443469a07ae7011135d058b671Garrett Cooper	 *
3004bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * Then wait for all of the child processes to send the checksum
3014bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * packets.  Upon receiving the checksum packets verify that the
3024bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * child's checksum matches that of the parent.
3034bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
3044bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * Might have to make several attempts with the NON-BLOCKING writes
305d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * if the resource is not immediately available.
3064bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
307d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Finally, close READ end of p2parent pipe as we have finished
308d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * receiving checksums from the child.
309d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
310d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	packet.last = 1;
311d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("\n\tParent: done sending packets & waiting for children to complete!\n");
312d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	for (i=0; i<num_children; i++) {
313d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		try_read_again:
314045fd16a63837924a0f20d2419fbd497f8e36764robbiew		if (write (p2child [i][WRITE], &packet, sizeof (packet)) < 0) {
315045fd16a63837924a0f20d2419fbd497f8e36764robbiew			if (non_blocking_flag && errno == EAGAIN) {
316d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				goto try_read_again;
317045fd16a63837924a0f20d2419fbd497f8e36764robbiew			} else {
318d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				sys_error ("write failed", __LINE__);
319045fd16a63837924a0f20d2419fbd497f8e36764robbiew			}
320045fd16a63837924a0f20d2419fbd497f8e36764robbiew		}
321d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if (close (p2child [i][WRITE]) < 0)
322d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			sys_error ("close failed", __LINE__);
3232c28215423293e443469a07ae7011135d058b671Garrett Cooper
324d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if (read (p2parent [READ], &packet, sizeof (packet)) <= 0)
325d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			sys_error ("read failed", __LINE__);
326d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
3274bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak		if (packet.valid != VALID_PACKET)
328d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			error ("received packet with corrupted data from child!",
329d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				__LINE__);
330d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
331d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if (cksum_parent != packet.checksum) {
332d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			sprintf (err_msg, "checksum of data sent by parent " \
333d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				"does not match checksum of data received by " \
334d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				"child [pid %d]\n"	\
335f3a83d59cce260ab513313b2c43c41fc16983959robbiew				"\tchild's checksum: %08lx\n" \
3364bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak				"\tparent's checksum: %08lx\n",
337d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				packet.pid, packet.checksum, cksum_parent);
338d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			error (err_msg, __LINE__);
339d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		}
340d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
341d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (close (p2parent [READ]) < 0)
342d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("close failed", __LINE__);
343d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
3444bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	/*
345d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Wait for all of the child processes to complete & check their
346d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * exit status.
347d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
348d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Upon completion of the child proccesses, exit program with success.
349d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
350d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	for (i=0; i<num_children; i++) {
351d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		waitpid (pid [i], &status, 0);
352d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
3534bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak		if (!WIFEXITED (status))
3544bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak			sys_error ("child process terminated abnormally",
355d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				__LINE__);
356d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
357d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("\n\tParent: children received all packets & exited successfully\n");
358d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
359d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/* Program completed successfully -- exit */
360d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("\nsuccessful!\n");
361d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
362d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	return (0);
363d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
364d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
365d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
366d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                               child ()                               |
367d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
368d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
369d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Receive packets from the parent, insure they are valid    |
370d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            and not out of sequence, and calculate a running          |
371d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            checksum.  Upon receiving the last packet from the        |
372d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            parent, build a checksum packet and send it to the parent.|
373d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
374d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Args:      p2child   - Pipe from parent to child                     |
375d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            p2parent  - Pipe from child to parent                     |
376d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
377d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Returns:   Exits with (-1) if an error occurs                        |
378d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
379d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
380d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid child (int p2child [], int p2parent [])
381d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
382d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	int	n;			/* Bytes read */
383d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	pid_t	pid = getpid ();	/* Process id of child */
3842c28215423293e443469a07ae7011135d058b671Garrett Cooper	int	end_of_transmission = 0;
3854bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	long	packets_received = 0;	/* Number of packets received
386d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj					 * from parent
387d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj					 */
388d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
389d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	data_packet 	packet;		/* Packet used to transmiting data */
390d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	unsigned long 	cksum_child = 0;/* Checksum of data fields received */
391d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
392d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/*
3934bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * Close the WRITE end of the p2child pipe, since the child
394d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * process will be reading from this pipe rather than writing.
3954bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * Also close the READ end of the p2parent pipe, for just the
396d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * the reverse reasons...
397d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
398d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (close (p2child [WRITE]) < 0)
399d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("close failed", __LINE__);
400d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (close (p2parent [READ]) < 0)
401d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("close failed", __LINE__);
402d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
403d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/*
404d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Receive packets from parent & insure packets are valid
4054bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
406d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Read packets from the parent through p2child pipe.  Upon
407d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * recieving the packet, verify that it is valid, in sequence
408d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * and that both the parent's and child's checksums match.
4094bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
410d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Might have to make several attempts with the NON-BLOCKING
411d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * reads if the resource is not immediately available.
4124bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
413d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Continue reading packets until the "last" packet is received
414d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * from the parent.  Upon receiving the last packet, close
415d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * the p2child READ pipe, as we are finished receiving packets
416d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * from the parent.
417d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
418d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	while (!end_of_transmission) {
419d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		try_write_again:
420d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		n = read (p2child [READ], &packet, sizeof (packet));
421d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if (n < 0) {
422d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			/* Resource not available */
423d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			if (non_blocking_flag && errno == EAGAIN)
424d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				goto try_write_again;
425d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			else
426d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				sys_error ("read failed", __LINE__);
427d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		} else if (n > 0) {
428d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			/* Insure packet is valid */
429d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			if (packet.valid != VALID_PACKET) {
4304bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak				sprintf (err_msg,
431d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj					"child received invalid packet " \
432f3a83d59cce260ab513313b2c43c41fc16983959robbiew					"from parent:\n\tpacket #: %ld\n",
433d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj					packets_received);
434d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				error (err_msg, __LINE__);
4354bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak			}
436d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			/* Received last packet */
437d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			if (packet.last) {
438d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				end_of_transmission = 1;
439d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			} else {
440d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
441d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				/* Insure packet was not received out of sequence */
442d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				packets_received++;
443d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				if (packets_received != packet.seq_number) {
444d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj					sprintf (err_msg,
445d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj						"child received packet out of sequence\n" \
446f3a83d59cce260ab513313b2c43c41fc16983959robbiew						"\texpecting packet: %ld\n" \
447f3a83d59cce260ab513313b2c43c41fc16983959robbiew						"\treceived packet:  %ld\n",
448d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj						packets_received, packet.seq_number);
449d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj					error (err_msg, __LINE__);
450d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				}
451d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
452d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				/* Insure checksums still match */
453d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				cksum_child += packet.data;
454d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				if (cksum_child != packet.checksum) {
455d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj					sprintf (err_msg,
456d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj						"child & parent checksums do not match\n" \
457f3a83d59cce260ab513313b2c43c41fc16983959robbiew						"\tchild checksum:  %08lx\n" \
458f3a83d59cce260ab513313b2c43c41fc16983959robbiew						"\tparent checksum: %08lx\n" \
459f3a83d59cce260ab513313b2c43c41fc16983959robbiew						"\tpacket number:   %ld\n",
460d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj						cksum_child, packet.checksum, packets_received);
461d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj					error (err_msg, __LINE__);
462d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				}
463d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			}
464d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		}
465d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
466d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (close (p2child [READ]) < 0)
467d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("close failed", __LINE__);
468d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
469d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/*
470d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Send parent packet containing child's checksum
4714bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
472d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Build a checksum packet (initialize packet fields) and then
473d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * send the packet to the parent.
4744bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 *
475d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Then close the WRITE p2parent pipe as we have finished sending packets
476d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * to the parent.
477d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
4784bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	printf ("\t\tChild:  pid [%d] received %ld packets from parent\n",
479d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		pid, packets_received);
480d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
481d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	packet.pid = pid;
482d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	packet.valid = VALID_PACKET;
483d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	packet.checksum = cksum_child;
484d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
485d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (write (p2parent [WRITE], &packet, sizeof (packet)) < 0)
486d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("write failed", __LINE__);
487d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (close (p2parent [WRITE]) < 0)
488d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("close failed", __LINE__);
489d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
490d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
491d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
492d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                               setup ()                               |
493d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
494d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
495d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Parse the command line arguments & initialize global      |
496d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            variables.                                                |
497d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
498d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Updates:   (command line options)                                    |
499d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
500d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            [-n] non_blocking_flag: prevents read & write calls from  |
501d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                 from blocking if the resource is not available.      |
502d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
503d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            [-p] num_packets: number of packets ...                   |
504d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
505d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            [-c] num_children: number of child processes to spawn ... |
506d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
507d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
508d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid setup (int argc, char **argv)
509d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
510d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	int	i;
511d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	int	errflag = 0;
512f3a83d59cce260ab513313b2c43c41fc16983959robbiew	int 	bytes = 0, megabytes = 0;
513d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	char	*program_name = *argv;
514d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	extern char 	*optarg;	/* Command line option */
515d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
516d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	while ((i = getopt(argc, argv, "nm:b:p:?")) != EOF) {
517d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		switch (i) {
518d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			case 'n':		/* NON-BLOCKING flag */
519d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				non_blocking_flag++;
520d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				break;
521d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			case 'm':		/* MB */
522d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				mflg++;
523d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				megabytes = atoi (optarg);
524d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				break;
525d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			case 'b':		/* bytes */
526d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				bflg++;
527d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				bytes = atoi (optarg);
528d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				break;
529d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			case 'p':		/* number of child procs */
530d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				num_children = atoi (optarg);
531d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				break;
532d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			case '?':
533d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				errflag++;
534d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				break;
535d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		}
536d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
537d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (mflg) {
538d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		num_packets = megabytes * MB / sizeof (struct data_packet);
539d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	} else if (bflg) {
540d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		num_packets = bytes / sizeof (struct data_packet);
541d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
542d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
543d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (num_packets == 0 || num_children == 0 || num_children > MAXCHILD)
544d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		errflag++;
545d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
546d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (errflag) {
547d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		fprintf (stderr, USAGE, program_name, MAXCHILD);
548d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		exit (2);
549d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
550d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/*
551d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Setup signal catching function for SIGPIPE & SIGINT, record
552d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * the process id of the parent and initialize the child process
553d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * id array.
554d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
555d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	setup_signal_handlers ();
556d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
557d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	parent_pid = getpid ();
558d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
559d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	for (i=0; i<num_children; i++) {
560d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		pid [i] = (pid_t)0;
561d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
562d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
563d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
564d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
565d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                          setup_handler ()                            |
566d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
567d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
568d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Setup the signal handler for SIGPIPE.                     |
569d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
570d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
571d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid setup_signal_handlers ()
572d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
573d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	struct sigaction invec;
574d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
575d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	invec.sa_handler = (void (*)(int)) handler;
576d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sigemptyset (&invec.sa_mask);
577d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	invec.sa_flags = 0;
578d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
579d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigaction (SIGINT, &invec, (struct sigaction *) NULL) < 0)
580d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigaction failed", __LINE__);
581d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
582d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigaction (SIGPIPE, &invec, (struct sigaction *) NULL) < 0)
583d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigaction failed", __LINE__);
584d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
585d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
586d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
587d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                             handler ()                               |
588d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
589d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
590d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Signal catching function for SIGPIPE signal.              |
591d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
592d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            o  SIGPIPE: Print message and abort program...            |
593d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
594d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            o  SIGINT:  Parent process calls cleanup, child processes |
595d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                        simply exit                                   |
596d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
597d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            o  Other:   Print message and abort program...            |
598d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
599d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
600d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid handler (int sig, int code, struct sigcontext *scp)
601d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
602d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	char 	msg [100];	/* Buffer for error message */
603d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
604d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sig == SIGPIPE) {
605d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		error ("wrote to pipe with closed read end", __LINE__);
606d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	} else if (sig == SIGINT) {
607d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if (getpid () == parent_pid) {
608d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
609d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			fprintf (stderr, "Received SIGINT -- cleaning up...\n");
610d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			fflush (stderr);
611d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
612d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			cleanup ();
613d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		}
6144bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak		else
615d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			exit (-1);
616d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	} else {
617d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sprintf (msg, "Received an unexpected signal (%d)", sig);
618d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		error (msg, __LINE__);
619d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
620d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
621d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
622d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
623d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                             cleanup ()                               |
624d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
625d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
626d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Closes all of the pipes, kills all of the child           |
627d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            processes and exits the program...                        |
628d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
629d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
630d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid cleanup ()
631d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
632d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	int i;
633d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
634d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (getpid () == parent_pid) {
635d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		for (i=0; i<num_children; i++) {
6364bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak			if (pid [i] > (pid_t)0 && kill (pid [i], SIGKILL) < 0)
637d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj				sys_error ("signal failed", __LINE__);
638d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
639d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			close (p2child [i][READ]);
640d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			close (p2child [i][WRITE]);
641d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			close (p2parent [READ]);
642d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			close (p2parent [WRITE]);
643d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		}
644d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
645d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
646d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	exit (-1);
647d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
648d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
649d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
650d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                             sys_error ()                             |
651d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
652d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
653d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Creates system error message and calls error ()           |
654d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
655d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
656d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid sys_error (const char *msg, int line)
657d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
658d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	char syserr_msg [256];
659d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
660d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sprintf (syserr_msg, "%s: %s\n", msg, strerror (errno));
661d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	error (syserr_msg, line);
662d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
663d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
664d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
665d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                               error ()                               |
666d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
667d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
668d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Prints out message and calls cleanup...                   |
669d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
670d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
671d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid error (const char *msg, int line)
672d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
673d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	fprintf (stderr, "ERROR [line: %d] %s\n", line, msg);
674d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	fflush (stderr);
675d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	cleanup ();
6762c28215423293e443469a07ae7011135d058b671Garrett Cooper}