11c5ac21333f543680ce306d46f287d62c175d873mridge/* Repeatedly run a program for a given length of time. */ 21c5ac21333f543680ce306d46f287d62c175d873mridge 31e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper/* 41c5ac21333f543680ce306d46f287d62c175d873mridge * Copyright (C) 2003-2006 IBM 51e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper * 61c5ac21333f543680ce306d46f287d62c175d873mridge * This program is free software; you can redistribute it and/or 71c5ac21333f543680ce306d46f287d62c175d873mridge * modify it under the terms of the GNU General Public License as 81c5ac21333f543680ce306d46f287d62c175d873mridge * published by the Free Software Foundation; either version 2 of the 91c5ac21333f543680ce306d46f287d62c175d873mridge * License, or (at your option) any later version. 101c5ac21333f543680ce306d46f287d62c175d873mridge * 111c5ac21333f543680ce306d46f287d62c175d873mridge * This program is distributed in the hope that it will be useful, but 121c5ac21333f543680ce306d46f287d62c175d873mridge * WITHOUT ANY WARRANTY; without even the implied warranty of 131c5ac21333f543680ce306d46f287d62c175d873mridge * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 141c5ac21333f543680ce306d46f287d62c175d873mridge * General Public License for more details. 151e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper * 161c5ac21333f543680ce306d46f287d62c175d873mridge * You should have received a copy of the GNU General Public License 171c5ac21333f543680ce306d46f287d62c175d873mridge * along with this program; if not, write to the Free Software 181c5ac21333f543680ce306d46f287d62c175d873mridge * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 191c5ac21333f543680ce306d46f287d62c175d873mridge * 02111-1307, USA. 201c5ac21333f543680ce306d46f287d62c175d873mridge */ 211c5ac21333f543680ce306d46f287d62c175d873mridge 221c5ac21333f543680ce306d46f287d62c175d873mridge#include <stdio.h> 2332cc0acd99e36836b13056c6d0e3e62a115678f3vapier#include <string.h> 241c5ac21333f543680ce306d46f287d62c175d873mridge#include <strings.h> 251c5ac21333f543680ce306d46f287d62c175d873mridge#include <stdlib.h> 261c5ac21333f543680ce306d46f287d62c175d873mridge#include <unistd.h> 271c5ac21333f543680ce306d46f287d62c175d873mridge#include <sys/types.h> 281c5ac21333f543680ce306d46f287d62c175d873mridge#include <sys/wait.h> 291c5ac21333f543680ce306d46f287d62c175d873mridge 301c5ac21333f543680ce306d46f287d62c175d873mridge#include "debug.h" 311c5ac21333f543680ce306d46f287d62c175d873mridge 321c5ac21333f543680ce306d46f287d62c175d873mridgestatic int res = 0; 331c5ac21333f543680ce306d46f287d62c175d873mridgestatic char *progname; 341c5ac21333f543680ce306d46f287d62c175d873mridgestatic pid_t test_pgrp; 3598d8d3aa130f8ec92171fb7e5bcd02d645bac110Li Wangstatic FILE *out; 361c5ac21333f543680ce306d46f287d62c175d873mridge 37354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void int_func(int signum) 38354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 3998d8d3aa130f8ec92171fb7e5bcd02d645bac110Li Wang pounder_fprintf(out, 40354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "%s: Killed by interrupt. Last exit code = %d.\n", 41354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao progname, res); 421c5ac21333f543680ce306d46f287d62c175d873mridge kill(-test_pgrp, SIGTERM); 431c5ac21333f543680ce306d46f287d62c175d873mridge exit(res); 441c5ac21333f543680ce306d46f287d62c175d873mridge} 45354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 46354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void alarm_func(int signum) 47354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 4898d8d3aa130f8ec92171fb7e5bcd02d645bac110Li Wang pounder_fprintf(out, "%s: Killed by timer. Last exit code = %d.\n", 49354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao progname, res); 501c5ac21333f543680ce306d46f287d62c175d873mridge kill(-test_pgrp, SIGTERM); 511c5ac21333f543680ce306d46f287d62c175d873mridge exit(res); 521c5ac21333f543680ce306d46f287d62c175d873mridge} 531c5ac21333f543680ce306d46f287d62c175d873mridge 541c5ac21333f543680ce306d46f287d62c175d873mridge/* 551c5ac21333f543680ce306d46f287d62c175d873mridgestatic void term_func(int signum) { 561c5ac21333f543680ce306d46f287d62c175d873mridge exit(res); 571c5ac21333f543680ce306d46f287d62c175d873mridge} 581c5ac21333f543680ce306d46f287d62c175d873mridge*/ 591c5ac21333f543680ce306d46f287d62c175d873mridge 60354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint main(int argc, char *argv[]) 61354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 621c5ac21333f543680ce306d46f287d62c175d873mridge int secs, stat; 631c5ac21333f543680ce306d46f287d62c175d873mridge pid_t pid; 641c5ac21333f543680ce306d46f287d62c175d873mridge unsigned int revs = 0; 651c5ac21333f543680ce306d46f287d62c175d873mridge struct sigaction zig; 6686db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang int use_max_failures = 0; 6786db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang int max_failures = 0; 6886db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang int fail_counter = 1; 691e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 701c5ac21333f543680ce306d46f287d62c175d873mridge if (argc < 3) { 71354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 72354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Usage: %s [-m max_failures] time_in_sec command [args]\n", 73354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao argv[0]); 741c5ac21333f543680ce306d46f287d62c175d873mridge exit(1); 751c5ac21333f543680ce306d46f287d62c175d873mridge } 7686db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang //by default, set max_failures to whatever the env variable $MAX_FAILURES is 77354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *max_failures_env = getenv("MAX_FAILURES"); 78354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao max_failures = atoi(max_failures_env); 7986db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang 8086db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang //if the -m option is used when calling timed_loop, override max_failures 8186db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang //specified by $MAX_FAILURES with the given argument instead 8286db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang if (argc > 4 && strcmp(argv[1], "-m") == 0) { 8337550cf5a86c7ca7424a2a318dd64e550f13f5dfChris Dearman if ((max_failures = atoi(argv[2])) >= 0) { 8486db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang use_max_failures = 1; 85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 86354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Usage: %s [-m max_failures] time_in_sec command [args]\n", 88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao argv[0]); 89354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("max_failures should be a nonnegative integer\n"); 9186db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang exit(1); 9286db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } 9386db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } 9486db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang 9598d8d3aa130f8ec92171fb7e5bcd02d645bac110Li Wang out = stdout; 961c5ac21333f543680ce306d46f287d62c175d873mridge 9786db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang if (use_max_failures) { 9886db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang progname = rindex(argv[4], '/'); 9986db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang if (progname == NULL) { 10086db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang progname = argv[4]; 10186db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } else { 10286db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang progname++; 10386db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } 104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 10586db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang progname = rindex(argv[2], '/'); 10686db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang if (progname == NULL) { 10786db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang progname = argv[2]; 10886db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } else { 10986db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang progname++; 11086db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } 1111c5ac21333f543680ce306d46f287d62c175d873mridge } 1121c5ac21333f543680ce306d46f287d62c175d873mridge 1131c5ac21333f543680ce306d46f287d62c175d873mridge /* Set up signals */ 11432cc0acd99e36836b13056c6d0e3e62a115678f3vapier memset(&zig, 0x00, sizeof(zig)); 1151c5ac21333f543680ce306d46f287d62c175d873mridge zig.sa_handler = alarm_func; 1161c5ac21333f543680ce306d46f287d62c175d873mridge sigaction(SIGALRM, &zig, NULL); 1171c5ac21333f543680ce306d46f287d62c175d873mridge zig.sa_handler = int_func; 1181c5ac21333f543680ce306d46f287d62c175d873mridge sigaction(SIGINT, &zig, NULL); 1191c5ac21333f543680ce306d46f287d62c175d873mridge sigaction(SIGTERM, &zig, NULL); 1201c5ac21333f543680ce306d46f287d62c175d873mridge 1211c5ac21333f543680ce306d46f287d62c175d873mridge /* set up process groups so that we can kill the 1221c5ac21333f543680ce306d46f287d62c175d873mridge * loop test and descendants easily */ 1231c5ac21333f543680ce306d46f287d62c175d873mridge 12486db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang if (use_max_failures) { 12586db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang secs = atoi(argv[3]); 126354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 12786db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang secs = atoi(argv[1]); 12886db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } 1291c5ac21333f543680ce306d46f287d62c175d873mridge alarm(secs); 1301c5ac21333f543680ce306d46f287d62c175d873mridge 1311c5ac21333f543680ce306d46f287d62c175d873mridge while (1) { 13298d8d3aa130f8ec92171fb7e5bcd02d645bac110Li Wang pounder_fprintf(out, "%s: %s loop #%d.\n", progname, 133354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao start_msg, revs++); 1341c5ac21333f543680ce306d46f287d62c175d873mridge pid = fork(); 1351c5ac21333f543680ce306d46f287d62c175d873mridge if (pid == 0) { 1361c5ac21333f543680ce306d46f287d62c175d873mridge if (setpgrp() < 0) { 1371c5ac21333f543680ce306d46f287d62c175d873mridge perror("setpgid"); 1381c5ac21333f543680ce306d46f287d62c175d873mridge } 1391c5ac21333f543680ce306d46f287d62c175d873mridge // run the program 14086db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang if (use_max_failures) { 14186db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang if (argc > 5) { 14286db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang stat = execvp(argv[4], &argv[4]); 14386db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } else { 14486db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang stat = execvp(argv[4], &argv[4]); 14586db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } 14686db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang 14786db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang perror(argv[4]); 148354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 14986db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang if (argc > 3) { 15086db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang stat = execvp(argv[2], &argv[2]); 15186db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } else { 15286db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang stat = execvp(argv[2], &argv[2]); 15386db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } 15486db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang 15586db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang perror(argv[2]); 1561c5ac21333f543680ce306d46f287d62c175d873mridge } 1571c5ac21333f543680ce306d46f287d62c175d873mridge 1581c5ac21333f543680ce306d46f287d62c175d873mridge exit(-1); 1591c5ac21333f543680ce306d46f287d62c175d873mridge } 1601e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 1611c5ac21333f543680ce306d46f287d62c175d873mridge /* save the pgrp of the spawned process */ 1621c5ac21333f543680ce306d46f287d62c175d873mridge test_pgrp = pid; 1631c5ac21333f543680ce306d46f287d62c175d873mridge 1641c5ac21333f543680ce306d46f287d62c175d873mridge // wait for it to be done 1651c5ac21333f543680ce306d46f287d62c175d873mridge if (waitpid(pid, &stat, 0) != pid) { 1661c5ac21333f543680ce306d46f287d62c175d873mridge perror("waitpid"); 1671c5ac21333f543680ce306d46f287d62c175d873mridge exit(1); 1681c5ac21333f543680ce306d46f287d62c175d873mridge } 1691c5ac21333f543680ce306d46f287d62c175d873mridge // interrogate it 1701c5ac21333f543680ce306d46f287d62c175d873mridge if (WIFSIGNALED(stat)) { 17198d8d3aa130f8ec92171fb7e5bcd02d645bac110Li Wang pounder_fprintf(out, "%s: %s on signal %d.\n", 172354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao progname, fail_msg, WTERMSIG(stat)); 1731c5ac21333f543680ce306d46f287d62c175d873mridge res = 255; 1741c5ac21333f543680ce306d46f287d62c175d873mridge } else { 1751c5ac21333f543680ce306d46f287d62c175d873mridge res = WEXITSTATUS(stat); 1761c5ac21333f543680ce306d46f287d62c175d873mridge if (res == 0) { 17798d8d3aa130f8ec92171fb7e5bcd02d645bac110Li Wang pounder_fprintf(out, "%s: %s.\n", progname, 178354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pass_msg); 1791c5ac21333f543680ce306d46f287d62c175d873mridge } else if (res < 0 || res == 255) { 18098d8d3aa130f8ec92171fb7e5bcd02d645bac110Li Wang pounder_fprintf(out, 181354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "CHECK %s: %s with code %d.\n", 182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao progname, abort_msg, res); 1831c5ac21333f543680ce306d46f287d62c175d873mridge exit(-1); 1841c5ac21333f543680ce306d46f287d62c175d873mridge // FIXME: add test to blacklist 1851c5ac21333f543680ce306d46f287d62c175d873mridge } else { 18698d8d3aa130f8ec92171fb7e5bcd02d645bac110Li Wang pounder_fprintf(out, 187354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "%s: %s with code %d.\n", 188354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao progname, fail_msg, res); 18986db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang if (max_failures > 0) { 19086db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang if (++fail_counter > max_failures) { 19186db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang exit(-1); 19286db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } 19386db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang } 1941c5ac21333f543680ce306d46f287d62c175d873mridge } 1951c5ac21333f543680ce306d46f287d62c175d873mridge } 1961c5ac21333f543680ce306d46f287d62c175d873mridge } 19786db0c171384b39671502c5e4e46c07da8c4f51fLucy Liang} 198