root/source3/script/tests/timelimit.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usage
  2. sig_alrm_kill
  3. sig_alrm_term
  4. sig_term
  5. sig_usr1
  6. new_process_group
  7. main

   1 /* run a command with a limited timeout
   2    tridge@samba.org, June 2005
   3    metze@samba.org, March 2006
   4 
   5    attempt to be as portable as possible (fighting posix all the way)
   6 */
   7 #include <stdio.h>
   8 #include <string.h>
   9 #include <stdlib.h>
  10 #include <unistd.h>
  11 #include <signal.h>
  12 #include <errno.h>
  13 #include <sys/types.h>
  14 #include <sys/wait.h>
  15 
  16 static pid_t child_pid;
  17 
  18 static void usage(void)
     /* [<][>][^][v][top][bottom][index][help] */
  19 {
  20         printf("usage: timelimit <time> <command>\n");
  21         printf("   SIGUSR1 - passes SIGTERM to command's process group\n");
  22         printf("   SIGALRM - passes SIGTERM to command's process group\n");
  23         printf("             after 5s SIGKILL will be passed and exit(1)\n");
  24         printf("   SIGTERM - passes SIGTERM to command's process group\n");
  25         printf("             after 1s SIGKILL will be passed and exit(1)\n");
  26 }
  27 
  28 static void sig_alrm_kill(int sig)
     /* [<][>][^][v][top][bottom][index][help] */
  29 {
  30         fprintf(stderr, "\nMaximum time expired in timelimit - killing\n");
  31         kill(-child_pid, SIGKILL);
  32         exit(1);
  33 }
  34 
  35 static void sig_alrm_term(int sig)
     /* [<][>][^][v][top][bottom][index][help] */
  36 {
  37         kill(-child_pid, SIGTERM);
  38         alarm(5);
  39         signal(SIGALRM, sig_alrm_kill);
  40 }
  41 
  42 static void sig_term(int sig)
     /* [<][>][^][v][top][bottom][index][help] */
  43 {
  44         kill(-child_pid, SIGTERM);
  45         alarm(1);
  46         signal(SIGALRM, sig_alrm_kill);
  47 }
  48 
  49 static void sig_usr1(int sig)
     /* [<][>][^][v][top][bottom][index][help] */
  50 {
  51         kill(-child_pid, SIGTERM);
  52 }
  53 
  54 static void new_process_group(void)
     /* [<][>][^][v][top][bottom][index][help] */
  55 {
  56         if (setpgid(0,0) == -1) {
  57                 perror("setpgid");
  58                 exit(1);
  59         }
  60 }
  61 
  62 
  63 int main(int argc, char *argv[])
     /* [<][>][^][v][top][bottom][index][help] */
  64 {
  65         int maxtime, ret=1;
  66 
  67         if (argc < 3) {
  68                 usage();
  69                 exit(1);
  70         }
  71 
  72         maxtime = atoi(argv[1]);
  73 
  74         child_pid = fork();
  75         if (child_pid == 0) {
  76                 new_process_group();
  77                 execvp(argv[2], argv+2);
  78                 perror(argv[2]);
  79                 exit(1);
  80         }
  81 
  82         signal(SIGTERM, sig_term);
  83         signal(SIGINT,  sig_term);
  84         signal(SIGQUIT, sig_term);
  85         signal(SIGUSR1, sig_usr1);
  86         signal(SIGALRM, sig_alrm_term);
  87         alarm(maxtime);
  88 
  89         do {
  90                 int status;
  91                 pid_t pid = wait(&status);
  92                 if (pid != -1) {
  93                         ret = WEXITSTATUS(status);
  94                 } else if (errno == ECHILD) {
  95                         break;
  96                 }
  97         } while (1);
  98 
  99         kill(-child_pid, SIGKILL);
 100 
 101         exit(ret);
 102 }

/* [<][>][^][v][top][bottom][index][help] */