114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak/*
214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * This program is free software; you can redistribute it and/or modify it
514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * under the terms of version 2 of the GNU General Public License as
614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * published by the Free Software Foundation.
714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * This program is distributed in the hope that it would be useful, but
914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * WITHOUT ANY WARRANTY; without even the implied warranty of
1014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
1214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * Further, this software is distributed without any warranty that it is
1314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * free of the rightful claim of any third person regarding infringement
1414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * or the like.  Any license provided herein, whether implied or
1514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * otherwise, applies only to this software file.  Patent licenses, if
1614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * any, provided herein do not apply to combinations of this program with
1714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * other software, or any other product whatsoever.
1814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
1914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * You should have received a copy of the GNU General Public License along
20fed9641096e27f79a0f2d9adfe9839dd8d11dc0fWanlong Gao * with this program; if not, write the Free Software Foundation, Inc.,
21fed9641096e27f79a0f2d9adfe9839dd8d11dc0fWanlong Gao * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
2314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
2414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * Mountain View, CA  94043, or:
2514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
2614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * http://www.sgi.com
2714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
2814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * For further information regarding this notice, see:
2914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
3014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
3114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
3214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * Changelog:
331e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper *
3414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *	Added timer options: William Jay Huie, IBM
3514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *	01/27/03 - Added: Manoj Iyer, manjo@mail.utexas.edu
361e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper *			   - option '-p' (pretty printing)i to enabled formatted printing
3714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *			     of results.
3814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
3914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *	01/27/03 - Added: Manoj Iyer, manjo@mail.utexas.edu
4014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *			   - added code to print system information
4114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
4214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *	01/28/03 - Added: Manoj Iyer, manjo@mail.utexas.edu
4314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *			   - added code to print test exit value.
4414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
4514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *	01/29/03 - Added: Manoj Iyer, manjo@mail.utexas.edu
4614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *			   - added code supresses test start and test end tags.
4714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *
4814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak * 	07/22/07 - Added: Ricardo Salveti de Araujo, rsalveti@linux.vnet.ibm.com
4914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak *			   - added option to create a command file with all failed tests.
501e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper *
5114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak */
522b6cd80e5a3e207b519c2301375081f3e2e8a467yaberauneya/* $Id: ltp-pan.c,v 1.4 2009/10/15 18:45:55 yaberauneya Exp $ */
5314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
5414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#include <sys/param.h>
55a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper#include <sys/stat.h>
5614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#include <sys/times.h>
57a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper#include <sys/types.h>
5814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#include <sys/wait.h>
5914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#include <sys/utsname.h>
60a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper#include <errno.h>
61a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper#include <err.h>
62a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper#include <limits.h>
6380a305eac8dd2327dd838274dcf8891bcdf554f9Garrett Cooper#include <signal.h>
64a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper#include <stdlib.h>
65a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper#include <string.h>
66a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper#include <time.h>
6714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
6814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#include "splitstr.h"
6914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#include "zoolib.h"
706f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang#include "tst_res_flags.h"
7114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
7214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak/* One entry in the command line collection.  */
73354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostruct coll_entry {
74354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *name;		/* tag name */
75354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *cmdline;		/* command line */
76354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *pcnt_f;		/* location of %f in the command line args, flag */
77354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct coll_entry *next;
7814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak};
7914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
80354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostruct collection {
81354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int cnt;
82354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct coll_entry **ary;
8314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak};
8414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostruct tag_pgrp {
86354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int pgrp;
87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int stopping;
88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	time_t mystime;
89354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct coll_entry *cmd;
90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char output[PATH_MAX];
9114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak};
9214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostruct orphan_pgrp {
94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int pgrp;
95354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct orphan_pgrp *next;
9614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak};
9714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
9814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic pid_t run_child(struct coll_entry *colle, struct tag_pgrp *active,
99204924aa4ba0bf51195405a66d6cd8d32bd17b91Peng Haitao		       int quiet_mode, int *failcnt, int fmt_print,
100204924aa4ba0bf51195405a66d6cd8d32bd17b91Peng Haitao		       FILE * logfile);
10114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic char *slurp(char *file);
10214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic struct collection *get_collection(char *file, int optind, int argc,
10314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak					 char **argv);
10414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic void pids_running(struct tag_pgrp *running, int keep_active);
10514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic int check_pids(struct tag_pgrp *running, int *num_active,
1061e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper		      int keep_active, FILE * logfile, FILE * failcmdfile,
1075f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		      FILE *tconfcmdfile, struct orphan_pgrp *orphans,
1085f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		      int fmt_print, int *failcnt, int *tconfcnt,
1095f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		      int quiet_mode);
11014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic void propagate_signal(struct tag_pgrp *running, int keep_active,
11114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak			     struct orphan_pgrp *orphans);
11214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic void dump_coll(struct collection *coll);
11314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic char *subst_pcnt_f(struct coll_entry *colle);
11414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic void mark_orphan(struct orphan_pgrp *orphans, pid_t cpid);
11514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic void orphans_running(struct orphan_pgrp *orphans);
11614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic void check_orphans(struct orphan_pgrp *orphans, int sig);
1175c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak
11814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic void copy_buffered_output(struct tag_pgrp *running);
119f6b28b5171cad776d06ce3aa6110f1ad18c6eec7subrata_modakstatic void write_test_start(struct tag_pgrp *running);
120f6b28b5171cad776d06ce3aa6110f1ad18c6eec7subrata_modakstatic void write_test_end(struct tag_pgrp *running, const char *init_status,
12114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak			   time_t exit_time, char *term_type, int stat_loc,
12214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak			   int term_id, struct tms *tms1, struct tms *tms2);
12314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1245c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak//wjh
12514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic char PAN_STOP_FILE[] = "PAN_STOP_FILE";
12614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
12714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic char *panname = NULL;
12814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic char *test_out_dir = NULL;	/* dir to buffer output to */
12914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakzoo_t zoofile;
13014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakstatic char *reporttype = NULL;
13114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
13214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak/* zoolib */
133354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint rec_signal;			/* received signal */
134354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint send_signal;		/* signal to send */
13514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
13614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak/* Debug Bits */
13714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modakint Debug = 0;
13814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#define Dbuffile	0x000400	/* buffer file use */
13914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#define	Dsetup		0x000200	/* one-time set-up */
14014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#define	Dshutdown	0x000100	/* killed by signal */
14114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#define	Dexit		0x000020	/* exit status */
14214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#define	Drunning	0x000010	/* current pids running */
14314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#define	Dstartup	0x000004	/* started command */
14414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#define	Dstart		0x000002	/* started command */
14514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak#define Dwait		0x000001	/* wait interrupted */
14614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
147354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint main(int argc, char **argv)
14814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	extern char *optarg;
150354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	extern int optind;
151354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *zooname = NULL;	/* name of the zoo file to use */
152354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *filename = "/dev/null";	/* filename to read test tags from */
153354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *logfilename = NULL;
154354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *failcmdfilename = NULL;
1555f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang	char *tconfcmdfilename = NULL;
156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *outputfilename = NULL;
157354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct collection *coll = NULL;
158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct tag_pgrp *running;
159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct orphan_pgrp *orphans, *orph;
16014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	struct utsname unamebuf;
161354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	FILE *logfile = NULL;
162354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	FILE *failcmdfile = NULL;
1635f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang	FILE *tconfcmdfile = NULL;
164354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int keep_active = 1;
165354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int num_active = 0;
1666f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang	int failcnt = 0;  /* count of total testcases that failed. */
1676f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang	int tconfcnt = 0; /* count of total testcases that return TCONF */
168354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int err, i;
169354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int starts = -1;
170354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int timed = 0;
171354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int run_time = -1;
172354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char modifier = 'm';
173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int ret = 0;
174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int stop;
175354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int go_idle;
176354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int has_brakes = 0;	/* stop everything if a test case fails */
177354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int sequential = 0;	/* run tests sequentially */
178354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int fork_in_road = 0;
179354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int exit_stat;
180354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int track_exit_stats = 0;	/* exit non-zero if any test exits non-zero */
181354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int fmt_print = 0;	/* enables formatted printing of logfiles. */
182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int quiet_mode = 0;	/* supresses test start and test end tags. */
183354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int c;
184354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	pid_t cpid;
185354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct sigaction sa;
186354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
187354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while ((c =
1885f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		getopt(argc, argv, "AO:Sa:C:T:d:ef:hl:n:o:pqr:s:t:x:y"))
1895f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		       != -1) {
190354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		switch (c) {
191354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'A':	/* all-stop flag */
192354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			has_brakes = 1;
193354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			track_exit_stats = 1;
194354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
195354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'O':	/* output buffering directory */
196354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			test_out_dir = strdup(optarg);
197354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
198354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'S':	/* run tests sequentially */
199354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			sequential = 1;
200354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
201354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'a':	/* name of the zoo file to use */
202354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			zooname = strdup(optarg);
203354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
204354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'C':	/* name of the file where all failed commands will be */
205354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			failcmdfilename = strdup(optarg);
206354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
2075f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		case 'T':
2085f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang			/*
2095f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang			 * test cases that are not fully tested will be recorded
2105f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang			 * in this file
2115f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang			 */
2125f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang			tconfcmdfilename = strdup(optarg);
2135f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang			break;
214354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'd':	/* debug options */
215354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			sscanf(optarg, "%i", &Debug);
216354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
217354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'e':	/* exit non-zero if any test exists non-zero */
218354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			track_exit_stats = 1;
219354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
220354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'f':	/* filename to read test tags from */
221354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			filename = strdup(optarg);
222354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
223354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'h':	/* help */
224354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stdout,
225354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"Usage: pan -n name [ -SyAehpq ] [ -s starts ]"
226354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				" [-t time[s|m|h|d] [ -x nactive ] [ -l logfile ]\n\t"
227354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"[ -a active-file ] [ -f command-file ] "
228354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"[ -C fail-command-file ] "
229354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"[ -d debug-level ]\n\t[-o output-file] "
230354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"[-O output-buffer-directory] [cmd]\n");
231354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			exit(0);
232354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'l':	/* log file */
233354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			logfilename = strdup(optarg);
234354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
235354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'n':	/* tag given to pan */
236354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			panname = strdup(optarg);
237354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
238354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'o':	/* send test output here */
239354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			outputfilename = strdup(optarg);
240354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
241354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'p':	/* formatted printing. */
242354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fmt_print = 1;
243354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
244354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'q':	/* supress test start and test end messages */
245354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			quiet_mode = 1;
246354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
247354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'r':	/* reporting type: none, rts */
248354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			reporttype = strdup(optarg);
249354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
250354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 's':	/* number of tags to run */
251354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			starts = atoi(optarg);
252354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
253354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 't':	/* run_time to run */
254354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			ret = sscanf(optarg, "%d%c", &run_time, &modifier);
255354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (ret == 0) {
256354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr,
257354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					"Need proper time input: ####x where"
258354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					"x is one of s,m,h,d\n");
259354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				break;
260354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			} else if (ret == 1) {
261354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr, "Only got a time value of %d "
262354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					"modifiers need to come immediately after #"
263354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					" assuming %c\n", run_time, modifier);
264354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			} else {
265354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				switch (modifier) {
266354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				case 's':
267354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					run_time = run_time;
268354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					break;
269354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				case 'm':
270354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					run_time = run_time * 60;
271354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					break;
272354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				case 'h':
273354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					run_time = run_time * 60 * 60;
274354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					break;
275354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				case 'd':
276354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					run_time = run_time * 60 * 60 * 24;
277354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					break;
278354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				default:
279354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					fprintf(stderr,
280354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						"Invalid time modifier, try: s|h|m|d\n");
281354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					exit(-1);
282354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				}
283354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (!quiet_mode)
284354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					printf("PAN will run for %d seconds\n",
285354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					       run_time);
286354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
287354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			timed = 1;	//-t implies run as many starts as possible, by default
288354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
289354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'x':	/* number of tags to keep running */
290354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			keep_active = atoi(optarg);
291354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
292354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		case 'y':	/* restart on failure or signal */
293354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fork_in_road = 1;
294354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
295354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
296354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
297354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
298354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (panname == NULL) {
299354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan: Must supply -n\n");
300354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(1);
30114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
30214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	if (zooname == NULL) {
303354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		zooname = zoo_getname();
304354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (zooname == NULL) {
305354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr,
306354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"pan(%s): Must supply -a or set ZOO env variable\n",
307354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				panname);
308354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			exit(1);
309354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
31014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
311354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (reporttype) {
312354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* make sure we understand the report type */
313354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (strcasecmp(reporttype, "rts")
314354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    && strcasecmp(reporttype, "none")
315354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    /* && strcasecmp(reporttype, "xml") */
316354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    )
317354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			reporttype = "rts";
3185c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak	} else {
319354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* set the default */
320354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		reporttype = "rts";
321354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
322354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
323354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (logfilename != NULL) {
324354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		time_t startup;
325354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		char *s;
326354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
327354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (!strcmp(logfilename, "-")) {
328354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			logfile = stdout;
329354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else {
330354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if ((logfile = fopen(logfilename, "a+")) == NULL) {
331354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr,
332354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					"pan(%s): Error %s (%d) opening log file '%s'\n",
333354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					panname, strerror(errno), errno,
334354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					logfilename);
335354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				exit(1);
336354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
337354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
338354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
339354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		time(&startup);
340354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		s = ctime(&startup);
341354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		*(s + strlen(s) - 1) = '\0';
342354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (!fmt_print)
343354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(logfile, "startup='%s'\n", s);
344354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		else {
345354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(logfile, "Test Start Time: %s\n", s);
346354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(logfile,
347354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"-----------------------------------------\n");
348354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(logfile, "%-30.20s %-10.10s %-10.10s\n",
349354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"Testcase", "Result", "Exit Value");
350354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(logfile, "%-30.20s %-10.10s %-10.10s\n",
351354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"--------", "------", "------------");
352354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
353354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fflush(logfile);
354354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
355354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
356354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	coll = get_collection(filename, optind, argc, argv);
357354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (!coll)
358354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(1);
359354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (coll->cnt == 0) {
36014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		fprintf(stderr,
361354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			"pan(%s): Must supply a file collection or a command\n",
362354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			panname);
36314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		exit(1);
36414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
36514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
366354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (Debug & Dsetup)
367354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		dump_coll(coll);
368354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
369354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* a place to store the pgrps we're watching */
370354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	running =
3714ad5833caef77fb911da4f13bbd41187479228a5Maninder Singh		malloc((keep_active + 1) *
3724ad5833caef77fb911da4f13bbd41187479228a5Maninder Singh			sizeof(struct tag_pgrp));
373354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (running == NULL) {
374354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan(%s): Failed to allocate memory: %s\n",
375354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			panname, strerror(errno));
376354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(2);
37714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
378354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	memset(running, 0, keep_active * sizeof(struct tag_pgrp));
379354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	running[keep_active].pgrp = -1;	/* end sentinel */
380354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
381354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* a head to the orphaned pgrp list */
3824ad5833caef77fb911da4f13bbd41187479228a5Maninder Singh	orphans = malloc(sizeof(struct orphan_pgrp));
383354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	memset(orphans, 0, sizeof(struct orphan_pgrp));
384354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
385354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	srand48(time(NULL) ^ (getpid() + (getpid() << 15)));
386354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
387354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* Supply a default for starts.  If we are in sequential mode, use
388354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 * the number of commands available; otherwise 1.
389354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 */
390354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (timed == 1 && starts == -1) {	/* timed, infinite by default */
391354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		starts = -1;
392354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	} else if (starts == -1) {
393354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (sequential) {
394354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			starts = coll->cnt;
395354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else {
396354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			starts = 1;
397354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
398354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	} else if (starts == 0) {	/* if the user specified infinite, set it */
399354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		starts = -1;
400354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	} else {		/* else, make sure we are starting at least keep_active processes */
401354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (starts < keep_active)
402354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			starts = keep_active;
40314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
40414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
405354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* if we're buffering output, but we're only running on process at a time,
406354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 * then essentially "turn off buffering"
407354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 */
408354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (test_out_dir && (keep_active == 1)) {
409354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		free(test_out_dir);
410354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		test_out_dir = NULL;
41114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
412354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
413354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (test_out_dir) {
414354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		struct stat sbuf;
415354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
416354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (stat(test_out_dir, &sbuf) < 0) {
417354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr,
418354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"pan(%s): stat of -O arg '%s' failed.  errno: %d  %s\n",
419354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				panname, test_out_dir, errno, strerror(errno));
420354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			exit(1);
421354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
422354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (!S_ISDIR(sbuf.st_mode)) {
423354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr,
424354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"pan(%s): -O arg '%s' must be a directory.\n",
425354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				panname, test_out_dir);
426354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			exit(1);
427354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
428354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (access(test_out_dir, W_OK | R_OK | X_OK) < 0) {
429354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr,
430354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"pan(%s): permission denied on -O arg '%s'.  errno: %d  %s\n",
431354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				panname, test_out_dir, errno, strerror(errno));
432354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			exit(1);
433354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
43414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
435354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
436354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (outputfilename) {
437354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (!freopen(outputfilename, "a+", stdout)) {
438354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr,
439354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"pan(%s): Error %s (%d) opening output file '%s'\n",
440354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				panname, strerror(errno), errno,
441354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				outputfilename);
442354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			exit(1);
443354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
44414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
445354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
446354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (failcmdfilename) {
447354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (!(failcmdfile = fopen(failcmdfilename, "a+"))) {
448354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr,
449354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"pan(%s): Error %s (%d) opening fail cmd file '%s'\n",
450354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				panname, strerror(errno), errno,
451354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				failcmdfilename);
452354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			exit(1);
453354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
45414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
455354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
4565f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang	if (tconfcmdfilename) {
4575f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		tconfcmdfile = fopen(tconfcmdfilename, "a+");
4585f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		if (!tconfcmdfile) {
4595f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang			fprintf(stderr, "pan(%s): Error %s (%d) opening "
4605f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang				"tconf cmd file '%s'\n", panname,
4615f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang				strerror(errno), errno, tconfcmdfilename);
4625f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang			exit(1);
4635f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		}
4645f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang	}
4655f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang
466354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if ((zoofile = zoo_open(zooname)) == NULL) {
4675c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak		fprintf(stderr, "pan(%s): %s\n", panname, zoo_error);
46814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		exit(1);
46914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
470354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (zoo_mark_args(zoofile, getpid(), panname, argc, argv)) {
4715c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak		fprintf(stderr, "pan(%s): %s\n", panname, zoo_error);
47214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		exit(1);
47314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
47414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
475354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* Allocate N spaces for max-arg commands.
476354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 * this is an "active file cleanliness" thing
477354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 */
478354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
479354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		for (c = 0; c < keep_active; c++) {
480354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (zoo_mark_cmdline(zoofile, c, panname, "")) {
481354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr, "pan(%s): %s\n", panname,
482354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					zoo_error);
483354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				exit(1);
484354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
485354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
486354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		for (c = 0; c < keep_active; c++) {
487354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (zoo_clear(zoofile, c)) {
488354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr, "pan(%s): %s\n", panname,
489354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					zoo_error);
490354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				exit(1);
491354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
492354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
493354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
494354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
495354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	rec_signal = send_signal = 0;
496354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (run_time != -1) {
497354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		alarm(run_time);
498354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
49914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
500354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sigemptyset(&sa.sa_mask);
501354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sa.sa_flags = 0;
502354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sa.sa_handler = wait_handler;
503354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
504354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sigaction(SIGALRM, &sa, NULL);
505354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sigaction(SIGINT, &sa, NULL);
506354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sigaction(SIGTERM, &sa, NULL);
507354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sigaction(SIGHUP, &sa, NULL);
508354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sigaction(SIGUSR1, &sa, NULL);	/* ignore fork_in_road */
509354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sigaction(SIGUSR2, &sa, NULL);	/* stop the scheduler */
510354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
511354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	c = 0;			/* in this loop, c is the command index */
512354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	stop = 0;
513354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	exit_stat = 0;
514354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	go_idle = 0;
515354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while (1) {
516354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
517354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		while ((num_active < keep_active) && (starts != 0)) {
518354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (stop || rec_signal || go_idle)
519354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				break;
520354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
521354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (!sequential)
522354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				c = lrand48() % coll->cnt;
523354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
524354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			/* find a slot for the child */
525354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			for (i = 0; i < keep_active; ++i) {
526354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (running[i].pgrp == 0)
527354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					break;
528354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
529354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (i == keep_active) {
530354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr,
531354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					"pan(%s): Aborting: i == keep_active = %d\n",
532354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					panname, i);
533354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				wait_handler(SIGINT);
534354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				exit_stat++;
535354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				break;
536354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
53714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
538354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			cpid =
539354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			    run_child(coll->ary[c], running + i, quiet_mode,
540354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				      &failcnt, fmt_print, logfile);
541354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (cpid != -1)
542354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				++num_active;
543354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if ((cpid != -1 || sequential) && starts > 0)
544354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				--starts;
54514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
546354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (sequential)
547354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (++c >= coll->cnt)
548354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					c = 0;
54914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
550354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}		/* while ((num_active < keep_active) && (starts != 0)) */
55114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
552354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (starts == 0) {
553354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (!quiet_mode)
554354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				printf("incrementing stop\n");
555354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			++stop;
556354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else if (starts == -1)	//wjh
557354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		{
558354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			FILE *f = (FILE *) - 1;
559354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if ((f = fopen(PAN_STOP_FILE, "r")) != 0) {
560354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				printf("Got %s Stopping!\n", PAN_STOP_FILE);
561354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fclose(f);
562354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				unlink(PAN_STOP_FILE);
563354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				stop++;
564354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
565354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
56614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
567354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (rec_signal) {
568354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			/* propagate everything except sigusr2 */
569354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
570354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (rec_signal == SIGUSR2) {
571354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (fork_in_road)
572354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					++go_idle;
573354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				else
574354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					++stop;
575354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				rec_signal = send_signal = 0;
576354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			} else {
577354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (rec_signal == SIGUSR1)
578354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					fork_in_road = 0;
579354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				propagate_signal(running, keep_active, orphans);
580354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (fork_in_road)
581354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					++go_idle;
582354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				else
583354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					++stop;
584354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
585354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
58614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
587354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		err = check_pids(running, &num_active, keep_active, logfile,
5885f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang				 failcmdfile, tconfcmdfile, orphans, fmt_print,
5895f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang				 &failcnt, &tconfcnt, quiet_mode);
590354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (Debug & Drunning) {
591354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			pids_running(running, keep_active);
592354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			orphans_running(orphans);
593354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
594354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (err) {
595354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (fork_in_road)
596354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				++go_idle;
597354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (track_exit_stats)
598354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				exit_stat++;
599354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (has_brakes) {
600354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr, "pan(%s): All stop!%s\n",
601354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					panname, go_idle ? " (idling)" : "");
602354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				wait_handler(SIGINT);
603354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
604354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
60514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
606354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (stop && (num_active == 0))
607354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
60814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
609354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (go_idle && (num_active == 0)) {
610354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			go_idle = 0;	/* It is idle, now resume scheduling. */
611354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			wait_handler(0);	/* Reset the signal ratchet. */
612354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
61314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
61414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
615354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* Wait for orphaned pgrps */
616354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while (1) {
617354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		for (orph = orphans; orph != NULL; orph = orph->next) {
618354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (orph->pgrp == 0)
619354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				continue;
620354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			/* Yes, we have orphaned pgrps */
621354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			sleep(5);
622354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (!rec_signal) {
623354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				/* force an artificial signal, move us
624354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 * through the signal ratchet.
625354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 */
626354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				wait_handler(SIGINT);
627354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
628354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			propagate_signal(running, keep_active, orphans);
629354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (Debug & Drunning)
630354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				orphans_running(orphans);
631354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
632354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
633354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (orph == NULL)
634354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
63514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
63614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
637354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (zoo_clear(zoofile, getpid())) {
638354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan(%s): %s\n", panname, zoo_error);
639354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		++exit_stat;
6405c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak	}
641354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	fclose(zoofile);
642354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (logfile && fmt_print) {
64314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		if (uname(&unamebuf) == -1)
644354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr, "ERROR: uname(): %s\n",
645354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				strerror(errno));
646354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(logfile,
647354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			"\n-----------------------------------------------\n");
64814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		fprintf(logfile, "Total Tests: %d\n", coll->cnt);
6496f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang		fprintf(logfile, "Total Skipped Tests: %d\n", tconfcnt);
65014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		fprintf(logfile, "Total Failures: %d\n", failcnt);
65114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		fprintf(logfile, "Kernel Version: %s\n", unamebuf.release);
652354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(logfile, "Machine Architecture: %s\n",
653354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			unamebuf.machine);
65414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		fprintf(logfile, "Hostname: %s\n\n", unamebuf.nodename);
65514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
656354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (logfile && (logfile != stdout))
657354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fclose(logfile);
65814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
6595f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang	if (failcmdfile)
6605f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		fclose(failcmdfile);
6615f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang
6625f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang	if (tconfcmdfile)
6635f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang		fclose(tconfcmdfile);
664354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	exit(exit_stat);
66514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
66614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
6675c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modakstatic void
6685c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modakpropagate_signal(struct tag_pgrp *running, int keep_active,
6695c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak		 struct orphan_pgrp *orphans)
67014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
671354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int i;
67214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
673354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (Debug & Dshutdown)
674354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan was signaled with sig %d...\n",
675354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			rec_signal);
67614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
677354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (rec_signal == SIGALRM) {
678354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		printf("PAN stop Alarm was received\n");
679354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		rec_signal = SIGTERM;
680354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
68114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
682354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (i = 0; i < keep_active; ++i) {
683354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (running[i].pgrp == 0)
684354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			continue;
68514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
686354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (Debug & Dshutdown)
687354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr, "  propagating sig %d to %d\n",
688354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				send_signal, -running[i].pgrp);
689354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (kill(-running[i].pgrp, send_signal) != 0) {
690354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr,
691354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"pan(%s): kill(%d,%d) failed on tag (%s).  errno:%d  %s\n",
692354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				panname, -running[i].pgrp, send_signal,
693354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				running[i].cmd->name, errno, strerror(errno));
694354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
695354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		running[i].stopping = 1;
69614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
69714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
698354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	check_orphans(orphans, send_signal);
69914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
700354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	rec_signal = send_signal = 0;
70114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
70214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
7035c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modakstatic int
7045c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modakcheck_pids(struct tag_pgrp *running, int *num_active, int keep_active,
7055f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang	   FILE *logfile, FILE *failcmdfile, FILE *tconfcmdfile,
7065f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang	   struct orphan_pgrp *orphans, int fmt_print, int *failcnt,
7075f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang	   int *tconfcnt, int quiet_mode)
70814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
709354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int w;
710354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	pid_t cpid;
711354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int stat_loc;
712354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int ret = 0;
713354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int i;
714354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	time_t t;
715354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *status;
7166f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang	char *result_str;
717354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int signaled = 0;
718354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct tms tms1, tms2;
719354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	clock_t tck;
720354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
721354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	check_orphans(orphans, 0);
722354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
723354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	tck = times(&tms1);
724354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (tck == -1) {
725354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan(%s): times(&tms1) failed.  errno:%d  %s\n",
726354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			panname, errno, strerror(errno));
7275c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak	}
728354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	cpid = wait(&stat_loc);
729354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	tck = times(&tms2);
730354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (tck == -1) {
731354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan(%s): times(&tms2) failed.  errno:%d  %s\n",
732354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			panname, errno, strerror(errno));
73314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
73414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
735354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (cpid < 0) {
736354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (errno == EINTR) {
737354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (Debug)
738354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr, "pan(%s): wait() interrupted\n",
739354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					panname);
740354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else if (errno != ECHILD) {
74114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak			fprintf(stderr,
742354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"pan(%s): wait() failed.  errno:%d  %s\n",
743354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				panname, errno, strerror(errno));
74414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		}
745354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	} else if (cpid > 0) {
746354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
747354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (WIFSIGNALED(stat_loc)) {
748354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			w = WTERMSIG(stat_loc);
749354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			status = "signaled";
750354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (Debug & Dexit)
751354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr,
752354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					"child %d terminated with signal %d\n",
753354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					cpid, w);
754354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			--*num_active;
755354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			signaled = 1;
756354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else if (WIFEXITED(stat_loc)) {
757354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			w = WEXITSTATUS(stat_loc);
758354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			status = "exited";
759354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (Debug & Dexit)
760354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr,
761354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					"child %d exited with status %d\n",
762354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					cpid, w);
763354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			--*num_active;
7646f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang			if (w != 0 && w != TCONF)
765354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				ret++;
766354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else if (WIFSTOPPED(stat_loc)) {	/* should never happen */
767354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			w = WSTOPSIG(stat_loc);
768354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			status = "stopped";
769354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			ret++;
770354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else {	/* should never happen */
771354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			w = 0;
772354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			status = "unknown";
773354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			ret++;
77414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		}
77514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
776354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		for (i = 0; i < keep_active; ++i) {
777354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (running[i].pgrp == cpid) {
778354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if ((w == 130) && running[i].stopping &&
779354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				    (strcmp(status, "exited") == 0)) {
780354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					/* The child received sigint, but
781354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					 * did not trap for it?  Compensate
782354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					 * for it here.
783354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					 */
784354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					w = 0;
785354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					ret--;	/* undo */
786354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					if (Debug & Drunning)
787354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						fprintf(stderr,
788354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							"pan(%s): tag=%s exited 130, known to be signaled; will give it an exit 0.\n",
789354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							panname,
790354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							running[i].cmd->name);
791354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				}
792354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				time(&t);
793354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (logfile != NULL) {
794354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					if (!fmt_print)
795354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						fprintf(logfile,
796354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							"tag=%s stime=%d dur=%d exit=%s stat=%d core=%s cu=%d cs=%d\n",
797354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							running[i].cmd->name,
798354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							(int)(running[i].
799354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							      mystime),
800354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							(int)(t -
801354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							      running[i].
802354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							      mystime), status,
803354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							w,
804354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							(stat_loc & 0200) ?
805354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							"yes" : "no",
806354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							(int)(tms2.tms_cutime -
807354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							      tms1.tms_cutime),
808354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							(int)(tms2.tms_cstime -
809354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							      tms1.tms_cstime));
810354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					else {
8116f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang						if (strcmp(status, "exited") ==
8126f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang						    0 && w == TCONF) {
8136f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang							++*tconfcnt;
8146f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang							result_str = "CONF";
8156f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang						} else if (w != 0) {
8166f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang							++*failcnt;
8176f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang							result_str = "FAIL";
8186f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang						} else {
8196f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang							result_str = "PASS";
8206f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang						}
8216f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang
822354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						fprintf(logfile,
823354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							"%-30.30s %-10.10s %-5d\n",
824354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							running[i].cmd->name,
8256f6878f4e1406d79cae53564777c5e1245d2a124Xiaoguang Wang							result_str,
826354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							w);
827354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					}
828354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
829354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					fflush(logfile);
830354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				}
831354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
8325f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang				if (w != 0) {
8335f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang					if (tconfcmdfile != NULL &&
8345f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang					    w == TCONF) {
8355f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang						fprintf(tconfcmdfile, "%s %s\n",
8365f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang						running[i].cmd->name,
8375f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang						running[i].cmd->cmdline);
8385f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang					} else if (failcmdfile != NULL) {
8395f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang						fprintf(failcmdfile, "%s %s\n",
840354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						running[i].cmd->name,
841354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						running[i].cmd->cmdline);
8425f71cf97d5753c5506cdf8287812f28e2fffe4aaXiaoguang Wang					}
843354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				}
844354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
845354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (running[i].stopping)
846354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					status = "driver_interrupt";
847354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
848354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (test_out_dir) {
849354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					if (!quiet_mode)
850354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						write_test_start(running + i);
851354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					copy_buffered_output(running + i);
852354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					unlink(running[i].output);
853354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				}
854354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (!quiet_mode)
855354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					write_test_end(running + i, "ok", t,
856354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						       status, stat_loc, w,
857354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						       &tms1, &tms2);
858354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
859354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				/* If signaled and we weren't expecting
860354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 * this to be stopped then the proc
861354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 * had a problem.
862354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 */
863354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (signaled && !running[i].stopping)
864354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					ret++;
865354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
866354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				running[i].pgrp = 0;
867354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (zoo_clear(zoofile, cpid)) {
868354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					fprintf(stderr, "pan(%s): %s\n",
869354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						panname, zoo_error);
870354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					exit(1);
871354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				}
872354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
873354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				/* Check for orphaned pgrps */
874354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if ((kill(-cpid, 0) == 0) || (errno == EPERM)) {
875354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					if (zoo_mark_cmdline
876354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					    (zoofile, cpid, "panorphan",
877354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					     running[i].cmd->cmdline)) {
878354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						fprintf(stderr, "pan(%s): %s\n",
879354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao							panname, zoo_error);
880354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						exit(1);
881354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					}
882354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					mark_orphan(orphans, cpid);
883354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					/* status of kill doesn't matter */
884354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					kill(-cpid, SIGTERM);
885354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				}
886354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
887354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				break;
888354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
8895c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak		}
8905c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak	}
891354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return ret;
8925c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak}
89314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
8945c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modakstatic pid_t
895204924aa4ba0bf51195405a66d6cd8d32bd17b91Peng Haitaorun_child(struct coll_entry *colle, struct tag_pgrp *active, int quiet_mode,
896204924aa4ba0bf51195405a66d6cd8d32bd17b91Peng Haitao	  int *failcnt, int fmt_print, FILE * logfile)
8975c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak{
898354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	ssize_t errlen;
899354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int cpid;
900354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int c_stdout = -1;	/* child's stdout, stderr */
901354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int capturing = 0;	/* output is going to a file instead of stdout */
902354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *c_cmdline;
903354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	static long cmdno = 0;
904354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int errpipe[2];		/* way to communicate to parent that the tag  */
905354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char errbuf[1024];	/* didn't actually start */
906354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
907354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* Try to open the file that will be stdout for the test */
908354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (test_out_dir) {
909354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		capturing = 1;
910354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		do {
911354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			sprintf(active->output, "%s/%s.%ld",
912354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				test_out_dir, colle->name, cmdno++);
913354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			c_stdout =
914354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			    open(active->output,
915354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 O_CREAT | O_RDWR | O_EXCL | O_SYNC, 0666);
916354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} while (c_stdout < 0 && errno == EEXIST);
917354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (c_stdout < 0) {
918354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr,
919354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"pan(%s): open of stdout file failed (tag %s).  errno: %d  %s\n  file: %s\n",
920354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				panname, colle->name, errno, strerror(errno),
921354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				active->output);
922354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			return -1;
923354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
9245c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak	}
925354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
926354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* get the tag's command line arguments ready.  subst_pcnt_f() uses a
927354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 * static counter, that's why we do it here instead of after we fork.
928354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 */
929354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (colle->pcnt_f) {
930354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		c_cmdline = subst_pcnt_f(colle);
931354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	} else {
932354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		c_cmdline = colle->cmdline;
933354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
934354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
935354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (pipe(errpipe) < 0) {
936354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan(%s): pipe() failed. errno:%d %s\n",
9375c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak			panname, errno, strerror(errno));
938354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (capturing) {
939354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			close(c_stdout);
940354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			unlink(active->output);
941354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
942354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return -1;
943354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
94414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
945354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	time(&active->mystime);
946354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	active->cmd = colle;
94714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
948354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (!test_out_dir)
949354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (!quiet_mode)
950354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			write_test_start(active);
951354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
9528bdf4010f8588358ccd2a5d100f9b02bf763dd39Cyril Hrubis	fflush(NULL);
9538bdf4010f8588358ccd2a5d100f9b02bf763dd39Cyril Hrubis
954354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if ((cpid = fork()) == -1) {
955354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr,
956354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			"pan(%s): fork failed (tag %s).  errno:%d  %s\n",
957354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			panname, colle->name, errno, strerror(errno));
958354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (capturing) {
959354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			unlink(active->output);
960354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			close(c_stdout);
961354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
962354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		close(errpipe[0]);
963354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		close(errpipe[1]);
964354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return -1;
965354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	} else if (cpid == 0) {
966354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* child */
967354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
968354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fclose(zoofile);
969354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		close(errpipe[0]);
970354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fcntl(errpipe[1], F_SETFD, 1);	/* close the pipe if we succeed */
971354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		setpgrp();
972354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
973354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		umask(0);
97414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
975a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper#define WRITE_OR_DIE(fd, buf, buflen) do {				\
976a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper	if (write((fd), (buf), (buflen)) != (buflen)) {			\
977a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper		err(1, "failed to write out %zd bytes at line %d",	\
978a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper		    buflen, __LINE__);					\
979a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper	}								\
980a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper} while(0)
981a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper
982354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* if we're putting output into a buffer file, we need to do the
983354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 * redirection now.  If we fail
984354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 */
985354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (capturing) {
986354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (dup2(c_stdout, fileno(stdout)) == -1) {
987354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				errlen =
988354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				    sprintf(errbuf,
989354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					    "pan(%s): couldn't redirect stdout for tag %s.  errno:%d  %s",
990354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					    panname, colle->name, errno,
991354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					    strerror(errno));
992354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				WRITE_OR_DIE(errpipe[1], &errlen,
993354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					     sizeof(errlen));
994354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				WRITE_OR_DIE(errpipe[1], errbuf, errlen);
995354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				exit(2);
996354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
997354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (dup2(c_stdout, fileno(stderr)) == -1) {
998354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				errlen =
999354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				    sprintf(errbuf,
1000354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					    "pan(%s): couldn't redirect stderr for tag %s.  errno:%d  %s",
1001354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					    panname, colle->name, errno,
1002354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					    strerror(errno));
1003354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				WRITE_OR_DIE(errpipe[1], &errlen,
1004354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					     sizeof(errlen));
1005354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				WRITE_OR_DIE(errpipe[1], errbuf, errlen);
1006354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				exit(2);
1007354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
1008354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else {	/* stderr still needs to be redirected */
1009354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (dup2(fileno(stdout), fileno(stderr)) == -1) {
1010354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				errlen =
1011354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				    sprintf(errbuf,
1012354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					    "pan(%s): couldn't redirect stderr for tag %s.  errno:%d  %s",
1013354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					    panname, colle->name, errno,
1014354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					    strerror(errno));
1015354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				WRITE_OR_DIE(errpipe[1], &errlen,
1016354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					     sizeof(errlen));
1017354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				WRITE_OR_DIE(errpipe[1], errbuf, errlen);
1018354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				exit(2);
1019354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
1020354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1021354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* If there are any shell-type characters in the cmdline
1022354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 * such as '>', '<', '$', '|', etc, then we exec a shell and
1023354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 * run the cmd under a shell.
1024354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 *
1025354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 * Otherwise, break the cmdline at white space and exec the
1026354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 * cmd directly.
1027354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 */
1028354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (strpbrk(c_cmdline, "\"';|<>$\\")) {
10294e2bab8415bfd5ddd552220203ed22c93a4617e5Cyril Hrubis			execlp("sh", "sh", "-c", c_cmdline, NULL);
1030354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			errlen = sprintf(errbuf,
1031354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					 "pan(%s): execlp of '%s' (tag %s) failed.  errno:%d %s",
1032354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					 panname, c_cmdline, colle->name, errno,
1033354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					 strerror(errno));
1034354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else {
1035354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			char **arg_v;
1036354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1037354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			arg_v = (char **)splitstr(c_cmdline, NULL, NULL);
1038354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1039354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			execvp(arg_v[0], arg_v);
1040354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			errlen = sprintf(errbuf,
1041354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					 "pan(%s): execvp of '%s' (tag %s) failed.  errno:%d  %s",
1042354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					 panname, arg_v[0], colle->name, errno,
1043354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					 strerror(errno));
1044354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1045a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper		WRITE_OR_DIE(errpipe[1], &errlen, sizeof(errlen));
1046a0ac15987eb3f0687376ccc52ca2fd232847d500Garrett Cooper		WRITE_OR_DIE(errpipe[1], errbuf, errlen);
1047354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(errno);
10485c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak	}
1049354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1050354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* parent */
1051354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1052354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* subst_pcnt_f() allocates the command line dynamically
1053354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 * free the malloc to prevent a memory leak
10545c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak	 */
1055354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (colle->pcnt_f)
1056354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		free(c_cmdline);
10575c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak
1058354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	close(errpipe[1]);
10591e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper
1060354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* if the child couldn't go through with the exec,
1061354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 * clean up the mess, note it, and move on
1062354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 */
1063354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (read(errpipe[0], &errlen, sizeof(errlen))) {
1064354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		int status;
1065354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		time_t end_time;
1066354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		int termid;
1067354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		char *termtype;
1068354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		struct tms notime = { 0, 0, 0, 0 };
1069354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
10704d1098948f8fb0581bfdad8cfbf80337c133272cXiaoguang Wang		if (read(errpipe[0], errbuf, errlen) < 0)
10714d1098948f8fb0581bfdad8cfbf80337c133272cXiaoguang Wang			fprintf(stderr, "Failed to read from errpipe[0]\n");
1072354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		close(errpipe[0]);
1073354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		errbuf[errlen] = '\0';
1074354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* fprintf(stderr, "%s", errbuf); */
1075354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		waitpid(cpid, &status, 0);
1076354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (WIFSIGNALED(status)) {
1077354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			termid = WTERMSIG(status);
1078354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			termtype = "signaled";
1079354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else if (WIFEXITED(status)) {
1080354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			termid = WEXITSTATUS(status);
1081354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			termtype = "exited";
1082354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		} else if (WIFSTOPPED(status)) {
1083354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			termid = WSTOPSIG(status);
1084354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			termtype = "stopped";
1085204924aa4ba0bf51195405a66d6cd8d32bd17b91Peng Haitao		} else {
1086354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			termid = 0;
1087354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			termtype = "unknown";
1088354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1089354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		time(&end_time);
1090354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (logfile != NULL) {
1091354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (!fmt_print) {
1092354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(logfile,
1093354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					"tag=%s stime=%d dur=%d exit=%s "
1094354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					"stat=%d core=%s cu=%d cs=%d\n",
1095354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					colle->name, (int)(active->mystime),
1096354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					(int)(end_time - active->mystime),
1097354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					termtype, termid,
1098354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					(status & 0200) ? "yes" : "no", 0, 0);
1099354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			} else {
1100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (termid != 0)
1101354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					++ * failcnt;
1102354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1103354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(logfile, "%-30.30s %-10.10s %-5d\n",
1104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					colle->name,
1105354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					((termid != 0) ? "FAIL" : "PASS"),
1106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					termid);
1107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
1108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fflush(logfile);
1109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1110204924aa4ba0bf51195405a66d6cd8d32bd17b91Peng Haitao
1111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (!quiet_mode) {
1112354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			//write_test_start(active, errbuf);
1113354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			write_test_end(active, errbuf, end_time, termtype,
1114354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				       status, termid, &notime, &notime);
1115204924aa4ba0bf51195405a66d6cd8d32bd17b91Peng Haitao		}
1116354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (capturing) {
1117354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			close(c_stdout);
1118354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			unlink(active->output);
1119354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1120354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return -1;
1121204924aa4ba0bf51195405a66d6cd8d32bd17b91Peng Haitao	}
1122204924aa4ba0bf51195405a66d6cd8d32bd17b91Peng Haitao
1123354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	close(errpipe[0]);
11245c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak	if (capturing)
1125354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		close(c_stdout);
112614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1127354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	active->pgrp = cpid;
1128354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	active->stopping = 0;
1129354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (zoo_mark_cmdline(zoofile, cpid, colle->name, colle->cmdline)) {
1131354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan(%s): %s\n", panname, zoo_error);
1132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(1);
1133354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
113414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (Debug & Dstartup)
1136354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "started %s cpid=%d at %s",
1137354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			colle->name, cpid, ctime(&active->mystime));
113814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1139354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (Debug & Dstart) {
1140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "Executing test = %s as %s", colle->name,
1141354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			colle->cmdline);
1142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (capturing)
1143354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr, "with output file = %s\n",
1144354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				active->output);
1145354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		else
1146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr, "\n");
1147354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1148354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return cpid;
1150354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao}
1151354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1152354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic char *subst_pcnt_f(struct coll_entry *colle)
115314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1154354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	static int counter = 1;
1155354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char pid_and_counter[20];
1156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char new_cmdline[1024];
115714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* if we get called falsely, do the right thing anyway */
1159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (!colle->pcnt_f)
1160354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return colle->cmdline;
116114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1162354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	snprintf(pid_and_counter, 20, "%d_%d", getpid(), counter++);
1163354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	snprintf(new_cmdline, 1024, colle->cmdline, pid_and_counter);
1164354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return strdup(new_cmdline);
116514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
116614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1167354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic struct collection *get_collection(char *file, int optind, int argc,
1168354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					 char **argv)
116914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1170354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *buf, *a, *b;
1171354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct coll_entry *head, *p, *n;
1172354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct collection *coll;
1173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int i;
1174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1175354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	buf = slurp(file);
1176354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (!buf)
1177354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return NULL;
1178354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
11794ad5833caef77fb911da4f13bbd41187479228a5Maninder Singh	coll = malloc(sizeof(struct collection));
1180354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	coll->cnt = 0;
1181354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	head = p = n = NULL;
1183354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	a = b = buf;
1184354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while (a) {
1185354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* set b to the start of the next line and add a NULL character
1186354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 * to separate the two lines */
1187354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if ((b = strchr(a, '\n')) != NULL)
1188354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			*b++ = '\0';
1189354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1190354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* If this is line isn't a comment */
1191354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if ((*a != '#') && (*a != '\0') && (*a != ' ')) {
11924ad5833caef77fb911da4f13bbd41187479228a5Maninder Singh			n = malloc(sizeof(struct coll_entry));
1193354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if ((n->pcnt_f = strstr(a, "%f"))) {
1194354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				n->pcnt_f[1] = 's';
1195354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
1196354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			n->name = strdup(strsep(&a, " \t"));
1197354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			n->cmdline = strdup(a);
1198354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			n->next = NULL;
1199354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1200354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (p) {
1201354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				p->next = n;
1202354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
1203354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (head == NULL) {
1204354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				head = n;
1205354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
1206354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			p = n;
1207354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			coll->cnt++;
1208354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1209354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		a = b;
121014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
1211354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	free(buf);
1212354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1213354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* is there something on the commandline to be counted? */
1214354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (optind < argc) {
1215354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		char workstr[1024] = "";
1216354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		int workstr_left = 1023;
1217354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1218354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* fill arg list */
1219354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		for (i = 0; optind < argc; ++optind, ++i) {
1220354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			strncat(workstr, argv[optind], workstr_left);
1221354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			workstr_left = workstr_left - strlen(argv[optind]);
1222354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			strncat(workstr, " ", workstr_left);
1223354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			workstr_left--;
1224354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1225354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
12264ad5833caef77fb911da4f13bbd41187479228a5Maninder Singh		n = malloc(sizeof(struct coll_entry));
1227354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if ((n->pcnt_f = strstr(workstr, "%f"))) {
1228354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			n->pcnt_f[1] = 's';
1229354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1230354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		n->cmdline = strdup(workstr);
1231354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		n->name = "cmdln";
1232354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		n->next = NULL;
1233354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (p) {
1234354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			p->next = n;
1235354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1236354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (head == NULL) {
1237354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			head = n;
1238354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1239354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		coll->cnt++;
124014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
124114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1242354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* get an array */
12434ad5833caef77fb911da4f13bbd41187479228a5Maninder Singh	coll->ary = malloc(coll->cnt * sizeof(struct coll_entry *));
1244354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1245354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* fill the array */
1246354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	i = 0;
1247354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	n = head;
1248354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while (n != NULL) {
1249354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		coll->ary[i] = n;
1250354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		n = n->next;
1251354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		++i;
125214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
1253354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (i != coll->cnt)
1254354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan(%s): i doesn't match cnt\n", panname);
1255354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1256354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return coll;
1257354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao}
1258354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1259354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic char *slurp(char *file)
1260354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{
1261354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *buf;
1262354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int fd;
1263354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct stat sbuf;
1264354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1265354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if ((fd = open(file, O_RDONLY)) < 0) {
1266354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr,
1267354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			"pan(%s): open(%s,O_RDONLY) failed.  errno:%d  %s\n",
1268354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			panname, file, errno, strerror(errno));
1269354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return NULL;
127014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
1271354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1272354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (fstat(fd, &sbuf) < 0) {
1273354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan(%s): fstat(%s) failed.  errno:%d  %s\n",
1274354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			panname, file, errno, strerror(errno));
1275354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return NULL;
127614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
127714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
12784ad5833caef77fb911da4f13bbd41187479228a5Maninder Singh	buf = malloc(sbuf.st_size + 1);
1279354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (read(fd, buf, sbuf.st_size) != sbuf.st_size) {
1280354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "pan(%s): slurp failed.  errno:%d  %s\n",
1281354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			panname, errno, strerror(errno));
128272a6f86864c7e17510a996b0437fb06041c6779cManjeet Pawar		free(buf);
1283354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return NULL;
1284354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1285354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	buf[sbuf.st_size] = '\0';
128614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1287354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	close(fd);
1288354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return buf;
128914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
129014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1291354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void check_orphans(struct orphan_pgrp *orphans, int sig)
129214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1293354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct orphan_pgrp *orph;
129414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1295354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (orph = orphans; orph != NULL; orph = orph->next) {
1296354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (orph->pgrp == 0)
1297354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			continue;
12985c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak
1299354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (Debug & Dshutdown)
1300354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr,
1301354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"  propagating sig %d to orphaned pgrp %d\n",
1302354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				sig, -(orph->pgrp));
1303354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (kill(-(orph->pgrp), sig) != 0) {
1304354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			if (errno == ESRCH) {
1305354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				/* This pgrp is now empty */
1306354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				if (zoo_clear(zoofile, orph->pgrp)) {
1307354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					fprintf(stderr, "pan(%s): %s\n",
1308354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao						panname, zoo_error);
1309354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				}
1310354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				orph->pgrp = 0;
1311354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			} else {
1312354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				fprintf(stderr,
1313354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					"pan(%s): kill(%d,%d) on orphaned pgrp failed.  errno:%d  %s\n",
1314354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					panname, -(orph->pgrp), sig, errno,
1315354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					strerror(errno));
1316354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			}
131714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak		}
131814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak	}
131914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
132014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1321354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void mark_orphan(struct orphan_pgrp *orphans, pid_t cpid)
132214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1323354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct orphan_pgrp *orph;
132414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1325354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (orph = orphans; orph != NULL; orph = orph->next) {
1326354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (orph->pgrp == 0)
1327354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			break;
1328354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1329354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (orph == NULL) {
1330354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* make a new struct */
13314ad5833caef77fb911da4f13bbd41187479228a5Maninder Singh		orph = malloc(sizeof(struct orphan_pgrp));
133214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1333354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* plug in the new struct just after the head */
1334354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		orph->next = orphans->next;
1335354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		orphans->next = orph;
1336354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1337354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	orph->pgrp = cpid;
1338354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao}
133914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1340354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void copy_buffered_output(struct tag_pgrp *running)
134114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1342354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *tag_output;
1343354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1344354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	tag_output = slurp(running->output);
1345354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (tag_output) {
1346354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		printf("%s", tag_output);
1347354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* make sure the output ends with a newline */
1348354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (tag_output[strlen(tag_output) - 1] != '\n')
1349354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			printf("\n");
1350354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fflush(stdout);
1351354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		free(tag_output);
1352354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
135314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
135414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1355354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void write_test_start(struct tag_pgrp *running)
135614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1357354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (!strcmp(reporttype, "rts")) {
135814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1359354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		printf
1360354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    ("%s\ntag=%s stime=%ld\ncmdline=\"%s\"\ncontacts=\"%s\"\nanalysis=%s\n%s\n",
1361354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     "<<<test_start>>>", running->cmd->name, running->mystime,
1362354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     running->cmd->cmdline, "", "exit", "<<<test_output>>>");
1363354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1364354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	fflush(stdout);
1365354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao}
136614390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
13675c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modakstatic void
1368f6b28b5171cad776d06ce3aa6110f1ad18c6eec7subrata_modakwrite_test_end(struct tag_pgrp *running, const char *init_status,
1369354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       time_t exit_time, char *term_type, int stat_loc,
1370354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       int term_id, struct tms *tms1, struct tms *tms2)
137114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1372354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (!strcmp(reporttype, "rts")) {
1373354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		printf
1374354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    ("%s\ninitiation_status=\"%s\"\nduration=%ld termination_type=%s "
1375354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     "termination_id=%d corefile=%s\ncutime=%d cstime=%d\n%s\n",
1376354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     "<<<execution_status>>>", init_status,
1377354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     (long)(exit_time - running->mystime), term_type, term_id,
1378354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     (stat_loc & 0200) ? "yes" : "no",
1379354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     (int)(tms2->tms_cutime - tms1->tms_cutime),
1380354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     (int)(tms2->tms_cstime - tms1->tms_cstime),
1381354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     "<<<test_end>>>");
1382354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1383354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	fflush(stdout);
138414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
138514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
13865c4b532c88c2029567c69b77a60b0b1a66aa94dbsubrata_modak/* The functions below are all debugging related */
138714390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1388354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void pids_running(struct tag_pgrp *running, int keep_active)
138914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1390354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int i;
1391354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1392354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	fprintf(stderr, "pids still running: ");
1393354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (i = 0; i < keep_active; ++i) {
1394354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (running[i].pgrp != 0)
1395354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr, "%d ", running[i].pgrp);
1396354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1397354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	fprintf(stderr, "\n");
139814390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
139914390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1400354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void orphans_running(struct orphan_pgrp *orphans)
140114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1402354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct orphan_pgrp *orph;
1403354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1404354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	fprintf(stderr, "orphans still running: ");
1405354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (orph = orphans; orph != NULL; orph = orph->next) {
1406354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (orph->pgrp != 0)
1407354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			fprintf(stderr, "%d ", -(orph->pgrp));
1408354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1409354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	fprintf(stderr, "\n");
141014390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
141114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1412354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void dump_coll(struct collection *coll)
141314390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1414354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int i;
141514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1416354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (i = 0; i < coll->cnt; ++i) {
1417354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "coll %d\n", i);
1418354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		fprintf(stderr, "  name=%s cmdline=%s\n", coll->ary[i]->name,
1419354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			coll->ary[i]->cmdline);
1420354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
142114390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
142214390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak
1423354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid wait_handler(int sig)
142414390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak{
1425354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	static int lastsent = 0;
1426354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1427354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (sig == 0) {
1428354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		lastsent = 0;
1429354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	} else {
1430354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		rec_signal = sig;
1431354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (sig == SIGUSR2)
1432354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			return;
1433354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (lastsent == 0)
1434354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			send_signal = sig;
1435354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		else if (lastsent == SIGUSR1)
1436354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			send_signal = SIGINT;
1437354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		else if (lastsent == sig)
1438354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			send_signal = SIGTERM;
1439354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		else if (lastsent == SIGTERM)
1440354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			send_signal = SIGHUP;
1441354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		else if (lastsent == SIGHUP)
1442354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			send_signal = SIGKILL;
1443354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		lastsent = send_signal;
1444354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
144514390fd5298724c529b3f5e5158bd0d3776b6933subrata_modak}
1446