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