1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3*49cdfc7eSAndroid Build Coastguard Worker *
4*49cdfc7eSAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify it
5*49cdfc7eSAndroid Build Coastguard Worker * under the terms of version 2 of the GNU General Public License as
6*49cdfc7eSAndroid Build Coastguard Worker * published by the Free Software Foundation.
7*49cdfc7eSAndroid Build Coastguard Worker *
8*49cdfc7eSAndroid Build Coastguard Worker * This program is distributed in the hope that it would be useful, but
9*49cdfc7eSAndroid Build Coastguard Worker * WITHOUT ANY WARRANTY; without even the implied warranty of
10*49cdfc7eSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11*49cdfc7eSAndroid Build Coastguard Worker *
12*49cdfc7eSAndroid Build Coastguard Worker * Further, this software is distributed without any warranty that it is
13*49cdfc7eSAndroid Build Coastguard Worker * free of the rightful claim of any third person regarding infringement
14*49cdfc7eSAndroid Build Coastguard Worker * or the like. Any license provided herein, whether implied or
15*49cdfc7eSAndroid Build Coastguard Worker * otherwise, applies only to this software file. Patent licenses, if
16*49cdfc7eSAndroid Build Coastguard Worker * any, provided herein do not apply to combinations of this program with
17*49cdfc7eSAndroid Build Coastguard Worker * other software, or any other product whatsoever.
18*49cdfc7eSAndroid Build Coastguard Worker *
19*49cdfc7eSAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License along
20*49cdfc7eSAndroid Build Coastguard Worker * with this program; if not, write the Free Software Foundation, Inc.,
21*49cdfc7eSAndroid Build Coastguard Worker * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22*49cdfc7eSAndroid Build Coastguard Worker *
23*49cdfc7eSAndroid Build Coastguard Worker * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24*49cdfc7eSAndroid Build Coastguard Worker * Mountain View, CA 94043, or:
25*49cdfc7eSAndroid Build Coastguard Worker *
26*49cdfc7eSAndroid Build Coastguard Worker * http://www.sgi.com
27*49cdfc7eSAndroid Build Coastguard Worker *
28*49cdfc7eSAndroid Build Coastguard Worker * For further information regarding this notice, see:
29*49cdfc7eSAndroid Build Coastguard Worker *
30*49cdfc7eSAndroid Build Coastguard Worker * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31*49cdfc7eSAndroid Build Coastguard Worker *
32*49cdfc7eSAndroid Build Coastguard Worker * Changelog:
33*49cdfc7eSAndroid Build Coastguard Worker *
34*49cdfc7eSAndroid Build Coastguard Worker * Added timer options: William Jay Huie, IBM
35*49cdfc7eSAndroid Build Coastguard Worker * 01/27/03 - Added: Manoj Iyer, [email protected]
36*49cdfc7eSAndroid Build Coastguard Worker * - option '-p' (pretty printing)i to enabled formatted printing
37*49cdfc7eSAndroid Build Coastguard Worker * of results.
38*49cdfc7eSAndroid Build Coastguard Worker *
39*49cdfc7eSAndroid Build Coastguard Worker * 01/27/03 - Added: Manoj Iyer, [email protected]
40*49cdfc7eSAndroid Build Coastguard Worker * - added code to print system information
41*49cdfc7eSAndroid Build Coastguard Worker *
42*49cdfc7eSAndroid Build Coastguard Worker * 01/28/03 - Added: Manoj Iyer, [email protected]
43*49cdfc7eSAndroid Build Coastguard Worker * - added code to print test exit value.
44*49cdfc7eSAndroid Build Coastguard Worker *
45*49cdfc7eSAndroid Build Coastguard Worker * 01/29/03 - Added: Manoj Iyer, [email protected]
46*49cdfc7eSAndroid Build Coastguard Worker * - added code supresses test start and test end tags.
47*49cdfc7eSAndroid Build Coastguard Worker *
48*49cdfc7eSAndroid Build Coastguard Worker * 07/22/07 - Added: Ricardo Salveti de Araujo, [email protected]
49*49cdfc7eSAndroid Build Coastguard Worker * - added option to create a command file with all failed tests.
50*49cdfc7eSAndroid Build Coastguard Worker *
51*49cdfc7eSAndroid Build Coastguard Worker */
52*49cdfc7eSAndroid Build Coastguard Worker /* $Id: ltp-pan.c,v 1.4 2009/10/15 18:45:55 yaberauneya Exp $ */
53*49cdfc7eSAndroid Build Coastguard Worker
54*49cdfc7eSAndroid Build Coastguard Worker #include <sys/param.h>
55*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
56*49cdfc7eSAndroid Build Coastguard Worker #include <stdarg.h>
57*49cdfc7eSAndroid Build Coastguard Worker #include <sys/times.h>
58*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
59*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
60*49cdfc7eSAndroid Build Coastguard Worker #include <sys/utsname.h>
61*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
62*49cdfc7eSAndroid Build Coastguard Worker #include <err.h>
63*49cdfc7eSAndroid Build Coastguard Worker #include <limits.h>
64*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
65*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
66*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
67*49cdfc7eSAndroid Build Coastguard Worker #include <time.h>
68*49cdfc7eSAndroid Build Coastguard Worker #include <ctype.h>
69*49cdfc7eSAndroid Build Coastguard Worker
70*49cdfc7eSAndroid Build Coastguard Worker #include "splitstr.h"
71*49cdfc7eSAndroid Build Coastguard Worker #include "zoolib.h"
72*49cdfc7eSAndroid Build Coastguard Worker #include "tst_res_flags.h"
73*49cdfc7eSAndroid Build Coastguard Worker
74*49cdfc7eSAndroid Build Coastguard Worker /* One entry in the command line collection. */
75*49cdfc7eSAndroid Build Coastguard Worker struct coll_entry {
76*49cdfc7eSAndroid Build Coastguard Worker char *name; /* tag name */
77*49cdfc7eSAndroid Build Coastguard Worker char *cmdline; /* command line */
78*49cdfc7eSAndroid Build Coastguard Worker char *pcnt_f; /* location of %f in the command line args, flag */
79*49cdfc7eSAndroid Build Coastguard Worker struct coll_entry *next;
80*49cdfc7eSAndroid Build Coastguard Worker };
81*49cdfc7eSAndroid Build Coastguard Worker
82*49cdfc7eSAndroid Build Coastguard Worker struct collection {
83*49cdfc7eSAndroid Build Coastguard Worker int cnt;
84*49cdfc7eSAndroid Build Coastguard Worker struct coll_entry **ary;
85*49cdfc7eSAndroid Build Coastguard Worker };
86*49cdfc7eSAndroid Build Coastguard Worker
87*49cdfc7eSAndroid Build Coastguard Worker struct tag_pgrp {
88*49cdfc7eSAndroid Build Coastguard Worker int pgrp;
89*49cdfc7eSAndroid Build Coastguard Worker int stopping;
90*49cdfc7eSAndroid Build Coastguard Worker time_t mystime;
91*49cdfc7eSAndroid Build Coastguard Worker struct coll_entry *cmd;
92*49cdfc7eSAndroid Build Coastguard Worker char output[PATH_MAX];
93*49cdfc7eSAndroid Build Coastguard Worker };
94*49cdfc7eSAndroid Build Coastguard Worker
95*49cdfc7eSAndroid Build Coastguard Worker struct orphan_pgrp {
96*49cdfc7eSAndroid Build Coastguard Worker int pgrp;
97*49cdfc7eSAndroid Build Coastguard Worker struct orphan_pgrp *next;
98*49cdfc7eSAndroid Build Coastguard Worker };
99*49cdfc7eSAndroid Build Coastguard Worker
100*49cdfc7eSAndroid Build Coastguard Worker static pid_t run_child(struct coll_entry *colle, struct tag_pgrp *active,
101*49cdfc7eSAndroid Build Coastguard Worker int quiet_mode, int *failcnt, int fmt_print,
102*49cdfc7eSAndroid Build Coastguard Worker FILE * logfile, int no_kmsg);
103*49cdfc7eSAndroid Build Coastguard Worker static char *slurp(char *file);
104*49cdfc7eSAndroid Build Coastguard Worker static struct collection *get_collection(char *file, int optind, int argc,
105*49cdfc7eSAndroid Build Coastguard Worker char **argv);
106*49cdfc7eSAndroid Build Coastguard Worker static void pids_running(struct tag_pgrp *running, int keep_active);
107*49cdfc7eSAndroid Build Coastguard Worker static int check_pids(struct tag_pgrp *running, int *num_active,
108*49cdfc7eSAndroid Build Coastguard Worker int keep_active, FILE * logfile, FILE * failcmdfile,
109*49cdfc7eSAndroid Build Coastguard Worker FILE *tconfcmdfile, struct orphan_pgrp *orphans,
110*49cdfc7eSAndroid Build Coastguard Worker int fmt_print, int *failcnt, int *tconfcnt,
111*49cdfc7eSAndroid Build Coastguard Worker int quiet_mode, int no_kmsg);
112*49cdfc7eSAndroid Build Coastguard Worker static void propagate_signal(struct tag_pgrp *running, int keep_active,
113*49cdfc7eSAndroid Build Coastguard Worker struct orphan_pgrp *orphans);
114*49cdfc7eSAndroid Build Coastguard Worker static void dump_coll(struct collection *coll);
115*49cdfc7eSAndroid Build Coastguard Worker static char *subst_pcnt_f(struct coll_entry *colle);
116*49cdfc7eSAndroid Build Coastguard Worker static void mark_orphan(struct orphan_pgrp *orphans, pid_t cpid);
117*49cdfc7eSAndroid Build Coastguard Worker static void orphans_running(struct orphan_pgrp *orphans);
118*49cdfc7eSAndroid Build Coastguard Worker static void check_orphans(struct orphan_pgrp *orphans, int sig);
119*49cdfc7eSAndroid Build Coastguard Worker
120*49cdfc7eSAndroid Build Coastguard Worker static void copy_buffered_output(struct tag_pgrp *running);
121*49cdfc7eSAndroid Build Coastguard Worker static void write_test_start(struct tag_pgrp *running, int no_kmsg);
122*49cdfc7eSAndroid Build Coastguard Worker static void write_test_end(struct tag_pgrp *running, const char *init_status,
123*49cdfc7eSAndroid Build Coastguard Worker time_t exit_time, char *term_type, int stat_loc,
124*49cdfc7eSAndroid Build Coastguard Worker int term_id, struct tms *tms1, struct tms *tms2);
125*49cdfc7eSAndroid Build Coastguard Worker
126*49cdfc7eSAndroid Build Coastguard Worker //wjh
127*49cdfc7eSAndroid Build Coastguard Worker static char PAN_STOP_FILE[] = "PAN_STOP_FILE";
128*49cdfc7eSAndroid Build Coastguard Worker
129*49cdfc7eSAndroid Build Coastguard Worker static char *panname = NULL;
130*49cdfc7eSAndroid Build Coastguard Worker static char *test_out_dir = NULL; /* dir to buffer output to */
131*49cdfc7eSAndroid Build Coastguard Worker zoo_t zoofile;
132*49cdfc7eSAndroid Build Coastguard Worker static char *reporttype = NULL;
133*49cdfc7eSAndroid Build Coastguard Worker
134*49cdfc7eSAndroid Build Coastguard Worker /* Common format string for ltp-pan results */
135*49cdfc7eSAndroid Build Coastguard Worker #define ResultFmt "%-50s %-10.10s"
136*49cdfc7eSAndroid Build Coastguard Worker
137*49cdfc7eSAndroid Build Coastguard Worker /* zoolib */
138*49cdfc7eSAndroid Build Coastguard Worker int rec_signal; /* received signal */
139*49cdfc7eSAndroid Build Coastguard Worker int send_signal; /* signal to send */
140*49cdfc7eSAndroid Build Coastguard Worker
141*49cdfc7eSAndroid Build Coastguard Worker /* Debug Bits */
142*49cdfc7eSAndroid Build Coastguard Worker int Debug = 0;
143*49cdfc7eSAndroid Build Coastguard Worker #define Dbuffile 0x000400 /* buffer file use */
144*49cdfc7eSAndroid Build Coastguard Worker #define Dsetup 0x000200 /* one-time set-up */
145*49cdfc7eSAndroid Build Coastguard Worker #define Dshutdown 0x000100 /* killed by signal */
146*49cdfc7eSAndroid Build Coastguard Worker #define Dexit 0x000020 /* exit status */
147*49cdfc7eSAndroid Build Coastguard Worker #define Drunning 0x000010 /* current pids running */
148*49cdfc7eSAndroid Build Coastguard Worker #define Dstartup 0x000004 /* started command */
149*49cdfc7eSAndroid Build Coastguard Worker #define Dstart 0x000002 /* started command */
150*49cdfc7eSAndroid Build Coastguard Worker #define Dwait 0x000001 /* wait interrupted */
151*49cdfc7eSAndroid Build Coastguard Worker
main(int argc,char ** argv)152*49cdfc7eSAndroid Build Coastguard Worker int main(int argc, char **argv)
153*49cdfc7eSAndroid Build Coastguard Worker {
154*49cdfc7eSAndroid Build Coastguard Worker extern char *optarg;
155*49cdfc7eSAndroid Build Coastguard Worker extern int optind;
156*49cdfc7eSAndroid Build Coastguard Worker char *zooname = NULL; /* name of the zoo file to use */
157*49cdfc7eSAndroid Build Coastguard Worker char *filename = "/dev/null"; /* filename to read test tags from */
158*49cdfc7eSAndroid Build Coastguard Worker char *logfilename = NULL;
159*49cdfc7eSAndroid Build Coastguard Worker char *failcmdfilename = NULL;
160*49cdfc7eSAndroid Build Coastguard Worker char *tconfcmdfilename = NULL;
161*49cdfc7eSAndroid Build Coastguard Worker char *outputfilename = NULL;
162*49cdfc7eSAndroid Build Coastguard Worker struct collection *coll = NULL;
163*49cdfc7eSAndroid Build Coastguard Worker struct tag_pgrp *running;
164*49cdfc7eSAndroid Build Coastguard Worker struct orphan_pgrp *orphans, *orph;
165*49cdfc7eSAndroid Build Coastguard Worker struct utsname unamebuf;
166*49cdfc7eSAndroid Build Coastguard Worker FILE *logfile = NULL;
167*49cdfc7eSAndroid Build Coastguard Worker FILE *failcmdfile = NULL;
168*49cdfc7eSAndroid Build Coastguard Worker FILE *tconfcmdfile = NULL;
169*49cdfc7eSAndroid Build Coastguard Worker int keep_active = 1;
170*49cdfc7eSAndroid Build Coastguard Worker int num_active = 0;
171*49cdfc7eSAndroid Build Coastguard Worker int failcnt = 0; /* count of total testcases that failed. */
172*49cdfc7eSAndroid Build Coastguard Worker int tconfcnt = 0; /* count of total testcases that return TCONF */
173*49cdfc7eSAndroid Build Coastguard Worker int err, i;
174*49cdfc7eSAndroid Build Coastguard Worker int starts = -1;
175*49cdfc7eSAndroid Build Coastguard Worker int timed = 0;
176*49cdfc7eSAndroid Build Coastguard Worker int run_time = -1;
177*49cdfc7eSAndroid Build Coastguard Worker char modifier = 'm';
178*49cdfc7eSAndroid Build Coastguard Worker int ret = 0;
179*49cdfc7eSAndroid Build Coastguard Worker int stop;
180*49cdfc7eSAndroid Build Coastguard Worker int go_idle;
181*49cdfc7eSAndroid Build Coastguard Worker int has_brakes = 0; /* stop everything if a test case fails */
182*49cdfc7eSAndroid Build Coastguard Worker int sequential = 0; /* run tests sequentially */
183*49cdfc7eSAndroid Build Coastguard Worker int fork_in_road = 0;
184*49cdfc7eSAndroid Build Coastguard Worker int exit_stat;
185*49cdfc7eSAndroid Build Coastguard Worker int track_exit_stats = 0; /* exit non-zero if any test exits non-zero */
186*49cdfc7eSAndroid Build Coastguard Worker int fmt_print = 0; /* enables formatted printing of logfiles. */
187*49cdfc7eSAndroid Build Coastguard Worker int quiet_mode = 0; /* supresses test start and test end tags. */
188*49cdfc7eSAndroid Build Coastguard Worker int no_kmsg = 0; /* don't log into /dev/kmsg */
189*49cdfc7eSAndroid Build Coastguard Worker int c;
190*49cdfc7eSAndroid Build Coastguard Worker pid_t cpid;
191*49cdfc7eSAndroid Build Coastguard Worker struct sigaction sa;
192*49cdfc7eSAndroid Build Coastguard Worker
193*49cdfc7eSAndroid Build Coastguard Worker while ((c =
194*49cdfc7eSAndroid Build Coastguard Worker getopt(argc, argv, "AO:Sa:C:QT:d:ef:hl:n:o:pqr:s:t:x:y"))
195*49cdfc7eSAndroid Build Coastguard Worker != -1) {
196*49cdfc7eSAndroid Build Coastguard Worker switch (c) {
197*49cdfc7eSAndroid Build Coastguard Worker case 'A': /* all-stop flag */
198*49cdfc7eSAndroid Build Coastguard Worker has_brakes = 1;
199*49cdfc7eSAndroid Build Coastguard Worker track_exit_stats = 1;
200*49cdfc7eSAndroid Build Coastguard Worker break;
201*49cdfc7eSAndroid Build Coastguard Worker case 'O': /* output buffering directory */
202*49cdfc7eSAndroid Build Coastguard Worker test_out_dir = strdup(optarg);
203*49cdfc7eSAndroid Build Coastguard Worker break;
204*49cdfc7eSAndroid Build Coastguard Worker case 'S': /* run tests sequentially */
205*49cdfc7eSAndroid Build Coastguard Worker sequential = 1;
206*49cdfc7eSAndroid Build Coastguard Worker break;
207*49cdfc7eSAndroid Build Coastguard Worker case 'a': /* name of the zoo file to use */
208*49cdfc7eSAndroid Build Coastguard Worker zooname = strdup(optarg);
209*49cdfc7eSAndroid Build Coastguard Worker break;
210*49cdfc7eSAndroid Build Coastguard Worker case 'C': /* name of the file where all failed commands will be */
211*49cdfc7eSAndroid Build Coastguard Worker failcmdfilename = strdup(optarg);
212*49cdfc7eSAndroid Build Coastguard Worker break;
213*49cdfc7eSAndroid Build Coastguard Worker case 'Q':
214*49cdfc7eSAndroid Build Coastguard Worker no_kmsg = 1;
215*49cdfc7eSAndroid Build Coastguard Worker break;
216*49cdfc7eSAndroid Build Coastguard Worker case 'T':
217*49cdfc7eSAndroid Build Coastguard Worker /*
218*49cdfc7eSAndroid Build Coastguard Worker * test cases that are not fully tested will be recorded
219*49cdfc7eSAndroid Build Coastguard Worker * in this file
220*49cdfc7eSAndroid Build Coastguard Worker */
221*49cdfc7eSAndroid Build Coastguard Worker tconfcmdfilename = strdup(optarg);
222*49cdfc7eSAndroid Build Coastguard Worker break;
223*49cdfc7eSAndroid Build Coastguard Worker case 'd': /* debug options */
224*49cdfc7eSAndroid Build Coastguard Worker sscanf(optarg, "%i", &Debug);
225*49cdfc7eSAndroid Build Coastguard Worker break;
226*49cdfc7eSAndroid Build Coastguard Worker case 'e': /* exit non-zero if any test exists non-zero */
227*49cdfc7eSAndroid Build Coastguard Worker track_exit_stats = 1;
228*49cdfc7eSAndroid Build Coastguard Worker break;
229*49cdfc7eSAndroid Build Coastguard Worker case 'f': /* filename to read test tags from */
230*49cdfc7eSAndroid Build Coastguard Worker filename = strdup(optarg);
231*49cdfc7eSAndroid Build Coastguard Worker break;
232*49cdfc7eSAndroid Build Coastguard Worker case 'h': /* help */
233*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
234*49cdfc7eSAndroid Build Coastguard Worker "Usage: pan -n name [ -SyAehpqQ ] [ -s starts ]"
235*49cdfc7eSAndroid Build Coastguard Worker " [-t time[s|m|h|d] [ -x nactive ] [ -l logfile ]\n\t"
236*49cdfc7eSAndroid Build Coastguard Worker "[ -a active-file ] [ -f command-file ] "
237*49cdfc7eSAndroid Build Coastguard Worker "[ -C fail-command-file ] "
238*49cdfc7eSAndroid Build Coastguard Worker "[ -d debug-level ]\n\t[-o output-file] "
239*49cdfc7eSAndroid Build Coastguard Worker "[-O output-buffer-directory] [cmd]\n");
240*49cdfc7eSAndroid Build Coastguard Worker exit(0);
241*49cdfc7eSAndroid Build Coastguard Worker case 'l': /* log file */
242*49cdfc7eSAndroid Build Coastguard Worker logfilename = strdup(optarg);
243*49cdfc7eSAndroid Build Coastguard Worker break;
244*49cdfc7eSAndroid Build Coastguard Worker case 'n': /* tag given to pan */
245*49cdfc7eSAndroid Build Coastguard Worker panname = strdup(optarg);
246*49cdfc7eSAndroid Build Coastguard Worker break;
247*49cdfc7eSAndroid Build Coastguard Worker case 'o': /* send test output here */
248*49cdfc7eSAndroid Build Coastguard Worker outputfilename = strdup(optarg);
249*49cdfc7eSAndroid Build Coastguard Worker break;
250*49cdfc7eSAndroid Build Coastguard Worker case 'p': /* formatted printing. */
251*49cdfc7eSAndroid Build Coastguard Worker fmt_print = 1;
252*49cdfc7eSAndroid Build Coastguard Worker break;
253*49cdfc7eSAndroid Build Coastguard Worker case 'q': /* supress test start and test end messages */
254*49cdfc7eSAndroid Build Coastguard Worker quiet_mode = 1;
255*49cdfc7eSAndroid Build Coastguard Worker break;
256*49cdfc7eSAndroid Build Coastguard Worker case 'r': /* reporting type: none, rts */
257*49cdfc7eSAndroid Build Coastguard Worker reporttype = strdup(optarg);
258*49cdfc7eSAndroid Build Coastguard Worker break;
259*49cdfc7eSAndroid Build Coastguard Worker case 's': /* number of tags to run */
260*49cdfc7eSAndroid Build Coastguard Worker starts = atoi(optarg);
261*49cdfc7eSAndroid Build Coastguard Worker break;
262*49cdfc7eSAndroid Build Coastguard Worker case 't': /* run_time to run */
263*49cdfc7eSAndroid Build Coastguard Worker ret = sscanf(optarg, "%d%c", &run_time, &modifier);
264*49cdfc7eSAndroid Build Coastguard Worker if (ret == 0) {
265*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
266*49cdfc7eSAndroid Build Coastguard Worker "Need proper time input: ####x where "
267*49cdfc7eSAndroid Build Coastguard Worker "x is one of s,m,h,d\n");
268*49cdfc7eSAndroid Build Coastguard Worker break;
269*49cdfc7eSAndroid Build Coastguard Worker } else if (ret == 1) {
270*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "Only got a time value of %d "
271*49cdfc7eSAndroid Build Coastguard Worker "modifiers need to come immediately after #"
272*49cdfc7eSAndroid Build Coastguard Worker " assuming %c\n", run_time, modifier);
273*49cdfc7eSAndroid Build Coastguard Worker } else {
274*49cdfc7eSAndroid Build Coastguard Worker switch (modifier) {
275*49cdfc7eSAndroid Build Coastguard Worker case 's':
276*49cdfc7eSAndroid Build Coastguard Worker run_time = run_time;
277*49cdfc7eSAndroid Build Coastguard Worker break;
278*49cdfc7eSAndroid Build Coastguard Worker case 'm':
279*49cdfc7eSAndroid Build Coastguard Worker run_time = run_time * 60;
280*49cdfc7eSAndroid Build Coastguard Worker break;
281*49cdfc7eSAndroid Build Coastguard Worker case 'h':
282*49cdfc7eSAndroid Build Coastguard Worker run_time = run_time * 60 * 60;
283*49cdfc7eSAndroid Build Coastguard Worker break;
284*49cdfc7eSAndroid Build Coastguard Worker case 'd':
285*49cdfc7eSAndroid Build Coastguard Worker run_time = run_time * 60 * 60 * 24;
286*49cdfc7eSAndroid Build Coastguard Worker break;
287*49cdfc7eSAndroid Build Coastguard Worker default:
288*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
289*49cdfc7eSAndroid Build Coastguard Worker "Invalid time modifier, try: s|h|m|d\n");
290*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
291*49cdfc7eSAndroid Build Coastguard Worker }
292*49cdfc7eSAndroid Build Coastguard Worker if (!quiet_mode)
293*49cdfc7eSAndroid Build Coastguard Worker printf("PAN will run for %d seconds\n",
294*49cdfc7eSAndroid Build Coastguard Worker run_time);
295*49cdfc7eSAndroid Build Coastguard Worker }
296*49cdfc7eSAndroid Build Coastguard Worker timed = 1; //-t implies run as many starts as possible, by default
297*49cdfc7eSAndroid Build Coastguard Worker break;
298*49cdfc7eSAndroid Build Coastguard Worker case 'x': /* number of tags to keep running */
299*49cdfc7eSAndroid Build Coastguard Worker keep_active = atoi(optarg);
300*49cdfc7eSAndroid Build Coastguard Worker break;
301*49cdfc7eSAndroid Build Coastguard Worker case 'y': /* restart on failure or signal */
302*49cdfc7eSAndroid Build Coastguard Worker fork_in_road = 1;
303*49cdfc7eSAndroid Build Coastguard Worker break;
304*49cdfc7eSAndroid Build Coastguard Worker }
305*49cdfc7eSAndroid Build Coastguard Worker }
306*49cdfc7eSAndroid Build Coastguard Worker
307*49cdfc7eSAndroid Build Coastguard Worker if (panname == NULL) {
308*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan: Must supply -n\n");
309*49cdfc7eSAndroid Build Coastguard Worker exit(1);
310*49cdfc7eSAndroid Build Coastguard Worker }
311*49cdfc7eSAndroid Build Coastguard Worker if (zooname == NULL) {
312*49cdfc7eSAndroid Build Coastguard Worker zooname = zoo_getname();
313*49cdfc7eSAndroid Build Coastguard Worker if (zooname == NULL) {
314*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
315*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): Must supply -a or set ZOO env variable\n",
316*49cdfc7eSAndroid Build Coastguard Worker panname);
317*49cdfc7eSAndroid Build Coastguard Worker exit(1);
318*49cdfc7eSAndroid Build Coastguard Worker }
319*49cdfc7eSAndroid Build Coastguard Worker }
320*49cdfc7eSAndroid Build Coastguard Worker if (reporttype) {
321*49cdfc7eSAndroid Build Coastguard Worker /* make sure we understand the report type */
322*49cdfc7eSAndroid Build Coastguard Worker if (strcasecmp(reporttype, "rts")
323*49cdfc7eSAndroid Build Coastguard Worker && strcasecmp(reporttype, "none")
324*49cdfc7eSAndroid Build Coastguard Worker /* && strcasecmp(reporttype, "xml") */
325*49cdfc7eSAndroid Build Coastguard Worker )
326*49cdfc7eSAndroid Build Coastguard Worker reporttype = "rts";
327*49cdfc7eSAndroid Build Coastguard Worker } else {
328*49cdfc7eSAndroid Build Coastguard Worker /* set the default */
329*49cdfc7eSAndroid Build Coastguard Worker reporttype = "rts";
330*49cdfc7eSAndroid Build Coastguard Worker }
331*49cdfc7eSAndroid Build Coastguard Worker
332*49cdfc7eSAndroid Build Coastguard Worker if (logfilename != NULL) {
333*49cdfc7eSAndroid Build Coastguard Worker time_t startup;
334*49cdfc7eSAndroid Build Coastguard Worker char *s;
335*49cdfc7eSAndroid Build Coastguard Worker
336*49cdfc7eSAndroid Build Coastguard Worker if (!strcmp(logfilename, "-")) {
337*49cdfc7eSAndroid Build Coastguard Worker logfile = stdout;
338*49cdfc7eSAndroid Build Coastguard Worker } else {
339*49cdfc7eSAndroid Build Coastguard Worker if ((logfile = fopen(logfilename, "a+e")) == NULL) {
340*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
341*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): Error %s (%d) opening log file '%s'\n",
342*49cdfc7eSAndroid Build Coastguard Worker panname, strerror(errno), errno,
343*49cdfc7eSAndroid Build Coastguard Worker logfilename);
344*49cdfc7eSAndroid Build Coastguard Worker exit(1);
345*49cdfc7eSAndroid Build Coastguard Worker }
346*49cdfc7eSAndroid Build Coastguard Worker }
347*49cdfc7eSAndroid Build Coastguard Worker
348*49cdfc7eSAndroid Build Coastguard Worker time(&startup);
349*49cdfc7eSAndroid Build Coastguard Worker s = ctime(&startup);
350*49cdfc7eSAndroid Build Coastguard Worker *(s + strlen(s) - 1) = '\0';
351*49cdfc7eSAndroid Build Coastguard Worker if (!fmt_print)
352*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, "startup='%s'\n", s);
353*49cdfc7eSAndroid Build Coastguard Worker else {
354*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, "Test Start Time: %s\n", s);
355*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile,
356*49cdfc7eSAndroid Build Coastguard Worker "-----------------------------------------\n");
357*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, ResultFmt" %-10.10s\n",
358*49cdfc7eSAndroid Build Coastguard Worker "Testcase", "Result", "Exit Value");
359*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, ResultFmt" %-10.10s\n",
360*49cdfc7eSAndroid Build Coastguard Worker "--------", "------", "------------");
361*49cdfc7eSAndroid Build Coastguard Worker }
362*49cdfc7eSAndroid Build Coastguard Worker fflush(logfile);
363*49cdfc7eSAndroid Build Coastguard Worker }
364*49cdfc7eSAndroid Build Coastguard Worker
365*49cdfc7eSAndroid Build Coastguard Worker coll = get_collection(filename, optind, argc, argv);
366*49cdfc7eSAndroid Build Coastguard Worker if (!coll)
367*49cdfc7eSAndroid Build Coastguard Worker exit(1);
368*49cdfc7eSAndroid Build Coastguard Worker if (coll->cnt == 0) {
369*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
370*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): Must supply a file collection or a command\n",
371*49cdfc7eSAndroid Build Coastguard Worker panname);
372*49cdfc7eSAndroid Build Coastguard Worker exit(1);
373*49cdfc7eSAndroid Build Coastguard Worker }
374*49cdfc7eSAndroid Build Coastguard Worker
375*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Dsetup)
376*49cdfc7eSAndroid Build Coastguard Worker dump_coll(coll);
377*49cdfc7eSAndroid Build Coastguard Worker
378*49cdfc7eSAndroid Build Coastguard Worker /* a place to store the pgrps we're watching */
379*49cdfc7eSAndroid Build Coastguard Worker running =
380*49cdfc7eSAndroid Build Coastguard Worker malloc((keep_active + 1) *
381*49cdfc7eSAndroid Build Coastguard Worker sizeof(struct tag_pgrp));
382*49cdfc7eSAndroid Build Coastguard Worker if (running == NULL) {
383*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): Failed to allocate memory: %s\n",
384*49cdfc7eSAndroid Build Coastguard Worker panname, strerror(errno));
385*49cdfc7eSAndroid Build Coastguard Worker exit(2);
386*49cdfc7eSAndroid Build Coastguard Worker }
387*49cdfc7eSAndroid Build Coastguard Worker memset(running, 0, keep_active * sizeof(struct tag_pgrp));
388*49cdfc7eSAndroid Build Coastguard Worker running[keep_active].pgrp = -1; /* end sentinel */
389*49cdfc7eSAndroid Build Coastguard Worker
390*49cdfc7eSAndroid Build Coastguard Worker /* a head to the orphaned pgrp list */
391*49cdfc7eSAndroid Build Coastguard Worker orphans = malloc(sizeof(struct orphan_pgrp));
392*49cdfc7eSAndroid Build Coastguard Worker memset(orphans, 0, sizeof(struct orphan_pgrp));
393*49cdfc7eSAndroid Build Coastguard Worker
394*49cdfc7eSAndroid Build Coastguard Worker srand48(time(NULL) ^ (getpid() + (getpid() << 15)));
395*49cdfc7eSAndroid Build Coastguard Worker
396*49cdfc7eSAndroid Build Coastguard Worker /* Supply a default for starts. If we are in sequential mode, use
397*49cdfc7eSAndroid Build Coastguard Worker * the number of commands available; otherwise 1.
398*49cdfc7eSAndroid Build Coastguard Worker */
399*49cdfc7eSAndroid Build Coastguard Worker if (timed == 1 && starts == -1) { /* timed, infinite by default */
400*49cdfc7eSAndroid Build Coastguard Worker starts = -1;
401*49cdfc7eSAndroid Build Coastguard Worker } else if (starts == -1) {
402*49cdfc7eSAndroid Build Coastguard Worker if (sequential) {
403*49cdfc7eSAndroid Build Coastguard Worker starts = coll->cnt;
404*49cdfc7eSAndroid Build Coastguard Worker } else {
405*49cdfc7eSAndroid Build Coastguard Worker starts = 1;
406*49cdfc7eSAndroid Build Coastguard Worker }
407*49cdfc7eSAndroid Build Coastguard Worker } else if (starts == 0) { /* if the user specified infinite, set it */
408*49cdfc7eSAndroid Build Coastguard Worker starts = -1;
409*49cdfc7eSAndroid Build Coastguard Worker } else { /* else, make sure we are starting at least keep_active processes */
410*49cdfc7eSAndroid Build Coastguard Worker if (starts < keep_active)
411*49cdfc7eSAndroid Build Coastguard Worker starts = keep_active;
412*49cdfc7eSAndroid Build Coastguard Worker }
413*49cdfc7eSAndroid Build Coastguard Worker
414*49cdfc7eSAndroid Build Coastguard Worker /* if we're buffering output, but we're only running on process at a time,
415*49cdfc7eSAndroid Build Coastguard Worker * then essentially "turn off buffering"
416*49cdfc7eSAndroid Build Coastguard Worker */
417*49cdfc7eSAndroid Build Coastguard Worker if (test_out_dir && (keep_active == 1)) {
418*49cdfc7eSAndroid Build Coastguard Worker free(test_out_dir);
419*49cdfc7eSAndroid Build Coastguard Worker test_out_dir = NULL;
420*49cdfc7eSAndroid Build Coastguard Worker }
421*49cdfc7eSAndroid Build Coastguard Worker
422*49cdfc7eSAndroid Build Coastguard Worker if (test_out_dir) {
423*49cdfc7eSAndroid Build Coastguard Worker struct stat sbuf;
424*49cdfc7eSAndroid Build Coastguard Worker
425*49cdfc7eSAndroid Build Coastguard Worker if (stat(test_out_dir, &sbuf) < 0) {
426*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
427*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): stat of -O arg '%s' failed. errno: %d %s\n",
428*49cdfc7eSAndroid Build Coastguard Worker panname, test_out_dir, errno, strerror(errno));
429*49cdfc7eSAndroid Build Coastguard Worker exit(1);
430*49cdfc7eSAndroid Build Coastguard Worker }
431*49cdfc7eSAndroid Build Coastguard Worker if (!S_ISDIR(sbuf.st_mode)) {
432*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
433*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): -O arg '%s' must be a directory.\n",
434*49cdfc7eSAndroid Build Coastguard Worker panname, test_out_dir);
435*49cdfc7eSAndroid Build Coastguard Worker exit(1);
436*49cdfc7eSAndroid Build Coastguard Worker }
437*49cdfc7eSAndroid Build Coastguard Worker if (access(test_out_dir, W_OK | R_OK | X_OK) < 0) {
438*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
439*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): permission denied on -O arg '%s'. errno: %d %s\n",
440*49cdfc7eSAndroid Build Coastguard Worker panname, test_out_dir, errno, strerror(errno));
441*49cdfc7eSAndroid Build Coastguard Worker exit(1);
442*49cdfc7eSAndroid Build Coastguard Worker }
443*49cdfc7eSAndroid Build Coastguard Worker }
444*49cdfc7eSAndroid Build Coastguard Worker
445*49cdfc7eSAndroid Build Coastguard Worker if (outputfilename) {
446*49cdfc7eSAndroid Build Coastguard Worker if (!freopen(outputfilename, "a+", stdout)) {
447*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
448*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): Error %s (%d) opening output file '%s'\n",
449*49cdfc7eSAndroid Build Coastguard Worker panname, strerror(errno), errno,
450*49cdfc7eSAndroid Build Coastguard Worker outputfilename);
451*49cdfc7eSAndroid Build Coastguard Worker exit(1);
452*49cdfc7eSAndroid Build Coastguard Worker }
453*49cdfc7eSAndroid Build Coastguard Worker }
454*49cdfc7eSAndroid Build Coastguard Worker
455*49cdfc7eSAndroid Build Coastguard Worker if (failcmdfilename) {
456*49cdfc7eSAndroid Build Coastguard Worker if (!(failcmdfile = fopen(failcmdfilename, "a+e"))) {
457*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
458*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): Error %s (%d) opening fail cmd file '%s'\n",
459*49cdfc7eSAndroid Build Coastguard Worker panname, strerror(errno), errno,
460*49cdfc7eSAndroid Build Coastguard Worker failcmdfilename);
461*49cdfc7eSAndroid Build Coastguard Worker exit(1);
462*49cdfc7eSAndroid Build Coastguard Worker }
463*49cdfc7eSAndroid Build Coastguard Worker }
464*49cdfc7eSAndroid Build Coastguard Worker
465*49cdfc7eSAndroid Build Coastguard Worker if (tconfcmdfilename) {
466*49cdfc7eSAndroid Build Coastguard Worker tconfcmdfile = fopen(tconfcmdfilename, "a+e");
467*49cdfc7eSAndroid Build Coastguard Worker if (!tconfcmdfile) {
468*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): Error %s (%d) opening "
469*49cdfc7eSAndroid Build Coastguard Worker "tconf cmd file '%s'\n", panname,
470*49cdfc7eSAndroid Build Coastguard Worker strerror(errno), errno, tconfcmdfilename);
471*49cdfc7eSAndroid Build Coastguard Worker exit(1);
472*49cdfc7eSAndroid Build Coastguard Worker }
473*49cdfc7eSAndroid Build Coastguard Worker }
474*49cdfc7eSAndroid Build Coastguard Worker
475*49cdfc7eSAndroid Build Coastguard Worker if ((zoofile = zoo_open(zooname)) == NULL) {
476*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): %s\n", panname, zoo_error);
477*49cdfc7eSAndroid Build Coastguard Worker exit(1);
478*49cdfc7eSAndroid Build Coastguard Worker }
479*49cdfc7eSAndroid Build Coastguard Worker if (zoo_mark_args(zoofile, getpid(), panname, argc, argv)) {
480*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): %s\n", panname, zoo_error);
481*49cdfc7eSAndroid Build Coastguard Worker exit(1);
482*49cdfc7eSAndroid Build Coastguard Worker }
483*49cdfc7eSAndroid Build Coastguard Worker
484*49cdfc7eSAndroid Build Coastguard Worker /* Allocate N spaces for max-arg commands.
485*49cdfc7eSAndroid Build Coastguard Worker * this is an "active file cleanliness" thing
486*49cdfc7eSAndroid Build Coastguard Worker */
487*49cdfc7eSAndroid Build Coastguard Worker {
488*49cdfc7eSAndroid Build Coastguard Worker for (c = 0; c < keep_active; c++) {
489*49cdfc7eSAndroid Build Coastguard Worker if (zoo_mark_cmdline(zoofile, c, panname, "")) {
490*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): %s\n", panname,
491*49cdfc7eSAndroid Build Coastguard Worker zoo_error);
492*49cdfc7eSAndroid Build Coastguard Worker exit(1);
493*49cdfc7eSAndroid Build Coastguard Worker }
494*49cdfc7eSAndroid Build Coastguard Worker }
495*49cdfc7eSAndroid Build Coastguard Worker for (c = 0; c < keep_active; c++) {
496*49cdfc7eSAndroid Build Coastguard Worker if (zoo_clear(zoofile, c)) {
497*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): %s\n", panname,
498*49cdfc7eSAndroid Build Coastguard Worker zoo_error);
499*49cdfc7eSAndroid Build Coastguard Worker exit(1);
500*49cdfc7eSAndroid Build Coastguard Worker }
501*49cdfc7eSAndroid Build Coastguard Worker }
502*49cdfc7eSAndroid Build Coastguard Worker }
503*49cdfc7eSAndroid Build Coastguard Worker
504*49cdfc7eSAndroid Build Coastguard Worker rec_signal = send_signal = 0;
505*49cdfc7eSAndroid Build Coastguard Worker if (run_time != -1) {
506*49cdfc7eSAndroid Build Coastguard Worker alarm(run_time);
507*49cdfc7eSAndroid Build Coastguard Worker }
508*49cdfc7eSAndroid Build Coastguard Worker
509*49cdfc7eSAndroid Build Coastguard Worker sigemptyset(&sa.sa_mask);
510*49cdfc7eSAndroid Build Coastguard Worker sa.sa_flags = 0;
511*49cdfc7eSAndroid Build Coastguard Worker sa.sa_handler = wait_handler;
512*49cdfc7eSAndroid Build Coastguard Worker
513*49cdfc7eSAndroid Build Coastguard Worker sigaction(SIGALRM, &sa, NULL);
514*49cdfc7eSAndroid Build Coastguard Worker sigaction(SIGINT, &sa, NULL);
515*49cdfc7eSAndroid Build Coastguard Worker sigaction(SIGTERM, &sa, NULL);
516*49cdfc7eSAndroid Build Coastguard Worker sigaction(SIGHUP, &sa, NULL);
517*49cdfc7eSAndroid Build Coastguard Worker sigaction(SIGUSR1, &sa, NULL); /* ignore fork_in_road */
518*49cdfc7eSAndroid Build Coastguard Worker sigaction(SIGUSR2, &sa, NULL); /* stop the scheduler */
519*49cdfc7eSAndroid Build Coastguard Worker
520*49cdfc7eSAndroid Build Coastguard Worker c = 0; /* in this loop, c is the command index */
521*49cdfc7eSAndroid Build Coastguard Worker stop = 0;
522*49cdfc7eSAndroid Build Coastguard Worker exit_stat = 0;
523*49cdfc7eSAndroid Build Coastguard Worker go_idle = 0;
524*49cdfc7eSAndroid Build Coastguard Worker while (1) {
525*49cdfc7eSAndroid Build Coastguard Worker
526*49cdfc7eSAndroid Build Coastguard Worker while ((num_active < keep_active) && (starts != 0)) {
527*49cdfc7eSAndroid Build Coastguard Worker if (stop || rec_signal || go_idle)
528*49cdfc7eSAndroid Build Coastguard Worker break;
529*49cdfc7eSAndroid Build Coastguard Worker
530*49cdfc7eSAndroid Build Coastguard Worker if (!sequential)
531*49cdfc7eSAndroid Build Coastguard Worker c = lrand48() % coll->cnt;
532*49cdfc7eSAndroid Build Coastguard Worker
533*49cdfc7eSAndroid Build Coastguard Worker /* find a slot for the child */
534*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < keep_active; ++i) {
535*49cdfc7eSAndroid Build Coastguard Worker if (running[i].pgrp == 0)
536*49cdfc7eSAndroid Build Coastguard Worker break;
537*49cdfc7eSAndroid Build Coastguard Worker }
538*49cdfc7eSAndroid Build Coastguard Worker if (i == keep_active) {
539*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
540*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): Aborting: i == keep_active = %d\n",
541*49cdfc7eSAndroid Build Coastguard Worker panname, i);
542*49cdfc7eSAndroid Build Coastguard Worker wait_handler(SIGINT);
543*49cdfc7eSAndroid Build Coastguard Worker exit_stat++;
544*49cdfc7eSAndroid Build Coastguard Worker break;
545*49cdfc7eSAndroid Build Coastguard Worker }
546*49cdfc7eSAndroid Build Coastguard Worker
547*49cdfc7eSAndroid Build Coastguard Worker cpid =
548*49cdfc7eSAndroid Build Coastguard Worker run_child(coll->ary[c], running + i, quiet_mode,
549*49cdfc7eSAndroid Build Coastguard Worker &failcnt, fmt_print, logfile, no_kmsg);
550*49cdfc7eSAndroid Build Coastguard Worker if (cpid != -1)
551*49cdfc7eSAndroid Build Coastguard Worker ++num_active;
552*49cdfc7eSAndroid Build Coastguard Worker if ((cpid != -1 || sequential) && starts > 0)
553*49cdfc7eSAndroid Build Coastguard Worker --starts;
554*49cdfc7eSAndroid Build Coastguard Worker
555*49cdfc7eSAndroid Build Coastguard Worker if (sequential)
556*49cdfc7eSAndroid Build Coastguard Worker if (++c >= coll->cnt)
557*49cdfc7eSAndroid Build Coastguard Worker c = 0;
558*49cdfc7eSAndroid Build Coastguard Worker
559*49cdfc7eSAndroid Build Coastguard Worker } /* while ((num_active < keep_active) && (starts != 0)) */
560*49cdfc7eSAndroid Build Coastguard Worker
561*49cdfc7eSAndroid Build Coastguard Worker if (starts == 0) {
562*49cdfc7eSAndroid Build Coastguard Worker if (!quiet_mode)
563*49cdfc7eSAndroid Build Coastguard Worker printf("incrementing stop\n");
564*49cdfc7eSAndroid Build Coastguard Worker ++stop;
565*49cdfc7eSAndroid Build Coastguard Worker } else if (starts == -1) //wjh
566*49cdfc7eSAndroid Build Coastguard Worker {
567*49cdfc7eSAndroid Build Coastguard Worker FILE *f = (FILE *) - 1;
568*49cdfc7eSAndroid Build Coastguard Worker if ((f = fopen(PAN_STOP_FILE, "r")) != 0) {
569*49cdfc7eSAndroid Build Coastguard Worker printf("Got %s Stopping!\n", PAN_STOP_FILE);
570*49cdfc7eSAndroid Build Coastguard Worker fclose(f);
571*49cdfc7eSAndroid Build Coastguard Worker unlink(PAN_STOP_FILE);
572*49cdfc7eSAndroid Build Coastguard Worker stop++;
573*49cdfc7eSAndroid Build Coastguard Worker }
574*49cdfc7eSAndroid Build Coastguard Worker }
575*49cdfc7eSAndroid Build Coastguard Worker
576*49cdfc7eSAndroid Build Coastguard Worker if (rec_signal) {
577*49cdfc7eSAndroid Build Coastguard Worker /* propagate everything except sigusr2 */
578*49cdfc7eSAndroid Build Coastguard Worker
579*49cdfc7eSAndroid Build Coastguard Worker if (rec_signal == SIGUSR2) {
580*49cdfc7eSAndroid Build Coastguard Worker if (fork_in_road)
581*49cdfc7eSAndroid Build Coastguard Worker ++go_idle;
582*49cdfc7eSAndroid Build Coastguard Worker else
583*49cdfc7eSAndroid Build Coastguard Worker ++stop;
584*49cdfc7eSAndroid Build Coastguard Worker rec_signal = send_signal = 0;
585*49cdfc7eSAndroid Build Coastguard Worker } else {
586*49cdfc7eSAndroid Build Coastguard Worker if (rec_signal == SIGUSR1)
587*49cdfc7eSAndroid Build Coastguard Worker fork_in_road = 0;
588*49cdfc7eSAndroid Build Coastguard Worker propagate_signal(running, keep_active, orphans);
589*49cdfc7eSAndroid Build Coastguard Worker if (fork_in_road)
590*49cdfc7eSAndroid Build Coastguard Worker ++go_idle;
591*49cdfc7eSAndroid Build Coastguard Worker else
592*49cdfc7eSAndroid Build Coastguard Worker ++stop;
593*49cdfc7eSAndroid Build Coastguard Worker }
594*49cdfc7eSAndroid Build Coastguard Worker }
595*49cdfc7eSAndroid Build Coastguard Worker
596*49cdfc7eSAndroid Build Coastguard Worker err = check_pids(running, &num_active, keep_active, logfile,
597*49cdfc7eSAndroid Build Coastguard Worker failcmdfile, tconfcmdfile, orphans, fmt_print,
598*49cdfc7eSAndroid Build Coastguard Worker &failcnt, &tconfcnt, quiet_mode, no_kmsg);
599*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Drunning) {
600*49cdfc7eSAndroid Build Coastguard Worker pids_running(running, keep_active);
601*49cdfc7eSAndroid Build Coastguard Worker orphans_running(orphans);
602*49cdfc7eSAndroid Build Coastguard Worker }
603*49cdfc7eSAndroid Build Coastguard Worker if (err) {
604*49cdfc7eSAndroid Build Coastguard Worker if (fork_in_road)
605*49cdfc7eSAndroid Build Coastguard Worker ++go_idle;
606*49cdfc7eSAndroid Build Coastguard Worker if (track_exit_stats)
607*49cdfc7eSAndroid Build Coastguard Worker exit_stat++;
608*49cdfc7eSAndroid Build Coastguard Worker if (has_brakes) {
609*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): All stop!%s\n",
610*49cdfc7eSAndroid Build Coastguard Worker panname, go_idle ? " (idling)" : "");
611*49cdfc7eSAndroid Build Coastguard Worker wait_handler(SIGINT);
612*49cdfc7eSAndroid Build Coastguard Worker }
613*49cdfc7eSAndroid Build Coastguard Worker }
614*49cdfc7eSAndroid Build Coastguard Worker
615*49cdfc7eSAndroid Build Coastguard Worker if (stop && (num_active == 0))
616*49cdfc7eSAndroid Build Coastguard Worker break;
617*49cdfc7eSAndroid Build Coastguard Worker
618*49cdfc7eSAndroid Build Coastguard Worker if (go_idle && (num_active == 0)) {
619*49cdfc7eSAndroid Build Coastguard Worker go_idle = 0; /* It is idle, now resume scheduling. */
620*49cdfc7eSAndroid Build Coastguard Worker wait_handler(0); /* Reset the signal ratchet. */
621*49cdfc7eSAndroid Build Coastguard Worker }
622*49cdfc7eSAndroid Build Coastguard Worker }
623*49cdfc7eSAndroid Build Coastguard Worker
624*49cdfc7eSAndroid Build Coastguard Worker /* Wait for orphaned pgrps */
625*49cdfc7eSAndroid Build Coastguard Worker while (1) {
626*49cdfc7eSAndroid Build Coastguard Worker for (orph = orphans; orph != NULL; orph = orph->next) {
627*49cdfc7eSAndroid Build Coastguard Worker if (orph->pgrp == 0)
628*49cdfc7eSAndroid Build Coastguard Worker continue;
629*49cdfc7eSAndroid Build Coastguard Worker /* Yes, we have orphaned pgrps */
630*49cdfc7eSAndroid Build Coastguard Worker sleep(5);
631*49cdfc7eSAndroid Build Coastguard Worker if (!rec_signal) {
632*49cdfc7eSAndroid Build Coastguard Worker /* force an artificial signal, move us
633*49cdfc7eSAndroid Build Coastguard Worker * through the signal ratchet.
634*49cdfc7eSAndroid Build Coastguard Worker */
635*49cdfc7eSAndroid Build Coastguard Worker wait_handler(SIGINT);
636*49cdfc7eSAndroid Build Coastguard Worker }
637*49cdfc7eSAndroid Build Coastguard Worker propagate_signal(running, keep_active, orphans);
638*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Drunning)
639*49cdfc7eSAndroid Build Coastguard Worker orphans_running(orphans);
640*49cdfc7eSAndroid Build Coastguard Worker break;
641*49cdfc7eSAndroid Build Coastguard Worker }
642*49cdfc7eSAndroid Build Coastguard Worker if (orph == NULL)
643*49cdfc7eSAndroid Build Coastguard Worker break;
644*49cdfc7eSAndroid Build Coastguard Worker }
645*49cdfc7eSAndroid Build Coastguard Worker
646*49cdfc7eSAndroid Build Coastguard Worker if (zoo_clear(zoofile, getpid())) {
647*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): %s\n", panname, zoo_error);
648*49cdfc7eSAndroid Build Coastguard Worker ++exit_stat;
649*49cdfc7eSAndroid Build Coastguard Worker }
650*49cdfc7eSAndroid Build Coastguard Worker fclose(zoofile);
651*49cdfc7eSAndroid Build Coastguard Worker if (logfile && fmt_print) {
652*49cdfc7eSAndroid Build Coastguard Worker if (uname(&unamebuf) == -1)
653*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "ERROR: uname(): %s\n",
654*49cdfc7eSAndroid Build Coastguard Worker strerror(errno));
655*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile,
656*49cdfc7eSAndroid Build Coastguard Worker "\n-----------------------------------------------\n");
657*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, "Total Tests: %d\n", coll->cnt);
658*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, "Total Skipped Tests: %d\n", tconfcnt);
659*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, "Total Failures: %d\n", failcnt);
660*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, "Kernel Version: %s\n", unamebuf.release);
661*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, "Machine Architecture: %s\n",
662*49cdfc7eSAndroid Build Coastguard Worker unamebuf.machine);
663*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, "Hostname: %s\n\n", unamebuf.nodename);
664*49cdfc7eSAndroid Build Coastguard Worker }
665*49cdfc7eSAndroid Build Coastguard Worker if (logfile && (logfile != stdout))
666*49cdfc7eSAndroid Build Coastguard Worker fclose(logfile);
667*49cdfc7eSAndroid Build Coastguard Worker
668*49cdfc7eSAndroid Build Coastguard Worker if (failcmdfile)
669*49cdfc7eSAndroid Build Coastguard Worker fclose(failcmdfile);
670*49cdfc7eSAndroid Build Coastguard Worker
671*49cdfc7eSAndroid Build Coastguard Worker if (tconfcmdfile)
672*49cdfc7eSAndroid Build Coastguard Worker fclose(tconfcmdfile);
673*49cdfc7eSAndroid Build Coastguard Worker exit(exit_stat);
674*49cdfc7eSAndroid Build Coastguard Worker }
675*49cdfc7eSAndroid Build Coastguard Worker
676*49cdfc7eSAndroid Build Coastguard Worker static void
propagate_signal(struct tag_pgrp * running,int keep_active,struct orphan_pgrp * orphans)677*49cdfc7eSAndroid Build Coastguard Worker propagate_signal(struct tag_pgrp *running, int keep_active,
678*49cdfc7eSAndroid Build Coastguard Worker struct orphan_pgrp *orphans)
679*49cdfc7eSAndroid Build Coastguard Worker {
680*49cdfc7eSAndroid Build Coastguard Worker int i;
681*49cdfc7eSAndroid Build Coastguard Worker
682*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Dshutdown)
683*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan was signaled with sig %d...\n",
684*49cdfc7eSAndroid Build Coastguard Worker rec_signal);
685*49cdfc7eSAndroid Build Coastguard Worker
686*49cdfc7eSAndroid Build Coastguard Worker if (rec_signal == SIGALRM) {
687*49cdfc7eSAndroid Build Coastguard Worker printf("PAN stop Alarm was received\n");
688*49cdfc7eSAndroid Build Coastguard Worker rec_signal = SIGTERM;
689*49cdfc7eSAndroid Build Coastguard Worker }
690*49cdfc7eSAndroid Build Coastguard Worker
691*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < keep_active; ++i) {
692*49cdfc7eSAndroid Build Coastguard Worker if (running[i].pgrp == 0)
693*49cdfc7eSAndroid Build Coastguard Worker continue;
694*49cdfc7eSAndroid Build Coastguard Worker
695*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Dshutdown)
696*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, " propagating sig %d to %d\n",
697*49cdfc7eSAndroid Build Coastguard Worker send_signal, -running[i].pgrp);
698*49cdfc7eSAndroid Build Coastguard Worker if (kill(-running[i].pgrp, send_signal) != 0) {
699*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
700*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): kill(%d,%d) failed on tag (%s). errno:%d %s\n",
701*49cdfc7eSAndroid Build Coastguard Worker panname, -running[i].pgrp, send_signal,
702*49cdfc7eSAndroid Build Coastguard Worker running[i].cmd->name, errno, strerror(errno));
703*49cdfc7eSAndroid Build Coastguard Worker }
704*49cdfc7eSAndroid Build Coastguard Worker running[i].stopping = 1;
705*49cdfc7eSAndroid Build Coastguard Worker }
706*49cdfc7eSAndroid Build Coastguard Worker
707*49cdfc7eSAndroid Build Coastguard Worker check_orphans(orphans, send_signal);
708*49cdfc7eSAndroid Build Coastguard Worker
709*49cdfc7eSAndroid Build Coastguard Worker rec_signal = send_signal = 0;
710*49cdfc7eSAndroid Build Coastguard Worker }
711*49cdfc7eSAndroid Build Coastguard Worker
712*49cdfc7eSAndroid Build Coastguard Worker static int
check_pids(struct tag_pgrp * running,int * num_active,int keep_active,FILE * logfile,FILE * failcmdfile,FILE * tconfcmdfile,struct orphan_pgrp * orphans,int fmt_print,int * failcnt,int * tconfcnt,int quiet_mode,int no_kmsg)713*49cdfc7eSAndroid Build Coastguard Worker check_pids(struct tag_pgrp *running, int *num_active, int keep_active,
714*49cdfc7eSAndroid Build Coastguard Worker FILE *logfile, FILE *failcmdfile, FILE *tconfcmdfile,
715*49cdfc7eSAndroid Build Coastguard Worker struct orphan_pgrp *orphans, int fmt_print, int *failcnt,
716*49cdfc7eSAndroid Build Coastguard Worker int *tconfcnt, int quiet_mode, int no_kmsg)
717*49cdfc7eSAndroid Build Coastguard Worker {
718*49cdfc7eSAndroid Build Coastguard Worker int w;
719*49cdfc7eSAndroid Build Coastguard Worker pid_t cpid;
720*49cdfc7eSAndroid Build Coastguard Worker int stat_loc;
721*49cdfc7eSAndroid Build Coastguard Worker int ret = 0;
722*49cdfc7eSAndroid Build Coastguard Worker int i;
723*49cdfc7eSAndroid Build Coastguard Worker time_t t;
724*49cdfc7eSAndroid Build Coastguard Worker char *status;
725*49cdfc7eSAndroid Build Coastguard Worker char *result_str;
726*49cdfc7eSAndroid Build Coastguard Worker int signaled = 0;
727*49cdfc7eSAndroid Build Coastguard Worker struct tms tms1, tms2;
728*49cdfc7eSAndroid Build Coastguard Worker clock_t tck;
729*49cdfc7eSAndroid Build Coastguard Worker
730*49cdfc7eSAndroid Build Coastguard Worker check_orphans(orphans, 0);
731*49cdfc7eSAndroid Build Coastguard Worker
732*49cdfc7eSAndroid Build Coastguard Worker tck = times(&tms1);
733*49cdfc7eSAndroid Build Coastguard Worker if (tck == -1) {
734*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): times(&tms1) failed. errno:%d %s\n",
735*49cdfc7eSAndroid Build Coastguard Worker panname, errno, strerror(errno));
736*49cdfc7eSAndroid Build Coastguard Worker }
737*49cdfc7eSAndroid Build Coastguard Worker cpid = wait(&stat_loc);
738*49cdfc7eSAndroid Build Coastguard Worker tck = times(&tms2);
739*49cdfc7eSAndroid Build Coastguard Worker if (tck == -1) {
740*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): times(&tms2) failed. errno:%d %s\n",
741*49cdfc7eSAndroid Build Coastguard Worker panname, errno, strerror(errno));
742*49cdfc7eSAndroid Build Coastguard Worker }
743*49cdfc7eSAndroid Build Coastguard Worker
744*49cdfc7eSAndroid Build Coastguard Worker if (cpid < 0) {
745*49cdfc7eSAndroid Build Coastguard Worker if (errno == EINTR) {
746*49cdfc7eSAndroid Build Coastguard Worker if (Debug)
747*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): wait() interrupted\n",
748*49cdfc7eSAndroid Build Coastguard Worker panname);
749*49cdfc7eSAndroid Build Coastguard Worker } else if (errno != ECHILD) {
750*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
751*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): wait() failed. errno:%d %s\n",
752*49cdfc7eSAndroid Build Coastguard Worker panname, errno, strerror(errno));
753*49cdfc7eSAndroid Build Coastguard Worker }
754*49cdfc7eSAndroid Build Coastguard Worker } else if (cpid > 0) {
755*49cdfc7eSAndroid Build Coastguard Worker
756*49cdfc7eSAndroid Build Coastguard Worker if (WIFSIGNALED(stat_loc)) {
757*49cdfc7eSAndroid Build Coastguard Worker w = WTERMSIG(stat_loc);
758*49cdfc7eSAndroid Build Coastguard Worker status = "signaled";
759*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Dexit)
760*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
761*49cdfc7eSAndroid Build Coastguard Worker "child %d terminated with signal %d\n",
762*49cdfc7eSAndroid Build Coastguard Worker cpid, w);
763*49cdfc7eSAndroid Build Coastguard Worker --*num_active;
764*49cdfc7eSAndroid Build Coastguard Worker signaled = 1;
765*49cdfc7eSAndroid Build Coastguard Worker } else if (WIFEXITED(stat_loc)) {
766*49cdfc7eSAndroid Build Coastguard Worker w = WEXITSTATUS(stat_loc);
767*49cdfc7eSAndroid Build Coastguard Worker status = "exited";
768*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Dexit)
769*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
770*49cdfc7eSAndroid Build Coastguard Worker "child %d exited with status %d\n",
771*49cdfc7eSAndroid Build Coastguard Worker cpid, w);
772*49cdfc7eSAndroid Build Coastguard Worker --*num_active;
773*49cdfc7eSAndroid Build Coastguard Worker if (w != 0 && w != TCONF)
774*49cdfc7eSAndroid Build Coastguard Worker ret++;
775*49cdfc7eSAndroid Build Coastguard Worker } else if (WIFSTOPPED(stat_loc)) { /* should never happen */
776*49cdfc7eSAndroid Build Coastguard Worker w = WSTOPSIG(stat_loc);
777*49cdfc7eSAndroid Build Coastguard Worker status = "stopped";
778*49cdfc7eSAndroid Build Coastguard Worker ret++;
779*49cdfc7eSAndroid Build Coastguard Worker } else { /* should never happen */
780*49cdfc7eSAndroid Build Coastguard Worker w = 0;
781*49cdfc7eSAndroid Build Coastguard Worker status = "unknown";
782*49cdfc7eSAndroid Build Coastguard Worker ret++;
783*49cdfc7eSAndroid Build Coastguard Worker }
784*49cdfc7eSAndroid Build Coastguard Worker
785*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < keep_active; ++i) {
786*49cdfc7eSAndroid Build Coastguard Worker if (running[i].pgrp == cpid) {
787*49cdfc7eSAndroid Build Coastguard Worker if ((w == 130) && running[i].stopping &&
788*49cdfc7eSAndroid Build Coastguard Worker (strcmp(status, "exited") == 0)) {
789*49cdfc7eSAndroid Build Coastguard Worker /* The child received sigint, but
790*49cdfc7eSAndroid Build Coastguard Worker * did not trap for it? Compensate
791*49cdfc7eSAndroid Build Coastguard Worker * for it here.
792*49cdfc7eSAndroid Build Coastguard Worker */
793*49cdfc7eSAndroid Build Coastguard Worker w = 0;
794*49cdfc7eSAndroid Build Coastguard Worker ret--; /* undo */
795*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Drunning)
796*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
797*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): tag=%s exited 130, known to be signaled; will give it an exit 0.\n",
798*49cdfc7eSAndroid Build Coastguard Worker panname,
799*49cdfc7eSAndroid Build Coastguard Worker running[i].cmd->name);
800*49cdfc7eSAndroid Build Coastguard Worker }
801*49cdfc7eSAndroid Build Coastguard Worker time(&t);
802*49cdfc7eSAndroid Build Coastguard Worker if (logfile != NULL) {
803*49cdfc7eSAndroid Build Coastguard Worker if (!fmt_print)
804*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile,
805*49cdfc7eSAndroid Build Coastguard Worker "tag=%s stime=%d dur=%d exit=%s stat=%d core=%s cu=%d cs=%d\n",
806*49cdfc7eSAndroid Build Coastguard Worker running[i].cmd->name,
807*49cdfc7eSAndroid Build Coastguard Worker (int)(running[i].
808*49cdfc7eSAndroid Build Coastguard Worker mystime),
809*49cdfc7eSAndroid Build Coastguard Worker (int)(t -
810*49cdfc7eSAndroid Build Coastguard Worker running[i].
811*49cdfc7eSAndroid Build Coastguard Worker mystime), status,
812*49cdfc7eSAndroid Build Coastguard Worker w,
813*49cdfc7eSAndroid Build Coastguard Worker (stat_loc & 0200) ?
814*49cdfc7eSAndroid Build Coastguard Worker "yes" : "no",
815*49cdfc7eSAndroid Build Coastguard Worker (int)(tms2.tms_cutime -
816*49cdfc7eSAndroid Build Coastguard Worker tms1.tms_cutime),
817*49cdfc7eSAndroid Build Coastguard Worker (int)(tms2.tms_cstime -
818*49cdfc7eSAndroid Build Coastguard Worker tms1.tms_cstime));
819*49cdfc7eSAndroid Build Coastguard Worker else {
820*49cdfc7eSAndroid Build Coastguard Worker if (strcmp(status, "exited") ==
821*49cdfc7eSAndroid Build Coastguard Worker 0 && w == TCONF) {
822*49cdfc7eSAndroid Build Coastguard Worker ++*tconfcnt;
823*49cdfc7eSAndroid Build Coastguard Worker result_str = "CONF";
824*49cdfc7eSAndroid Build Coastguard Worker } else if (w != 0) {
825*49cdfc7eSAndroid Build Coastguard Worker ++*failcnt;
826*49cdfc7eSAndroid Build Coastguard Worker result_str = "FAIL";
827*49cdfc7eSAndroid Build Coastguard Worker } else {
828*49cdfc7eSAndroid Build Coastguard Worker result_str = "PASS";
829*49cdfc7eSAndroid Build Coastguard Worker }
830*49cdfc7eSAndroid Build Coastguard Worker
831*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile,
832*49cdfc7eSAndroid Build Coastguard Worker ResultFmt" %-5d\n",
833*49cdfc7eSAndroid Build Coastguard Worker running[i].cmd->name,
834*49cdfc7eSAndroid Build Coastguard Worker result_str,
835*49cdfc7eSAndroid Build Coastguard Worker w);
836*49cdfc7eSAndroid Build Coastguard Worker }
837*49cdfc7eSAndroid Build Coastguard Worker
838*49cdfc7eSAndroid Build Coastguard Worker fflush(logfile);
839*49cdfc7eSAndroid Build Coastguard Worker }
840*49cdfc7eSAndroid Build Coastguard Worker
841*49cdfc7eSAndroid Build Coastguard Worker if (w != 0) {
842*49cdfc7eSAndroid Build Coastguard Worker if (tconfcmdfile != NULL &&
843*49cdfc7eSAndroid Build Coastguard Worker w == TCONF) {
844*49cdfc7eSAndroid Build Coastguard Worker fprintf(tconfcmdfile, "%s %s\n",
845*49cdfc7eSAndroid Build Coastguard Worker running[i].cmd->name,
846*49cdfc7eSAndroid Build Coastguard Worker running[i].cmd->cmdline);
847*49cdfc7eSAndroid Build Coastguard Worker } else if (failcmdfile != NULL) {
848*49cdfc7eSAndroid Build Coastguard Worker fprintf(failcmdfile, "%s %s\n",
849*49cdfc7eSAndroid Build Coastguard Worker running[i].cmd->name,
850*49cdfc7eSAndroid Build Coastguard Worker running[i].cmd->cmdline);
851*49cdfc7eSAndroid Build Coastguard Worker }
852*49cdfc7eSAndroid Build Coastguard Worker }
853*49cdfc7eSAndroid Build Coastguard Worker
854*49cdfc7eSAndroid Build Coastguard Worker if (running[i].stopping)
855*49cdfc7eSAndroid Build Coastguard Worker status = "driver_interrupt";
856*49cdfc7eSAndroid Build Coastguard Worker
857*49cdfc7eSAndroid Build Coastguard Worker if (test_out_dir) {
858*49cdfc7eSAndroid Build Coastguard Worker if (!quiet_mode)
859*49cdfc7eSAndroid Build Coastguard Worker write_test_start(running + i, no_kmsg);
860*49cdfc7eSAndroid Build Coastguard Worker copy_buffered_output(running + i);
861*49cdfc7eSAndroid Build Coastguard Worker unlink(running[i].output);
862*49cdfc7eSAndroid Build Coastguard Worker }
863*49cdfc7eSAndroid Build Coastguard Worker if (!quiet_mode)
864*49cdfc7eSAndroid Build Coastguard Worker write_test_end(running + i, "ok", t,
865*49cdfc7eSAndroid Build Coastguard Worker status, stat_loc, w,
866*49cdfc7eSAndroid Build Coastguard Worker &tms1, &tms2);
867*49cdfc7eSAndroid Build Coastguard Worker
868*49cdfc7eSAndroid Build Coastguard Worker /* If signaled and we weren't expecting
869*49cdfc7eSAndroid Build Coastguard Worker * this to be stopped then the proc
870*49cdfc7eSAndroid Build Coastguard Worker * had a problem.
871*49cdfc7eSAndroid Build Coastguard Worker */
872*49cdfc7eSAndroid Build Coastguard Worker if (signaled && !running[i].stopping)
873*49cdfc7eSAndroid Build Coastguard Worker ret++;
874*49cdfc7eSAndroid Build Coastguard Worker
875*49cdfc7eSAndroid Build Coastguard Worker running[i].pgrp = 0;
876*49cdfc7eSAndroid Build Coastguard Worker if (zoo_clear(zoofile, cpid)) {
877*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): %s\n",
878*49cdfc7eSAndroid Build Coastguard Worker panname, zoo_error);
879*49cdfc7eSAndroid Build Coastguard Worker exit(1);
880*49cdfc7eSAndroid Build Coastguard Worker }
881*49cdfc7eSAndroid Build Coastguard Worker
882*49cdfc7eSAndroid Build Coastguard Worker /* Check for orphaned pgrps */
883*49cdfc7eSAndroid Build Coastguard Worker if ((kill(-cpid, 0) == 0) || (errno == EPERM)) {
884*49cdfc7eSAndroid Build Coastguard Worker if (zoo_mark_cmdline
885*49cdfc7eSAndroid Build Coastguard Worker (zoofile, cpid, "panorphan",
886*49cdfc7eSAndroid Build Coastguard Worker running[i].cmd->cmdline)) {
887*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): %s\n",
888*49cdfc7eSAndroid Build Coastguard Worker panname, zoo_error);
889*49cdfc7eSAndroid Build Coastguard Worker exit(1);
890*49cdfc7eSAndroid Build Coastguard Worker }
891*49cdfc7eSAndroid Build Coastguard Worker mark_orphan(orphans, cpid);
892*49cdfc7eSAndroid Build Coastguard Worker /* status of kill doesn't matter */
893*49cdfc7eSAndroid Build Coastguard Worker kill(-cpid, SIGTERM);
894*49cdfc7eSAndroid Build Coastguard Worker }
895*49cdfc7eSAndroid Build Coastguard Worker
896*49cdfc7eSAndroid Build Coastguard Worker break;
897*49cdfc7eSAndroid Build Coastguard Worker }
898*49cdfc7eSAndroid Build Coastguard Worker }
899*49cdfc7eSAndroid Build Coastguard Worker }
900*49cdfc7eSAndroid Build Coastguard Worker return ret;
901*49cdfc7eSAndroid Build Coastguard Worker }
902*49cdfc7eSAndroid Build Coastguard Worker
903*49cdfc7eSAndroid Build Coastguard Worker static pid_t
run_child(struct coll_entry * colle,struct tag_pgrp * active,int quiet_mode,int * failcnt,int fmt_print,FILE * logfile,int no_kmsg)904*49cdfc7eSAndroid Build Coastguard Worker run_child(struct coll_entry *colle, struct tag_pgrp *active, int quiet_mode,
905*49cdfc7eSAndroid Build Coastguard Worker int *failcnt, int fmt_print, FILE * logfile, int no_kmsg)
906*49cdfc7eSAndroid Build Coastguard Worker {
907*49cdfc7eSAndroid Build Coastguard Worker ssize_t errlen;
908*49cdfc7eSAndroid Build Coastguard Worker int cpid;
909*49cdfc7eSAndroid Build Coastguard Worker int c_stdout = -1; /* child's stdout, stderr */
910*49cdfc7eSAndroid Build Coastguard Worker int capturing = 0; /* output is going to a file instead of stdout */
911*49cdfc7eSAndroid Build Coastguard Worker char *c_cmdline;
912*49cdfc7eSAndroid Build Coastguard Worker static long cmdno = 0;
913*49cdfc7eSAndroid Build Coastguard Worker int errpipe[2]; /* way to communicate to parent that the tag */
914*49cdfc7eSAndroid Build Coastguard Worker char errbuf[1024]; /* didn't actually start */
915*49cdfc7eSAndroid Build Coastguard Worker
916*49cdfc7eSAndroid Build Coastguard Worker /* Try to open the file that will be stdout for the test */
917*49cdfc7eSAndroid Build Coastguard Worker if (test_out_dir) {
918*49cdfc7eSAndroid Build Coastguard Worker capturing = 1;
919*49cdfc7eSAndroid Build Coastguard Worker do {
920*49cdfc7eSAndroid Build Coastguard Worker sprintf(active->output, "%s/%s.%ld",
921*49cdfc7eSAndroid Build Coastguard Worker test_out_dir, colle->name, cmdno++);
922*49cdfc7eSAndroid Build Coastguard Worker c_stdout =
923*49cdfc7eSAndroid Build Coastguard Worker open(active->output,
924*49cdfc7eSAndroid Build Coastguard Worker O_CREAT | O_RDWR | O_EXCL | O_SYNC, 0666);
925*49cdfc7eSAndroid Build Coastguard Worker } while (c_stdout < 0 && errno == EEXIST);
926*49cdfc7eSAndroid Build Coastguard Worker if (c_stdout < 0) {
927*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
928*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): open of stdout file failed (tag %s). errno: %d %s\n file: %s\n",
929*49cdfc7eSAndroid Build Coastguard Worker panname, colle->name, errno, strerror(errno),
930*49cdfc7eSAndroid Build Coastguard Worker active->output);
931*49cdfc7eSAndroid Build Coastguard Worker return -1;
932*49cdfc7eSAndroid Build Coastguard Worker }
933*49cdfc7eSAndroid Build Coastguard Worker }
934*49cdfc7eSAndroid Build Coastguard Worker
935*49cdfc7eSAndroid Build Coastguard Worker /* get the tag's command line arguments ready. subst_pcnt_f() uses a
936*49cdfc7eSAndroid Build Coastguard Worker * static counter, that's why we do it here instead of after we fork.
937*49cdfc7eSAndroid Build Coastguard Worker */
938*49cdfc7eSAndroid Build Coastguard Worker if (colle->pcnt_f) {
939*49cdfc7eSAndroid Build Coastguard Worker c_cmdline = subst_pcnt_f(colle);
940*49cdfc7eSAndroid Build Coastguard Worker } else {
941*49cdfc7eSAndroid Build Coastguard Worker c_cmdline = colle->cmdline;
942*49cdfc7eSAndroid Build Coastguard Worker }
943*49cdfc7eSAndroid Build Coastguard Worker
944*49cdfc7eSAndroid Build Coastguard Worker if (pipe(errpipe) < 0) {
945*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): pipe() failed. errno:%d %s\n",
946*49cdfc7eSAndroid Build Coastguard Worker panname, errno, strerror(errno));
947*49cdfc7eSAndroid Build Coastguard Worker if (capturing) {
948*49cdfc7eSAndroid Build Coastguard Worker close(c_stdout);
949*49cdfc7eSAndroid Build Coastguard Worker unlink(active->output);
950*49cdfc7eSAndroid Build Coastguard Worker }
951*49cdfc7eSAndroid Build Coastguard Worker return -1;
952*49cdfc7eSAndroid Build Coastguard Worker }
953*49cdfc7eSAndroid Build Coastguard Worker
954*49cdfc7eSAndroid Build Coastguard Worker time(&active->mystime);
955*49cdfc7eSAndroid Build Coastguard Worker active->cmd = colle;
956*49cdfc7eSAndroid Build Coastguard Worker
957*49cdfc7eSAndroid Build Coastguard Worker if (!test_out_dir && !quiet_mode)
958*49cdfc7eSAndroid Build Coastguard Worker write_test_start(active, no_kmsg);
959*49cdfc7eSAndroid Build Coastguard Worker
960*49cdfc7eSAndroid Build Coastguard Worker fflush(NULL);
961*49cdfc7eSAndroid Build Coastguard Worker
962*49cdfc7eSAndroid Build Coastguard Worker if ((cpid = fork()) == -1) {
963*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
964*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): fork failed (tag %s). errno:%d %s\n",
965*49cdfc7eSAndroid Build Coastguard Worker panname, colle->name, errno, strerror(errno));
966*49cdfc7eSAndroid Build Coastguard Worker if (capturing) {
967*49cdfc7eSAndroid Build Coastguard Worker unlink(active->output);
968*49cdfc7eSAndroid Build Coastguard Worker close(c_stdout);
969*49cdfc7eSAndroid Build Coastguard Worker }
970*49cdfc7eSAndroid Build Coastguard Worker close(errpipe[0]);
971*49cdfc7eSAndroid Build Coastguard Worker close(errpipe[1]);
972*49cdfc7eSAndroid Build Coastguard Worker return -1;
973*49cdfc7eSAndroid Build Coastguard Worker } else if (cpid == 0) {
974*49cdfc7eSAndroid Build Coastguard Worker /* child */
975*49cdfc7eSAndroid Build Coastguard Worker
976*49cdfc7eSAndroid Build Coastguard Worker fclose(zoofile);
977*49cdfc7eSAndroid Build Coastguard Worker close(errpipe[0]);
978*49cdfc7eSAndroid Build Coastguard Worker fcntl(errpipe[1], F_SETFD, 1); /* close the pipe if we succeed */
979*49cdfc7eSAndroid Build Coastguard Worker setpgrp();
980*49cdfc7eSAndroid Build Coastguard Worker
981*49cdfc7eSAndroid Build Coastguard Worker umask(0);
982*49cdfc7eSAndroid Build Coastguard Worker
983*49cdfc7eSAndroid Build Coastguard Worker #define WRITE_OR_DIE(fd, buf, buflen) do { \
984*49cdfc7eSAndroid Build Coastguard Worker if (write((fd), (buf), (buflen)) != (buflen)) { \
985*49cdfc7eSAndroid Build Coastguard Worker err(1, "failed to write out %zd bytes at line %d", \
986*49cdfc7eSAndroid Build Coastguard Worker buflen, __LINE__); \
987*49cdfc7eSAndroid Build Coastguard Worker } \
988*49cdfc7eSAndroid Build Coastguard Worker } while(0)
989*49cdfc7eSAndroid Build Coastguard Worker
990*49cdfc7eSAndroid Build Coastguard Worker /* if we're putting output into a buffer file, we need to do the
991*49cdfc7eSAndroid Build Coastguard Worker * redirection now. If we fail
992*49cdfc7eSAndroid Build Coastguard Worker */
993*49cdfc7eSAndroid Build Coastguard Worker if (capturing) {
994*49cdfc7eSAndroid Build Coastguard Worker if (dup2(c_stdout, fileno(stdout)) == -1) {
995*49cdfc7eSAndroid Build Coastguard Worker errlen =
996*49cdfc7eSAndroid Build Coastguard Worker sprintf(errbuf,
997*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): couldn't redirect stdout for tag %s. errno:%d %s",
998*49cdfc7eSAndroid Build Coastguard Worker panname, colle->name, errno,
999*49cdfc7eSAndroid Build Coastguard Worker strerror(errno));
1000*49cdfc7eSAndroid Build Coastguard Worker WRITE_OR_DIE(errpipe[1], &errlen,
1001*49cdfc7eSAndroid Build Coastguard Worker sizeof(errlen));
1002*49cdfc7eSAndroid Build Coastguard Worker WRITE_OR_DIE(errpipe[1], errbuf, errlen);
1003*49cdfc7eSAndroid Build Coastguard Worker exit(2);
1004*49cdfc7eSAndroid Build Coastguard Worker }
1005*49cdfc7eSAndroid Build Coastguard Worker if (dup2(c_stdout, fileno(stderr)) == -1) {
1006*49cdfc7eSAndroid Build Coastguard Worker errlen =
1007*49cdfc7eSAndroid Build Coastguard Worker sprintf(errbuf,
1008*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): couldn't redirect stderr for tag %s. errno:%d %s",
1009*49cdfc7eSAndroid Build Coastguard Worker panname, colle->name, errno,
1010*49cdfc7eSAndroid Build Coastguard Worker strerror(errno));
1011*49cdfc7eSAndroid Build Coastguard Worker WRITE_OR_DIE(errpipe[1], &errlen,
1012*49cdfc7eSAndroid Build Coastguard Worker sizeof(errlen));
1013*49cdfc7eSAndroid Build Coastguard Worker WRITE_OR_DIE(errpipe[1], errbuf, errlen);
1014*49cdfc7eSAndroid Build Coastguard Worker exit(2);
1015*49cdfc7eSAndroid Build Coastguard Worker }
1016*49cdfc7eSAndroid Build Coastguard Worker } else { /* stderr still needs to be redirected */
1017*49cdfc7eSAndroid Build Coastguard Worker if (dup2(fileno(stdout), fileno(stderr)) == -1) {
1018*49cdfc7eSAndroid Build Coastguard Worker errlen =
1019*49cdfc7eSAndroid Build Coastguard Worker sprintf(errbuf,
1020*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): couldn't redirect stderr for tag %s. errno:%d %s",
1021*49cdfc7eSAndroid Build Coastguard Worker panname, colle->name, errno,
1022*49cdfc7eSAndroid Build Coastguard Worker strerror(errno));
1023*49cdfc7eSAndroid Build Coastguard Worker WRITE_OR_DIE(errpipe[1], &errlen,
1024*49cdfc7eSAndroid Build Coastguard Worker sizeof(errlen));
1025*49cdfc7eSAndroid Build Coastguard Worker WRITE_OR_DIE(errpipe[1], errbuf, errlen);
1026*49cdfc7eSAndroid Build Coastguard Worker exit(2);
1027*49cdfc7eSAndroid Build Coastguard Worker }
1028*49cdfc7eSAndroid Build Coastguard Worker }
1029*49cdfc7eSAndroid Build Coastguard Worker /* If there are any shell-type characters in the cmdline
1030*49cdfc7eSAndroid Build Coastguard Worker * such as '>', '<', '$', '|', etc, then we exec a shell and
1031*49cdfc7eSAndroid Build Coastguard Worker * run the cmd under a shell.
1032*49cdfc7eSAndroid Build Coastguard Worker *
1033*49cdfc7eSAndroid Build Coastguard Worker * Otherwise, break the cmdline at white space and exec the
1034*49cdfc7eSAndroid Build Coastguard Worker * cmd directly.
1035*49cdfc7eSAndroid Build Coastguard Worker */
1036*49cdfc7eSAndroid Build Coastguard Worker if (strpbrk(c_cmdline, "\"';|<>$\\")) {
1037*49cdfc7eSAndroid Build Coastguard Worker execlp("sh", "sh", "-c", c_cmdline, NULL);
1038*49cdfc7eSAndroid Build Coastguard Worker errlen = sprintf(errbuf,
1039*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): execlp of '%s' (tag %s) failed. errno:%d %s",
1040*49cdfc7eSAndroid Build Coastguard Worker panname, c_cmdline, colle->name, errno,
1041*49cdfc7eSAndroid Build Coastguard Worker strerror(errno));
1042*49cdfc7eSAndroid Build Coastguard Worker } else {
1043*49cdfc7eSAndroid Build Coastguard Worker char **arg_v;
1044*49cdfc7eSAndroid Build Coastguard Worker
1045*49cdfc7eSAndroid Build Coastguard Worker arg_v = (char **)splitstr(c_cmdline, NULL, NULL);
1046*49cdfc7eSAndroid Build Coastguard Worker
1047*49cdfc7eSAndroid Build Coastguard Worker execvp(arg_v[0], arg_v);
1048*49cdfc7eSAndroid Build Coastguard Worker errlen = sprintf(errbuf,
1049*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): execvp of '%s' (tag %s) failed. errno:%d %s",
1050*49cdfc7eSAndroid Build Coastguard Worker panname, arg_v[0], colle->name, errno,
1051*49cdfc7eSAndroid Build Coastguard Worker strerror(errno));
1052*49cdfc7eSAndroid Build Coastguard Worker }
1053*49cdfc7eSAndroid Build Coastguard Worker WRITE_OR_DIE(errpipe[1], &errlen, sizeof(errlen));
1054*49cdfc7eSAndroid Build Coastguard Worker WRITE_OR_DIE(errpipe[1], errbuf, errlen);
1055*49cdfc7eSAndroid Build Coastguard Worker exit(errno);
1056*49cdfc7eSAndroid Build Coastguard Worker }
1057*49cdfc7eSAndroid Build Coastguard Worker
1058*49cdfc7eSAndroid Build Coastguard Worker /* parent */
1059*49cdfc7eSAndroid Build Coastguard Worker
1060*49cdfc7eSAndroid Build Coastguard Worker /* subst_pcnt_f() allocates the command line dynamically
1061*49cdfc7eSAndroid Build Coastguard Worker * free the malloc to prevent a memory leak
1062*49cdfc7eSAndroid Build Coastguard Worker */
1063*49cdfc7eSAndroid Build Coastguard Worker if (colle->pcnt_f)
1064*49cdfc7eSAndroid Build Coastguard Worker free(c_cmdline);
1065*49cdfc7eSAndroid Build Coastguard Worker
1066*49cdfc7eSAndroid Build Coastguard Worker close(errpipe[1]);
1067*49cdfc7eSAndroid Build Coastguard Worker
1068*49cdfc7eSAndroid Build Coastguard Worker /* if the child couldn't go through with the exec,
1069*49cdfc7eSAndroid Build Coastguard Worker * clean up the mess, note it, and move on
1070*49cdfc7eSAndroid Build Coastguard Worker */
1071*49cdfc7eSAndroid Build Coastguard Worker if (read(errpipe[0], &errlen, sizeof(errlen))) {
1072*49cdfc7eSAndroid Build Coastguard Worker int status;
1073*49cdfc7eSAndroid Build Coastguard Worker time_t end_time;
1074*49cdfc7eSAndroid Build Coastguard Worker int termid;
1075*49cdfc7eSAndroid Build Coastguard Worker char *termtype;
1076*49cdfc7eSAndroid Build Coastguard Worker struct tms notime = { 0, 0, 0, 0 };
1077*49cdfc7eSAndroid Build Coastguard Worker
1078*49cdfc7eSAndroid Build Coastguard Worker if (read(errpipe[0], errbuf, errlen) < 0)
1079*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "Failed to read from errpipe[0]\n");
1080*49cdfc7eSAndroid Build Coastguard Worker close(errpipe[0]);
1081*49cdfc7eSAndroid Build Coastguard Worker errbuf[errlen] = '\0';
1082*49cdfc7eSAndroid Build Coastguard Worker /* fprintf(stderr, "%s", errbuf); */
1083*49cdfc7eSAndroid Build Coastguard Worker waitpid(cpid, &status, 0);
1084*49cdfc7eSAndroid Build Coastguard Worker if (WIFSIGNALED(status)) {
1085*49cdfc7eSAndroid Build Coastguard Worker termid = WTERMSIG(status);
1086*49cdfc7eSAndroid Build Coastguard Worker termtype = "signaled";
1087*49cdfc7eSAndroid Build Coastguard Worker } else if (WIFEXITED(status)) {
1088*49cdfc7eSAndroid Build Coastguard Worker termid = WEXITSTATUS(status);
1089*49cdfc7eSAndroid Build Coastguard Worker termtype = "exited";
1090*49cdfc7eSAndroid Build Coastguard Worker } else if (WIFSTOPPED(status)) {
1091*49cdfc7eSAndroid Build Coastguard Worker termid = WSTOPSIG(status);
1092*49cdfc7eSAndroid Build Coastguard Worker termtype = "stopped";
1093*49cdfc7eSAndroid Build Coastguard Worker } else {
1094*49cdfc7eSAndroid Build Coastguard Worker termid = 0;
1095*49cdfc7eSAndroid Build Coastguard Worker termtype = "unknown";
1096*49cdfc7eSAndroid Build Coastguard Worker }
1097*49cdfc7eSAndroid Build Coastguard Worker time(&end_time);
1098*49cdfc7eSAndroid Build Coastguard Worker if (logfile != NULL) {
1099*49cdfc7eSAndroid Build Coastguard Worker if (!fmt_print) {
1100*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile,
1101*49cdfc7eSAndroid Build Coastguard Worker "tag=%s stime=%d dur=%d exit=%s "
1102*49cdfc7eSAndroid Build Coastguard Worker "stat=%d core=%s cu=%d cs=%d\n",
1103*49cdfc7eSAndroid Build Coastguard Worker colle->name, (int)(active->mystime),
1104*49cdfc7eSAndroid Build Coastguard Worker (int)(end_time - active->mystime),
1105*49cdfc7eSAndroid Build Coastguard Worker termtype, termid,
1106*49cdfc7eSAndroid Build Coastguard Worker (status & 0200) ? "yes" : "no", 0, 0);
1107*49cdfc7eSAndroid Build Coastguard Worker } else {
1108*49cdfc7eSAndroid Build Coastguard Worker if (termid != 0)
1109*49cdfc7eSAndroid Build Coastguard Worker ++ * failcnt;
1110*49cdfc7eSAndroid Build Coastguard Worker
1111*49cdfc7eSAndroid Build Coastguard Worker fprintf(logfile, ResultFmt" %-5d\n",
1112*49cdfc7eSAndroid Build Coastguard Worker colle->name,
1113*49cdfc7eSAndroid Build Coastguard Worker ((termid != 0) ? "FAIL" : "PASS"),
1114*49cdfc7eSAndroid Build Coastguard Worker termid);
1115*49cdfc7eSAndroid Build Coastguard Worker }
1116*49cdfc7eSAndroid Build Coastguard Worker fflush(logfile);
1117*49cdfc7eSAndroid Build Coastguard Worker }
1118*49cdfc7eSAndroid Build Coastguard Worker
1119*49cdfc7eSAndroid Build Coastguard Worker if (!quiet_mode) {
1120*49cdfc7eSAndroid Build Coastguard Worker write_test_end(active, errbuf, end_time, termtype,
1121*49cdfc7eSAndroid Build Coastguard Worker status, termid, ¬ime, ¬ime);
1122*49cdfc7eSAndroid Build Coastguard Worker }
1123*49cdfc7eSAndroid Build Coastguard Worker if (capturing) {
1124*49cdfc7eSAndroid Build Coastguard Worker close(c_stdout);
1125*49cdfc7eSAndroid Build Coastguard Worker unlink(active->output);
1126*49cdfc7eSAndroid Build Coastguard Worker }
1127*49cdfc7eSAndroid Build Coastguard Worker return -1;
1128*49cdfc7eSAndroid Build Coastguard Worker }
1129*49cdfc7eSAndroid Build Coastguard Worker
1130*49cdfc7eSAndroid Build Coastguard Worker close(errpipe[0]);
1131*49cdfc7eSAndroid Build Coastguard Worker if (capturing)
1132*49cdfc7eSAndroid Build Coastguard Worker close(c_stdout);
1133*49cdfc7eSAndroid Build Coastguard Worker
1134*49cdfc7eSAndroid Build Coastguard Worker active->pgrp = cpid;
1135*49cdfc7eSAndroid Build Coastguard Worker active->stopping = 0;
1136*49cdfc7eSAndroid Build Coastguard Worker
1137*49cdfc7eSAndroid Build Coastguard Worker if (zoo_mark_cmdline(zoofile, cpid, colle->name, colle->cmdline)) {
1138*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): %s\n", panname, zoo_error);
1139*49cdfc7eSAndroid Build Coastguard Worker exit(1);
1140*49cdfc7eSAndroid Build Coastguard Worker }
1141*49cdfc7eSAndroid Build Coastguard Worker
1142*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Dstartup)
1143*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "started %s cpid=%d at %s",
1144*49cdfc7eSAndroid Build Coastguard Worker colle->name, cpid, ctime(&active->mystime));
1145*49cdfc7eSAndroid Build Coastguard Worker
1146*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Dstart) {
1147*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "Executing test = %s as %s", colle->name,
1148*49cdfc7eSAndroid Build Coastguard Worker colle->cmdline);
1149*49cdfc7eSAndroid Build Coastguard Worker if (capturing)
1150*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "with output file = %s\n",
1151*49cdfc7eSAndroid Build Coastguard Worker active->output);
1152*49cdfc7eSAndroid Build Coastguard Worker else
1153*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "\n");
1154*49cdfc7eSAndroid Build Coastguard Worker }
1155*49cdfc7eSAndroid Build Coastguard Worker
1156*49cdfc7eSAndroid Build Coastguard Worker return cpid;
1157*49cdfc7eSAndroid Build Coastguard Worker }
1158*49cdfc7eSAndroid Build Coastguard Worker
subst_pcnt_f(struct coll_entry * colle)1159*49cdfc7eSAndroid Build Coastguard Worker static char *subst_pcnt_f(struct coll_entry *colle)
1160*49cdfc7eSAndroid Build Coastguard Worker {
1161*49cdfc7eSAndroid Build Coastguard Worker static int counter = 1;
1162*49cdfc7eSAndroid Build Coastguard Worker char pid_and_counter[20];
1163*49cdfc7eSAndroid Build Coastguard Worker char new_cmdline[1024];
1164*49cdfc7eSAndroid Build Coastguard Worker
1165*49cdfc7eSAndroid Build Coastguard Worker /* if we get called falsely, do the right thing anyway */
1166*49cdfc7eSAndroid Build Coastguard Worker if (!colle->pcnt_f)
1167*49cdfc7eSAndroid Build Coastguard Worker return colle->cmdline;
1168*49cdfc7eSAndroid Build Coastguard Worker
1169*49cdfc7eSAndroid Build Coastguard Worker snprintf(pid_and_counter, 20, "%d_%d", getpid(), counter++);
1170*49cdfc7eSAndroid Build Coastguard Worker snprintf(new_cmdline, 1024, colle->cmdline, pid_and_counter);
1171*49cdfc7eSAndroid Build Coastguard Worker return strdup(new_cmdline);
1172*49cdfc7eSAndroid Build Coastguard Worker }
1173*49cdfc7eSAndroid Build Coastguard Worker
get_collection(char * file,int optind,int argc,char ** argv)1174*49cdfc7eSAndroid Build Coastguard Worker static struct collection *get_collection(char *file, int optind, int argc,
1175*49cdfc7eSAndroid Build Coastguard Worker char **argv)
1176*49cdfc7eSAndroid Build Coastguard Worker {
1177*49cdfc7eSAndroid Build Coastguard Worker char *buf, *a, *b;
1178*49cdfc7eSAndroid Build Coastguard Worker struct coll_entry *head, *p, *n;
1179*49cdfc7eSAndroid Build Coastguard Worker struct collection *coll;
1180*49cdfc7eSAndroid Build Coastguard Worker int i;
1181*49cdfc7eSAndroid Build Coastguard Worker
1182*49cdfc7eSAndroid Build Coastguard Worker buf = slurp(file);
1183*49cdfc7eSAndroid Build Coastguard Worker if (!buf)
1184*49cdfc7eSAndroid Build Coastguard Worker return NULL;
1185*49cdfc7eSAndroid Build Coastguard Worker
1186*49cdfc7eSAndroid Build Coastguard Worker coll = malloc(sizeof(struct collection));
1187*49cdfc7eSAndroid Build Coastguard Worker coll->cnt = 0;
1188*49cdfc7eSAndroid Build Coastguard Worker
1189*49cdfc7eSAndroid Build Coastguard Worker head = p = n = NULL;
1190*49cdfc7eSAndroid Build Coastguard Worker a = b = buf;
1191*49cdfc7eSAndroid Build Coastguard Worker while (a) {
1192*49cdfc7eSAndroid Build Coastguard Worker /* set b to the start of the next line and add a NULL character
1193*49cdfc7eSAndroid Build Coastguard Worker * to separate the two lines */
1194*49cdfc7eSAndroid Build Coastguard Worker if ((b = strchr(a, '\n')) != NULL)
1195*49cdfc7eSAndroid Build Coastguard Worker *b++ = '\0';
1196*49cdfc7eSAndroid Build Coastguard Worker
1197*49cdfc7eSAndroid Build Coastguard Worker /* If this is line isn't a comment */
1198*49cdfc7eSAndroid Build Coastguard Worker if ((*a != '#') && (*a != '\0') && (*a != ' ')) {
1199*49cdfc7eSAndroid Build Coastguard Worker n = malloc(sizeof(struct coll_entry));
1200*49cdfc7eSAndroid Build Coastguard Worker if ((n->pcnt_f = strstr(a, "%f"))) {
1201*49cdfc7eSAndroid Build Coastguard Worker n->pcnt_f[1] = 's';
1202*49cdfc7eSAndroid Build Coastguard Worker }
1203*49cdfc7eSAndroid Build Coastguard Worker n->name = strdup(strsep(&a, " \t"));
1204*49cdfc7eSAndroid Build Coastguard Worker while (a != NULL && isspace(*a))
1205*49cdfc7eSAndroid Build Coastguard Worker a++;
1206*49cdfc7eSAndroid Build Coastguard Worker if (a == NULL || a[0] == 0) {
1207*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
1208*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): Testcase '%s' requires a command to execute.\n",
1209*49cdfc7eSAndroid Build Coastguard Worker panname, n->name);
1210*49cdfc7eSAndroid Build Coastguard Worker return NULL;
1211*49cdfc7eSAndroid Build Coastguard Worker }
1212*49cdfc7eSAndroid Build Coastguard Worker n->cmdline = strdup(a);
1213*49cdfc7eSAndroid Build Coastguard Worker n->next = NULL;
1214*49cdfc7eSAndroid Build Coastguard Worker
1215*49cdfc7eSAndroid Build Coastguard Worker if (p) {
1216*49cdfc7eSAndroid Build Coastguard Worker p->next = n;
1217*49cdfc7eSAndroid Build Coastguard Worker }
1218*49cdfc7eSAndroid Build Coastguard Worker if (head == NULL) {
1219*49cdfc7eSAndroid Build Coastguard Worker head = n;
1220*49cdfc7eSAndroid Build Coastguard Worker }
1221*49cdfc7eSAndroid Build Coastguard Worker p = n;
1222*49cdfc7eSAndroid Build Coastguard Worker coll->cnt++;
1223*49cdfc7eSAndroid Build Coastguard Worker }
1224*49cdfc7eSAndroid Build Coastguard Worker a = b;
1225*49cdfc7eSAndroid Build Coastguard Worker }
1226*49cdfc7eSAndroid Build Coastguard Worker free(buf);
1227*49cdfc7eSAndroid Build Coastguard Worker
1228*49cdfc7eSAndroid Build Coastguard Worker /* is there something on the commandline to be counted? */
1229*49cdfc7eSAndroid Build Coastguard Worker if (optind < argc) {
1230*49cdfc7eSAndroid Build Coastguard Worker char workstr[1024] = "";
1231*49cdfc7eSAndroid Build Coastguard Worker int workstr_left = 1023;
1232*49cdfc7eSAndroid Build Coastguard Worker
1233*49cdfc7eSAndroid Build Coastguard Worker /* fill arg list */
1234*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; optind < argc; ++optind, ++i) {
1235*49cdfc7eSAndroid Build Coastguard Worker strncat(workstr, argv[optind], workstr_left);
1236*49cdfc7eSAndroid Build Coastguard Worker workstr_left = workstr_left - strlen(argv[optind]);
1237*49cdfc7eSAndroid Build Coastguard Worker strncat(workstr, " ", workstr_left);
1238*49cdfc7eSAndroid Build Coastguard Worker workstr_left--;
1239*49cdfc7eSAndroid Build Coastguard Worker }
1240*49cdfc7eSAndroid Build Coastguard Worker
1241*49cdfc7eSAndroid Build Coastguard Worker n = malloc(sizeof(struct coll_entry));
1242*49cdfc7eSAndroid Build Coastguard Worker if ((n->pcnt_f = strstr(workstr, "%f"))) {
1243*49cdfc7eSAndroid Build Coastguard Worker n->pcnt_f[1] = 's';
1244*49cdfc7eSAndroid Build Coastguard Worker }
1245*49cdfc7eSAndroid Build Coastguard Worker n->cmdline = strdup(workstr);
1246*49cdfc7eSAndroid Build Coastguard Worker n->name = "cmdln";
1247*49cdfc7eSAndroid Build Coastguard Worker n->next = NULL;
1248*49cdfc7eSAndroid Build Coastguard Worker if (p) {
1249*49cdfc7eSAndroid Build Coastguard Worker p->next = n;
1250*49cdfc7eSAndroid Build Coastguard Worker }
1251*49cdfc7eSAndroid Build Coastguard Worker if (head == NULL) {
1252*49cdfc7eSAndroid Build Coastguard Worker head = n;
1253*49cdfc7eSAndroid Build Coastguard Worker }
1254*49cdfc7eSAndroid Build Coastguard Worker coll->cnt++;
1255*49cdfc7eSAndroid Build Coastguard Worker }
1256*49cdfc7eSAndroid Build Coastguard Worker
1257*49cdfc7eSAndroid Build Coastguard Worker /* get an array */
1258*49cdfc7eSAndroid Build Coastguard Worker coll->ary = malloc(coll->cnt * sizeof(struct coll_entry *));
1259*49cdfc7eSAndroid Build Coastguard Worker
1260*49cdfc7eSAndroid Build Coastguard Worker /* fill the array */
1261*49cdfc7eSAndroid Build Coastguard Worker i = 0;
1262*49cdfc7eSAndroid Build Coastguard Worker n = head;
1263*49cdfc7eSAndroid Build Coastguard Worker while (n != NULL) {
1264*49cdfc7eSAndroid Build Coastguard Worker coll->ary[i] = n;
1265*49cdfc7eSAndroid Build Coastguard Worker n = n->next;
1266*49cdfc7eSAndroid Build Coastguard Worker ++i;
1267*49cdfc7eSAndroid Build Coastguard Worker }
1268*49cdfc7eSAndroid Build Coastguard Worker if (i != coll->cnt)
1269*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): i doesn't match cnt\n", panname);
1270*49cdfc7eSAndroid Build Coastguard Worker
1271*49cdfc7eSAndroid Build Coastguard Worker return coll;
1272*49cdfc7eSAndroid Build Coastguard Worker }
1273*49cdfc7eSAndroid Build Coastguard Worker
slurp(char * file)1274*49cdfc7eSAndroid Build Coastguard Worker static char *slurp(char *file)
1275*49cdfc7eSAndroid Build Coastguard Worker {
1276*49cdfc7eSAndroid Build Coastguard Worker char *buf;
1277*49cdfc7eSAndroid Build Coastguard Worker int fd;
1278*49cdfc7eSAndroid Build Coastguard Worker struct stat sbuf;
1279*49cdfc7eSAndroid Build Coastguard Worker
1280*49cdfc7eSAndroid Build Coastguard Worker if ((fd = open(file, O_RDONLY)) < 0) {
1281*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
1282*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): open(%s,O_RDONLY) failed. errno:%d %s\n",
1283*49cdfc7eSAndroid Build Coastguard Worker panname, file, errno, strerror(errno));
1284*49cdfc7eSAndroid Build Coastguard Worker return NULL;
1285*49cdfc7eSAndroid Build Coastguard Worker }
1286*49cdfc7eSAndroid Build Coastguard Worker
1287*49cdfc7eSAndroid Build Coastguard Worker if (fstat(fd, &sbuf) < 0) {
1288*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): fstat(%s) failed. errno:%d %s\n",
1289*49cdfc7eSAndroid Build Coastguard Worker panname, file, errno, strerror(errno));
1290*49cdfc7eSAndroid Build Coastguard Worker return NULL;
1291*49cdfc7eSAndroid Build Coastguard Worker }
1292*49cdfc7eSAndroid Build Coastguard Worker
1293*49cdfc7eSAndroid Build Coastguard Worker buf = malloc(sbuf.st_size + 1);
1294*49cdfc7eSAndroid Build Coastguard Worker if (read(fd, buf, sbuf.st_size) != sbuf.st_size) {
1295*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): slurp failed. errno:%d %s\n",
1296*49cdfc7eSAndroid Build Coastguard Worker panname, errno, strerror(errno));
1297*49cdfc7eSAndroid Build Coastguard Worker free(buf);
1298*49cdfc7eSAndroid Build Coastguard Worker return NULL;
1299*49cdfc7eSAndroid Build Coastguard Worker }
1300*49cdfc7eSAndroid Build Coastguard Worker buf[sbuf.st_size] = '\0';
1301*49cdfc7eSAndroid Build Coastguard Worker
1302*49cdfc7eSAndroid Build Coastguard Worker close(fd);
1303*49cdfc7eSAndroid Build Coastguard Worker return buf;
1304*49cdfc7eSAndroid Build Coastguard Worker }
1305*49cdfc7eSAndroid Build Coastguard Worker
check_orphans(struct orphan_pgrp * orphans,int sig)1306*49cdfc7eSAndroid Build Coastguard Worker static void check_orphans(struct orphan_pgrp *orphans, int sig)
1307*49cdfc7eSAndroid Build Coastguard Worker {
1308*49cdfc7eSAndroid Build Coastguard Worker struct orphan_pgrp *orph;
1309*49cdfc7eSAndroid Build Coastguard Worker
1310*49cdfc7eSAndroid Build Coastguard Worker for (orph = orphans; orph != NULL; orph = orph->next) {
1311*49cdfc7eSAndroid Build Coastguard Worker if (orph->pgrp == 0)
1312*49cdfc7eSAndroid Build Coastguard Worker continue;
1313*49cdfc7eSAndroid Build Coastguard Worker
1314*49cdfc7eSAndroid Build Coastguard Worker if (Debug & Dshutdown)
1315*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
1316*49cdfc7eSAndroid Build Coastguard Worker " propagating sig %d to orphaned pgrp %d\n",
1317*49cdfc7eSAndroid Build Coastguard Worker sig, -(orph->pgrp));
1318*49cdfc7eSAndroid Build Coastguard Worker if (kill(-(orph->pgrp), sig) != 0) {
1319*49cdfc7eSAndroid Build Coastguard Worker if (errno == ESRCH) {
1320*49cdfc7eSAndroid Build Coastguard Worker /* This pgrp is now empty */
1321*49cdfc7eSAndroid Build Coastguard Worker if (zoo_clear(zoofile, orph->pgrp)) {
1322*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pan(%s): %s\n",
1323*49cdfc7eSAndroid Build Coastguard Worker panname, zoo_error);
1324*49cdfc7eSAndroid Build Coastguard Worker }
1325*49cdfc7eSAndroid Build Coastguard Worker orph->pgrp = 0;
1326*49cdfc7eSAndroid Build Coastguard Worker } else {
1327*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
1328*49cdfc7eSAndroid Build Coastguard Worker "pan(%s): kill(%d,%d) on orphaned pgrp failed. errno:%d %s\n",
1329*49cdfc7eSAndroid Build Coastguard Worker panname, -(orph->pgrp), sig, errno,
1330*49cdfc7eSAndroid Build Coastguard Worker strerror(errno));
1331*49cdfc7eSAndroid Build Coastguard Worker }
1332*49cdfc7eSAndroid Build Coastguard Worker }
1333*49cdfc7eSAndroid Build Coastguard Worker }
1334*49cdfc7eSAndroid Build Coastguard Worker }
1335*49cdfc7eSAndroid Build Coastguard Worker
mark_orphan(struct orphan_pgrp * orphans,pid_t cpid)1336*49cdfc7eSAndroid Build Coastguard Worker static void mark_orphan(struct orphan_pgrp *orphans, pid_t cpid)
1337*49cdfc7eSAndroid Build Coastguard Worker {
1338*49cdfc7eSAndroid Build Coastguard Worker struct orphan_pgrp *orph;
1339*49cdfc7eSAndroid Build Coastguard Worker
1340*49cdfc7eSAndroid Build Coastguard Worker for (orph = orphans; orph != NULL; orph = orph->next) {
1341*49cdfc7eSAndroid Build Coastguard Worker if (orph->pgrp == 0)
1342*49cdfc7eSAndroid Build Coastguard Worker break;
1343*49cdfc7eSAndroid Build Coastguard Worker }
1344*49cdfc7eSAndroid Build Coastguard Worker if (orph == NULL) {
1345*49cdfc7eSAndroid Build Coastguard Worker /* make a new struct */
1346*49cdfc7eSAndroid Build Coastguard Worker orph = malloc(sizeof(struct orphan_pgrp));
1347*49cdfc7eSAndroid Build Coastguard Worker
1348*49cdfc7eSAndroid Build Coastguard Worker /* plug in the new struct just after the head */
1349*49cdfc7eSAndroid Build Coastguard Worker orph->next = orphans->next;
1350*49cdfc7eSAndroid Build Coastguard Worker orphans->next = orph;
1351*49cdfc7eSAndroid Build Coastguard Worker }
1352*49cdfc7eSAndroid Build Coastguard Worker orph->pgrp = cpid;
1353*49cdfc7eSAndroid Build Coastguard Worker }
1354*49cdfc7eSAndroid Build Coastguard Worker
copy_buffered_output(struct tag_pgrp * running)1355*49cdfc7eSAndroid Build Coastguard Worker static void copy_buffered_output(struct tag_pgrp *running)
1356*49cdfc7eSAndroid Build Coastguard Worker {
1357*49cdfc7eSAndroid Build Coastguard Worker char *tag_output;
1358*49cdfc7eSAndroid Build Coastguard Worker
1359*49cdfc7eSAndroid Build Coastguard Worker tag_output = slurp(running->output);
1360*49cdfc7eSAndroid Build Coastguard Worker if (tag_output) {
1361*49cdfc7eSAndroid Build Coastguard Worker printf("%s", tag_output);
1362*49cdfc7eSAndroid Build Coastguard Worker /* make sure the output ends with a newline */
1363*49cdfc7eSAndroid Build Coastguard Worker if (tag_output[strlen(tag_output) - 1] != '\n')
1364*49cdfc7eSAndroid Build Coastguard Worker printf("\n");
1365*49cdfc7eSAndroid Build Coastguard Worker fflush(stdout);
1366*49cdfc7eSAndroid Build Coastguard Worker free(tag_output);
1367*49cdfc7eSAndroid Build Coastguard Worker }
1368*49cdfc7eSAndroid Build Coastguard Worker }
1369*49cdfc7eSAndroid Build Coastguard Worker
write_kmsg(const char * fmt,...)1370*49cdfc7eSAndroid Build Coastguard Worker static void write_kmsg(const char *fmt, ...)
1371*49cdfc7eSAndroid Build Coastguard Worker {
1372*49cdfc7eSAndroid Build Coastguard Worker FILE *kmsg;
1373*49cdfc7eSAndroid Build Coastguard Worker va_list ap;
1374*49cdfc7eSAndroid Build Coastguard Worker
1375*49cdfc7eSAndroid Build Coastguard Worker if ((kmsg = fopen("/dev/kmsg", "r+")) == NULL) {
1376*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "Error %s: (%d) opening /dev/kmsg\n",
1377*49cdfc7eSAndroid Build Coastguard Worker strerror(errno), errno);
1378*49cdfc7eSAndroid Build Coastguard Worker exit(1);
1379*49cdfc7eSAndroid Build Coastguard Worker }
1380*49cdfc7eSAndroid Build Coastguard Worker
1381*49cdfc7eSAndroid Build Coastguard Worker va_start(ap, fmt);
1382*49cdfc7eSAndroid Build Coastguard Worker vfprintf(kmsg, fmt, ap);
1383*49cdfc7eSAndroid Build Coastguard Worker va_end(ap);
1384*49cdfc7eSAndroid Build Coastguard Worker fclose(kmsg);
1385*49cdfc7eSAndroid Build Coastguard Worker }
1386*49cdfc7eSAndroid Build Coastguard Worker
write_test_start(struct tag_pgrp * running,int no_kmsg)1387*49cdfc7eSAndroid Build Coastguard Worker static void write_test_start(struct tag_pgrp *running, int no_kmsg)
1388*49cdfc7eSAndroid Build Coastguard Worker {
1389*49cdfc7eSAndroid Build Coastguard Worker if (!strcmp(reporttype, "rts")) {
1390*49cdfc7eSAndroid Build Coastguard Worker
1391*49cdfc7eSAndroid Build Coastguard Worker printf
1392*49cdfc7eSAndroid Build Coastguard Worker ("%s\ntag=%s stime=%lld\ncmdline=\"%s\"\ncontacts=\"%s\"\nanalysis=%s\n%s\n",
1393*49cdfc7eSAndroid Build Coastguard Worker "<<<test_start>>>", running->cmd->name, (long long)running->mystime,
1394*49cdfc7eSAndroid Build Coastguard Worker running->cmd->cmdline, "", "exit", "<<<test_output>>>");
1395*49cdfc7eSAndroid Build Coastguard Worker }
1396*49cdfc7eSAndroid Build Coastguard Worker fflush(stdout);
1397*49cdfc7eSAndroid Build Coastguard Worker if (no_kmsg)
1398*49cdfc7eSAndroid Build Coastguard Worker return;
1399*49cdfc7eSAndroid Build Coastguard Worker
1400*49cdfc7eSAndroid Build Coastguard Worker if (strcmp(running->cmd->name, running->cmd->cmdline))
1401*49cdfc7eSAndroid Build Coastguard Worker write_kmsg("LTP: starting %s (%s)\n", running->cmd->name,
1402*49cdfc7eSAndroid Build Coastguard Worker running->cmd->cmdline);
1403*49cdfc7eSAndroid Build Coastguard Worker else
1404*49cdfc7eSAndroid Build Coastguard Worker write_kmsg("LTP: starting %s\n", running->cmd->name);
1405*49cdfc7eSAndroid Build Coastguard Worker }
1406*49cdfc7eSAndroid Build Coastguard Worker
1407*49cdfc7eSAndroid Build Coastguard Worker static void
write_test_end(struct tag_pgrp * running,const char * init_status,time_t exit_time,char * term_type,int stat_loc,int term_id,struct tms * tms1,struct tms * tms2)1408*49cdfc7eSAndroid Build Coastguard Worker write_test_end(struct tag_pgrp *running, const char *init_status,
1409*49cdfc7eSAndroid Build Coastguard Worker time_t exit_time, char *term_type, int stat_loc,
1410*49cdfc7eSAndroid Build Coastguard Worker int term_id, struct tms *tms1, struct tms *tms2)
1411*49cdfc7eSAndroid Build Coastguard Worker {
1412*49cdfc7eSAndroid Build Coastguard Worker if (!strcmp(reporttype, "rts")) {
1413*49cdfc7eSAndroid Build Coastguard Worker printf
1414*49cdfc7eSAndroid Build Coastguard Worker ("%s\ninitiation_status=\"%s\"\nduration=%ld termination_type=%s "
1415*49cdfc7eSAndroid Build Coastguard Worker "termination_id=%d corefile=%s\ncutime=%d cstime=%d\n%s\n",
1416*49cdfc7eSAndroid Build Coastguard Worker "<<<execution_status>>>", init_status,
1417*49cdfc7eSAndroid Build Coastguard Worker (long)(exit_time - running->mystime), term_type, term_id,
1418*49cdfc7eSAndroid Build Coastguard Worker (stat_loc & 0200) ? "yes" : "no",
1419*49cdfc7eSAndroid Build Coastguard Worker (int)(tms2->tms_cutime - tms1->tms_cutime),
1420*49cdfc7eSAndroid Build Coastguard Worker (int)(tms2->tms_cstime - tms1->tms_cstime),
1421*49cdfc7eSAndroid Build Coastguard Worker "<<<test_end>>>");
1422*49cdfc7eSAndroid Build Coastguard Worker }
1423*49cdfc7eSAndroid Build Coastguard Worker fflush(stdout);
1424*49cdfc7eSAndroid Build Coastguard Worker }
1425*49cdfc7eSAndroid Build Coastguard Worker
1426*49cdfc7eSAndroid Build Coastguard Worker /* The functions below are all debugging related */
1427*49cdfc7eSAndroid Build Coastguard Worker
pids_running(struct tag_pgrp * running,int keep_active)1428*49cdfc7eSAndroid Build Coastguard Worker static void pids_running(struct tag_pgrp *running, int keep_active)
1429*49cdfc7eSAndroid Build Coastguard Worker {
1430*49cdfc7eSAndroid Build Coastguard Worker int i;
1431*49cdfc7eSAndroid Build Coastguard Worker
1432*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pids still running: ");
1433*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < keep_active; ++i) {
1434*49cdfc7eSAndroid Build Coastguard Worker if (running[i].pgrp != 0)
1435*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "%d ", running[i].pgrp);
1436*49cdfc7eSAndroid Build Coastguard Worker }
1437*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "\n");
1438*49cdfc7eSAndroid Build Coastguard Worker }
1439*49cdfc7eSAndroid Build Coastguard Worker
orphans_running(struct orphan_pgrp * orphans)1440*49cdfc7eSAndroid Build Coastguard Worker static void orphans_running(struct orphan_pgrp *orphans)
1441*49cdfc7eSAndroid Build Coastguard Worker {
1442*49cdfc7eSAndroid Build Coastguard Worker struct orphan_pgrp *orph;
1443*49cdfc7eSAndroid Build Coastguard Worker
1444*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "orphans still running: ");
1445*49cdfc7eSAndroid Build Coastguard Worker for (orph = orphans; orph != NULL; orph = orph->next) {
1446*49cdfc7eSAndroid Build Coastguard Worker if (orph->pgrp != 0)
1447*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "%d ", -(orph->pgrp));
1448*49cdfc7eSAndroid Build Coastguard Worker }
1449*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "\n");
1450*49cdfc7eSAndroid Build Coastguard Worker }
1451*49cdfc7eSAndroid Build Coastguard Worker
dump_coll(struct collection * coll)1452*49cdfc7eSAndroid Build Coastguard Worker static void dump_coll(struct collection *coll)
1453*49cdfc7eSAndroid Build Coastguard Worker {
1454*49cdfc7eSAndroid Build Coastguard Worker int i;
1455*49cdfc7eSAndroid Build Coastguard Worker
1456*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < coll->cnt; ++i) {
1457*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "coll %d\n", i);
1458*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, " name=%s cmdline=%s\n", coll->ary[i]->name,
1459*49cdfc7eSAndroid Build Coastguard Worker coll->ary[i]->cmdline);
1460*49cdfc7eSAndroid Build Coastguard Worker }
1461*49cdfc7eSAndroid Build Coastguard Worker }
1462*49cdfc7eSAndroid Build Coastguard Worker
wait_handler(int sig)1463*49cdfc7eSAndroid Build Coastguard Worker void wait_handler(int sig)
1464*49cdfc7eSAndroid Build Coastguard Worker {
1465*49cdfc7eSAndroid Build Coastguard Worker static int lastsent = 0;
1466*49cdfc7eSAndroid Build Coastguard Worker
1467*49cdfc7eSAndroid Build Coastguard Worker if (sig == 0) {
1468*49cdfc7eSAndroid Build Coastguard Worker lastsent = 0;
1469*49cdfc7eSAndroid Build Coastguard Worker } else {
1470*49cdfc7eSAndroid Build Coastguard Worker rec_signal = sig;
1471*49cdfc7eSAndroid Build Coastguard Worker if (sig == SIGUSR2)
1472*49cdfc7eSAndroid Build Coastguard Worker return;
1473*49cdfc7eSAndroid Build Coastguard Worker if (lastsent == 0)
1474*49cdfc7eSAndroid Build Coastguard Worker send_signal = sig;
1475*49cdfc7eSAndroid Build Coastguard Worker else if (lastsent == SIGUSR1)
1476*49cdfc7eSAndroid Build Coastguard Worker send_signal = SIGINT;
1477*49cdfc7eSAndroid Build Coastguard Worker else if (lastsent == sig)
1478*49cdfc7eSAndroid Build Coastguard Worker send_signal = SIGTERM;
1479*49cdfc7eSAndroid Build Coastguard Worker else if (lastsent == SIGTERM)
1480*49cdfc7eSAndroid Build Coastguard Worker send_signal = SIGHUP;
1481*49cdfc7eSAndroid Build Coastguard Worker else if (lastsent == SIGHUP)
1482*49cdfc7eSAndroid Build Coastguard Worker send_signal = SIGKILL;
1483*49cdfc7eSAndroid Build Coastguard Worker lastsent = send_signal;
1484*49cdfc7eSAndroid Build Coastguard Worker }
1485*49cdfc7eSAndroid Build Coastguard Worker }
1486