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