1/*
2 * Copyright (c) 2004, Bull S.A..  All rights reserved.
3 * Created by: Sebastien Decugis
4
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write the Free Software Foundation, Inc., 59
15 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
16
17
18 * This utility software allows to run any executable file with a timeout limit.
19 * The syntax is:
20 * $ ./t0 n exe arglist
21 *  where n is the timeout duration in seconds,
22 *        exe is the executable filename to run,
23 *        arglist is the arguments to be passed to executable.
24 *
25 * The use of this utility is intended to be "transparent", which means
26 * everything is as if
27 * $ exe arglist
28 *   had been called, and a call to "alarm(n)" had been added inside exe's main.
29 *
30 * SPECIAL CASE:
31 * $ ./t0 0
32 *  Here another arg is not required. This special case will return immediatly
33 *  as if it has been timedout. This is usefull to check a timeout return code value.
34 *
35 */
36
37/* This utility should compile on any POSIX-conformant implementation. */
38#define _POSIX_C_SOURCE 200112L
39
40#include <pthread.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <unistd.h>
44#include <signal.h>
45
46#include <assert.h>
47
48int main (int argc, char * argv[])
49{
50	int ret, timeout;
51
52	/* Special case: t0 0 */
53	if (argc==2 && (strcmp(argv[1], "0") == 0))
54	{
55		kill(getpid(), SIGALRM);
56		sleep(1);
57		return 2;
58	}
59
60	/* General case */
61	if (argc < 3)
62	{
63		printf("\nUsage: \n");
64		printf("  $ %s n exe arglist\n", argv[0]);
65		printf("  $ %s 0\n", argv[0]);
66		printf("\nWhere:\n");
67		printf("  n       is the timeout duration in seconds,\n");
68		printf("  exe     is the executable filename to run,\n");
69		printf("  arglist is the arguments to be passed to executable.\n\n");
70		printf("  The second use case will emulate an immediate timeout.\n\n");
71		return 2;
72	}
73
74	timeout = atoi(argv[1]);
75	if (timeout < 1)
76	{
77		fprintf(stderr, "Invalid timeout value \"%s\". Timeout must be a positive integer.\n", argv[1]);
78		return 2;
79	}
80
81	/* Set the timeout */
82	alarm(timeout);
83
84	/* Execute the command */
85	ret = execvp(argv[2], &argv[2]);
86	if (ret == -1)
87	{
88		/* Application was not launched */
89		perror("Unable to run child application");
90		return 2;
91	}
92
93	assert(0);
94	perror("Should not see me");
95	return 2;
96}
97
98