1255376Sdes/*
2255376Sdes * Copyright (c) 2004, Bull S.A..  All rights reserved.
3271947Sdes * Created by: Sebastien Decugis
491094Sdes
591094Sdes * This program is free software; you can redistribute it and/or modify it
691094Sdes * under the terms of version 2 of the GNU General Public License as
791094Sdes * published by the Free Software Foundation.
891094Sdes *
991094Sdes * This program is distributed in the hope that it would be useful, but
1091094Sdes * WITHOUT ANY WARRANTY; without even the implied warranty of
1191094Sdes * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12108794Sdes *
1391094Sdes * You should have received a copy of the GNU General Public License along
14117610Sdes * with this program; if not, write the Free Software Foundation, Inc., 59
1591094Sdes * Temple Place - Suite 330, Boston MA 02111-1307, USA.
1691094Sdes
1794209Sdes
18236109Sdes * This utility software allows to run any executable file with a timeout limit.
1994209Sdes * The syntax is:
2094209Sdes * $ ./t0 n exe arglist
21141098Sdes *  where n is the timeout duration in seconds,
2294209Sdes *        exe is the executable filename to run,
2394209Sdes *        arglist is the arguments to be passed to executable.
2494209Sdes *
25141098Sdes * The use of this utility is intended to be "transparent", which means
2694209Sdes * everything is as if
2794209Sdes * $ exe arglist
2894670Sdes *   had been called, and a call to "alarm(n)" had been added inside exe's main.
2994670Sdes *
3094670Sdes * SPECIAL CASE:
3194670Sdes * $ ./t0 0
3294670Sdes *  Here another arg is not required. This special case will return immediatly
3394670Sdes *  as if it has been timedout. This is usefull to check a timeout return code value.
3499158Sdes *
3594670Sdes */
36236109Sdes
3794670Sdes/* This utility should compile on any POSIX-conformant implementation. */
3894670Sdes#define _POSIX_C_SOURCE 200112L
3991100Sdes
4091094Sdes#include <pthread.h>
41236109Sdes#include <stdio.h>
4291094Sdes#include <stdlib.h>
4391100Sdes#include <unistd.h>
4491100Sdes#include <signal.h>
4591100Sdes
4691100Sdes#include <assert.h>
4791100Sdes
4891100Sdesint main (int argc, char * argv[])
4991100Sdes{
5091100Sdes	int ret, timeout;
5191100Sdes
5291100Sdes	/* Special case: t0 0 */
5391100Sdes	if (argc==2 && (strcmp(argv[1], "0") == 0))
5491100Sdes	{
5591100Sdes		kill(getpid(), SIGALRM);
5691100Sdes		sleep(1);
5791100Sdes		return 2;
5891100Sdes	}
5991100Sdes
6091100Sdes	/* General case */
6191100Sdes	if (argc < 3)
6291684Sdes	{
6391684Sdes		printf("\nUsage: \n");
6491100Sdes		printf("  $ %s n exe arglist\n", argv[0]);
6591100Sdes		printf("  $ %s 0\n", argv[0]);
6691684Sdes		printf("\nWhere:\n");
6791684Sdes		printf("  n       is the timeout duration in seconds,\n");
6891094Sdes		printf("  exe     is the executable filename to run,\n");
6991094Sdes		printf("  arglist is the arguments to be passed to executable.\n\n");
7091100Sdes		printf("  The second use case will emulate an immediate timeout.\n\n");
7191100Sdes		return 2;
7291094Sdes	}
7391094Sdes
7491094Sdes	timeout = atoi(argv[1]);
7591094Sdes	if (timeout < 1)
7691094Sdes	{
7791094Sdes		fprintf(stderr, "Invalid timeout value \"%s\". Timeout must be a positive integer.\n", argv[1]);
7891094Sdes		return 2;
79236109Sdes	}
80236109Sdes
81236109Sdes	/* Set the timeout */
82117610Sdes	alarm(timeout);
83236109Sdes
84147466Sdes	/* Execute the command */
85117610Sdes	ret = execvp(argv[2], &argv[2]);
8691094Sdes	if (ret == -1)
8791094Sdes	{
88255376Sdes		/* Application was not launched */
89255376Sdes		perror("Unable to run child application");
90255376Sdes		return 2;
91	}
92
93	assert(0);
94	perror("Should not see me");
95	return 2;
96}
97
98