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}