/* safe.c -- safe program execution
 * 
 * $Id: safe.c 6 2007-08-30 20:38:17Z piumarta $
 * 
 * Last edited:  2007-08-30 13:15:46 by piumarta on vps2.piumarta.com
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <math.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>


int pid= 0;


void sigalrm(int sig)
{
  printf("timeout\n");
  kill(pid, SIGKILL);
}


int main(int argc, char **argv)
{
  double timeout= 1.0;
  char *prog= argv[0];

  ++argv;  --argc;
  if (argc)
    {
      if ('-' == argv[0][0])
	{
	  char *endptr= 0;
	  timeout= strtod(argv[0] + 1, &endptr);
	  if ((!argv[0][1]) || endptr[0])
	    {
	      fprintf(stderr, "illegal timeout: %s\n", argv[0]);
	      exit(1);
	    }
	  ++argv;  --argc;
	}
      if (argc)
	{
	  if ((pid= fork()))
	    {
	      int status;
	      struct itimerval itv;
	      long secs= timeout * 1000000;
	      itv.it_interval.tv_sec=  0;
	      itv.it_interval.tv_usec= 0;
	      itv.it_value.tv_sec=  secs / 1000000;
	      itv.it_value.tv_usec= secs % 1000000;
	      signal(SIGALRM, sigalrm);
	      setitimer(ITIMER_REAL, &itv, 0);
	      wait(&status);
	      exit(status);
	    }
	  else
	    {
	      int error= execvp(*argv, argv);
	      perror(argv[1]);
	      exit(error);
	    }
	}
    }
  fprintf(stderr, "usage: %s [-timeout] command [args...]\n", prog);
  return 1;
}

