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 174548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 */ 111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid setup(int, char **); 112354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid child(int[], int[]); 113354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid cleanup(); 114354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid sys_error(const char *, int); 115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid error(const char *, int); 116354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid setup_signal_handlers(); 117354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid 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 { 140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pid_t pid; /* Child process id */ 141354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int last; /* Indicates last packet when set */ 142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao long valid; /* Insure packet was not garbled */ 143354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao long seq_number; /* Packet sequence number */ 144354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long checksum; /* Cumulative checksum so far */ 145354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned char data; /* Data sent in packet */ 146d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}; 147d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojtypedef struct data_packet data_packet; 148d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint num_children = DEFAULT_NUM_CHILDREN; 150354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaolong num_packets = DEFAULT_PACKETS_TO_SEND; 151354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint non_blocking_flag = 0; /* Uses NON-BLOCKING pipes when set */ 152354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint bflg = 0; /* Data quantity flag (MB) */ 153354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint mflg = 0; /* Data quantity flag (bytes) */ 154d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 155354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaopid_t parent_pid; /* Parent's process id */ 156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaopid_t pid[MAXCHILD]; /* Process id's of spawned processes */ 157354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint p2child[MAXCHILD][2]; /* Pipes from parent to child processes */ 158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint p2parent[2]; /* Pipe from child processes to parent */ 159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaochar 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+---------------------------------------------------------------------*/ 171354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint main(int argc, char **argv) 172d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{ 173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int i; 174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int n; /* Number of bytes written */ 175354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int status; /* Child's exit status */ 176354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao long packets_sent; 177354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned char data; 178354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long cksum_parent = 0; 179354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao data_packet packet; 180d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 181d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* 182d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Parse command line arguments, initialize global variables and 183d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * print program header 184d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */ 185354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao setup(argc, argv); 186354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("%s: IPC Pipe TestSuite program\n", *argv); 187354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 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 */ 202354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("\n\tCreating pipes...\n"); 203354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fflush(stdout); 204d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 205354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pipe(p2parent) < 0) 206354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("pipe failed", __LINE__); 207d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 208d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (non_blocking_flag) { 209354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("\n\tSending data NON-BLOCKING!\n"); 210354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fflush(stdout); 211d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 212d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 213354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; i < num_children; i++) { 214354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pipe(&p2child[i][0]) < 0) 215354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("pipe failed", __LINE__); 216d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (non_blocking_flag) { 217354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fcntl(p2child[i][READ], F_SETFL, O_NONBLOCK) < 0) 218354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("fcntl (O_NONBLOCK) failed", 219354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao __LINE__); 220354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fcntl(p2child[i][WRITE], F_SETFL, O_NONBLOCK) < 0) 221354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("fcntl (O_NONBLOCK) failed", 222354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao __LINE__); 223d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 224d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 225d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 226d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* 227d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Spawn num_children processes 2284bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 229d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Fork of the child process & record the newly created process's 2302c28215423293e443469a07ae7011135d058b671Garrett Cooper * id for future reference. 2312c28215423293e443469a07ae7011135d058b671Garrett Cooper * 2324bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * Then close the READ end of the p2child pipe, since the parent 233d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * process will be writing into this pipe rather than reading. 2344bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * Also close the WRITE end of the p2parent pipe, for just the 235d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * the reverse reasons... 236d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */ 237354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("\n\tSpawning %d child processes ... \n", num_children); 238354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fflush(stdout); 239d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 240354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; i < num_children; i++) { 241d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 242354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((pid[i] = fork()) == 0) { 243d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 244d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* Child process */ 245354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao child(&p2child[i][0], p2parent); 246354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(0); 247d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 248354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (pid[i] < (pid_t) 0) 249354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("fork failed", __LINE__); 250d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 251354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (close(p2child[i][READ]) < 0) 252354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("close failed", __LINE__); 253d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 254354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (close(p2parent[WRITE]) < 0) 255354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("close failed", __LINE__); 256d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 257d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* 258d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Send data packets to the child processes 2594bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 260d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Build packets (initialize all of the packets fields) and then 261d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * send the packets to all of the child processes. 2624bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 2634bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * Might have to make several attempts with the NON-BLOCKING writes 264d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * if the resource is not immediately available. 265d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */ 266354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 267354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("\n\tParent: sending %ld packets (%ld bytes) to child processes ...\n", 268354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao num_packets, num_packets * sizeof(struct data_packet)); 269d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 270d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packet.last = 0; 271d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packet.valid = VALID_PACKET; 272d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 273d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj for (packets_sent = data = 0; num_packets > 0; num_packets--) { 274d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 275d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packet.seq_number = ++packets_sent; 276d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packet.data = data++; 277354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao packet.pid = pid[i]; 278d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packet.checksum = cksum_parent += packet.data; 279d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 280354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; i < num_children; i++) { 281354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaotry_write_ETXN_again: 282354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((n = write(p2child[i][WRITE], &packet, 283354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(packet))) < 0) { 284045fd16a63837924a0f20d2419fbd497f8e36764robbiew if (non_blocking_flag && errno == EAGAIN) { 285d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj goto try_write_ETXN_again; 286045fd16a63837924a0f20d2419fbd497f8e36764robbiew } else { 287354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("write failed", __LINE__); 288045fd16a63837924a0f20d2419fbd497f8e36764robbiew } 289045fd16a63837924a0f20d2419fbd497f8e36764robbiew } 290f3a83d59cce260ab513313b2c43c41fc16983959robbiew } 291d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 292d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 293d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* 294d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Send the last packet to the child processes 2954bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 296d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * [ Upon receiving this packet, the child process will know that all 2974bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * of the packets have been sent and that the parent process is 298d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * expecting the child to send it's checksum back. ] 2994bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 300d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * After sending the last packet, close the WRITE end of the p2child 301d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * pipe as we are finish sending packets to the child processes. 3022c28215423293e443469a07ae7011135d058b671Garrett Cooper * 3034bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * Then wait for all of the child processes to send the checksum 3044bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * packets. Upon receiving the checksum packets verify that the 3054bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * child's checksum matches that of the parent. 3064bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 3074bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * Might have to make several attempts with the NON-BLOCKING writes 308d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * if the resource is not immediately available. 3094bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 310d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Finally, close READ end of p2parent pipe as we have finished 311d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * receiving checksums from the child. 312d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */ 313d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packet.last = 1; 314354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 315354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("\n\tParent: done sending packets & waiting for children to complete!\n"); 316354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; i < num_children; i++) { 317354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaotry_read_again: 318354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (write(p2child[i][WRITE], &packet, sizeof(packet)) < 0) { 319045fd16a63837924a0f20d2419fbd497f8e36764robbiew if (non_blocking_flag && errno == EAGAIN) { 320d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj goto try_read_again; 321045fd16a63837924a0f20d2419fbd497f8e36764robbiew } else { 322354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("write failed", __LINE__); 323045fd16a63837924a0f20d2419fbd497f8e36764robbiew } 324045fd16a63837924a0f20d2419fbd497f8e36764robbiew } 325354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (close(p2child[i][WRITE]) < 0) 326354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("close failed", __LINE__); 3272c28215423293e443469a07ae7011135d058b671Garrett Cooper 328354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (read(p2parent[READ], &packet, sizeof(packet)) <= 0) 329354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("read failed", __LINE__); 330d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 3314bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak if (packet.valid != VALID_PACKET) 332354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao error("received packet with corrupted data from child!", 333354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao __LINE__); 334d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 335d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (cksum_parent != packet.checksum) { 336354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sprintf(err_msg, "checksum of data sent by parent " 337354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "does not match checksum of data received by " 338354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "child [pid %d]\n" 339354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\tchild's checksum: %08lx\n" 3404bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak "\tparent's checksum: %08lx\n", 341d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packet.pid, packet.checksum, cksum_parent); 342354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao error(err_msg, __LINE__); 343d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 344d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 345354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (close(p2parent[READ]) < 0) 346354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("close failed", __LINE__); 347d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 3484bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak /* 349d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Wait for all of the child processes to complete & check their 350d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * exit status. 351d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * 352d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Upon completion of the child proccesses, exit program with success. 353d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */ 354354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; i < num_children; i++) { 355354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao waitpid(pid[i], &status, 0); 356d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 357354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!WIFEXITED(status)) 358354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("child process terminated abnormally", 359354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao __LINE__); 360d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 361354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 362354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("\n\tParent: children received all packets & exited successfully\n"); 363d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 364d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* Program completed successfully -- exit */ 365354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("\nsuccessful!\n"); 366d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 367d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj return (0); 368d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj} 369d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 370d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+ 371d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| child () | 372d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== | 373d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 374d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function: Receive packets from the parent, insure they are valid | 375d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| and not out of sequence, and calculate a running | 376d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| checksum. Upon receiving the last packet from the | 377d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| parent, build a checksum packet and send it to the parent.| 378d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 379d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Args: p2child - Pipe from parent to child | 380d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| p2parent - Pipe from child to parent | 381d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 382d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Returns: Exits with (-1) if an error occurs | 383d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 384d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/ 385354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid child(int p2child[], int p2parent[]) 386d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{ 387354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int n; /* Bytes read */ 388354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pid_t pid = getpid(); /* Process id of child */ 389354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int end_of_transmission = 0; 390354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao long packets_received = 0; /* Number of packets received 391d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * from parent 392d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */ 393d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 394354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao data_packet packet; /* Packet used to transmiting data */ 395354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long cksum_child = 0; /* Checksum of data fields received */ 396d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 397d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* 3984bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * Close the WRITE end of the p2child pipe, since the child 399d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * process will be reading from this pipe rather than writing. 4004bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * Also close the READ end of the p2parent pipe, for just the 401d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * the reverse reasons... 402d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */ 403354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (close(p2child[WRITE]) < 0) 404354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("close failed", __LINE__); 405354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (close(p2parent[READ]) < 0) 406354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("close failed", __LINE__); 407d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 408d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* 409d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Receive packets from parent & insure packets are valid 4104bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 411d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Read packets from the parent through p2child pipe. Upon 412d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * recieving the packet, verify that it is valid, in sequence 413d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * and that both the parent's and child's checksums match. 4144bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 415d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Might have to make several attempts with the NON-BLOCKING 416d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * reads if the resource is not immediately available. 4174bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 418d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Continue reading packets until the "last" packet is received 419d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * from the parent. Upon receiving the last packet, close 420d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * the p2child READ pipe, as we are finished receiving packets 421d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * from the parent. 422d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */ 423d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj while (!end_of_transmission) { 424354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaotry_write_again: 425354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao n = read(p2child[READ], &packet, sizeof(packet)); 426d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (n < 0) { 427d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* Resource not available */ 428d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (non_blocking_flag && errno == EAGAIN) 429d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj goto try_write_again; 430d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj else 431354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("read failed", __LINE__); 432d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } else if (n > 0) { 433d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* Insure packet is valid */ 434d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (packet.valid != VALID_PACKET) { 435354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sprintf(err_msg, 436354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "child received invalid packet " 437f3a83d59cce260ab513313b2c43c41fc16983959robbiew "from parent:\n\tpacket #: %ld\n", 438d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packets_received); 439354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao error(err_msg, __LINE__); 4404bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak } 441d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* Received last packet */ 442d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (packet.last) { 443d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj end_of_transmission = 1; 444d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } else { 445d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 446d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* Insure packet was not received out of sequence */ 447d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packets_received++; 448d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (packets_received != packet.seq_number) { 449354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sprintf(err_msg, 450354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "child received packet out of sequence\n" 451354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\texpecting packet: %ld\n" 452f3a83d59cce260ab513313b2c43c41fc16983959robbiew "\treceived packet: %ld\n", 453354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao packets_received, 454354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao packet.seq_number); 455354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao error(err_msg, __LINE__); 456d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 457d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 458d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* Insure checksums still match */ 459d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj cksum_child += packet.data; 460d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (cksum_child != packet.checksum) { 461354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sprintf(err_msg, 462354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "child & parent checksums do not match\n" 463354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\tchild checksum: %08lx\n" 464354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "\tparent checksum: %08lx\n" 465f3a83d59cce260ab513313b2c43c41fc16983959robbiew "\tpacket number: %ld\n", 466354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao cksum_child, packet.checksum, 467354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao packets_received); 468354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao error(err_msg, __LINE__); 469d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 470d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 471d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 472d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 473354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (close(p2child[READ]) < 0) 474354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("close failed", __LINE__); 475d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 476d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* 477d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Send parent packet containing child's checksum 4784bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 479d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Build a checksum packet (initialize packet fields) and then 480d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * send the packet to the parent. 4814bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * 482d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Then close the WRITE p2parent pipe as we have finished sending packets 483d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * to the parent. 484d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */ 485354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("\t\tChild: pid [%d] received %ld packets from parent\n", 486354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pid, packets_received); 487d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 488d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packet.pid = pid; 489d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packet.valid = VALID_PACKET; 490d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj packet.checksum = cksum_child; 491d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 492354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (write(p2parent[WRITE], &packet, sizeof(packet)) < 0) 493354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("write failed", __LINE__); 494354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (close(p2parent[WRITE]) < 0) 495354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("close failed", __LINE__); 496d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj} 497d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 498d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+ 499d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| setup () | 500d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== | 501d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 502d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function: Parse the command line arguments & initialize global | 503d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| variables. | 504d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 505d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Updates: (command line options) | 506d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 507d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| [-n] non_blocking_flag: prevents read & write calls from | 508d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| from blocking if the resource is not available. | 509d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 510d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| [-p] num_packets: number of packets ... | 511d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 512d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| [-c] num_children: number of child processes to spawn ... | 513d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 514d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/ 515354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid setup(int argc, char **argv) 516d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{ 517354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int i; 518354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int errflag = 0; 519354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int bytes = 0, megabytes = 0; 520354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *program_name = *argv; 521354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao extern char *optarg; /* Command line option */ 522d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 523d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj while ((i = getopt(argc, argv, "nm:b:p:?")) != EOF) { 524d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj switch (i) { 525354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'n': /* NON-BLOCKING flag */ 526354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao non_blocking_flag++; 527354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 528354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'm': /* MB */ 529354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao mflg++; 530354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao megabytes = atoi(optarg); 531354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 532354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'b': /* bytes */ 533354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bflg++; 534354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytes = atoi(optarg); 535354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 536354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'p': /* number of child procs */ 537354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao num_children = atoi(optarg); 538354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 539354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case '?': 540354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao errflag++; 541354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 542d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 543d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 544d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (mflg) { 545354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao num_packets = megabytes * MB / sizeof(struct data_packet); 546d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } else if (bflg) { 547354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao num_packets = bytes / sizeof(struct data_packet); 548d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 549d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 550d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (num_packets == 0 || num_children == 0 || num_children > MAXCHILD) 551d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj errflag++; 552d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 553d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (errflag) { 554354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, USAGE, program_name, MAXCHILD); 555354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(2); 556d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 557d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj /* 558d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * Setup signal catching function for SIGPIPE & SIGINT, record 559d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * the process id of the parent and initialize the child process 560d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj * id array. 561d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */ 562354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao setup_signal_handlers(); 563d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 564354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao parent_pid = getpid(); 565d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 566354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; i < num_children; i++) { 567354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pid[i] = (pid_t) 0; 568d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 569d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj} 570d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 571d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+ 572d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| setup_handler () | 573d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== | 574d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 575d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function: Setup the signal handler for SIGPIPE. | 576d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 577d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/ 578354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid setup_signal_handlers() 579d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{ 580d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj struct sigaction invec; 581d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 582354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao invec.sa_handler = (void (*)(int))handler; 583354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sigemptyset(&invec.sa_mask); 584d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj invec.sa_flags = 0; 585d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 586cf0d626fe6224db3c714843dc7007e9f81d94a80Cyril Hrubis if (sigaction(SIGINT, &invec, NULL) < 0) 587354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("sigaction failed", __LINE__); 588d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 589cf0d626fe6224db3c714843dc7007e9f81d94a80Cyril Hrubis if (sigaction(SIGPIPE, &invec, NULL) < 0) 590354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("sigaction failed", __LINE__); 591d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj} 592d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 593d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+ 594d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| handler () | 595d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== | 596d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 597d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function: Signal catching function for SIGPIPE signal. | 598d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 599d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| o SIGPIPE: Print message and abort program... | 600d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 601d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| o SIGINT: Parent process calls cleanup, child processes | 602d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| simply exit | 603d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 604d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| o Other: Print message and abort program... | 605d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 606d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/ 607354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid handler(int sig, int code, struct sigcontext *scp) 608d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{ 609354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char msg[100]; /* Buffer for error message */ 610d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 611d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj if (sig == SIGPIPE) { 612354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao error("wrote to pipe with closed read end", __LINE__); 613d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } else if (sig == SIGINT) { 614354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (getpid() == parent_pid) { 615d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 616354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Received SIGINT -- cleaning up...\n"); 617354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fflush(stderr); 618d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 619354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao cleanup(); 620354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else 621354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(-1); 622d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } else { 623354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sprintf(msg, "Received an unexpected signal (%d)", sig); 624354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao error(msg, __LINE__); 625d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 626d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj} 627d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 628d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+ 629d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| cleanup () | 630d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== | 631d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 632d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function: Closes all of the pipes, kills all of the child | 633d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| processes and exits the program... | 634d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 635d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/ 636354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid cleanup() 637d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{ 638d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj int i; 639d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 640354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (getpid() == parent_pid) { 641354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (i = 0; i < num_children; i++) { 642354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pid[i] > (pid_t) 0 && kill(pid[i], SIGKILL) < 0) 643354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sys_error("signal failed", __LINE__); 644d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 645354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao close(p2child[i][READ]); 646354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao close(p2child[i][WRITE]); 647354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao close(p2parent[READ]); 648354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao close(p2parent[WRITE]); 649d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 650d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj } 651d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 652354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(-1); 653d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj} 654d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 655d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+ 656d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| sys_error () | 657d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== | 658d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 659d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function: Creates system error message and calls error () | 660d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 661d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/ 662354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid sys_error(const char *msg, int line) 663d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{ 664354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char syserr_msg[256]; 665d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 666354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sprintf(syserr_msg, "%s: %s\n", msg, strerror(errno)); 667354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao error(syserr_msg, line); 668d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj} 669d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj 670d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+ 671d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| error () | 672d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== | 673d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 674d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function: Prints out message and calls cleanup... | 675d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| | 676d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/ 677354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid error(const char *msg, int line) 678d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{ 679354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "ERROR [line: %d] %s\n", line, msg); 680354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fflush(stderr); 681354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao cleanup(); 682ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman} 683