LCOV - code coverage report
Current view: top level - source3/script/tests - timelimit.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 26 56 46.4 %
Date: 2021-09-23 10:06:22 Functions: 2 7 28.6 %

          Line data    Source code
       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           0 : static void usage(void)
      19             : {
      20           0 :         printf("usage: timelimit <time> <command>\n");
      21           0 :         printf("   SIGUSR1 - passes SIGTERM to command's process group\n");
      22           0 :         printf("   SIGALRM - passes SIGTERM to command's process group\n");
      23           0 :         printf("             after 5s SIGKILL will be passed and exit(1)\n");
      24           0 :         printf("   SIGTERM - passes SIGTERM to command's process group\n");
      25           0 :         printf("             after 1s SIGKILL will be passed and exit(1)\n");
      26           0 : }
      27             : 
      28           0 : static void sig_alrm_kill(int sig)
      29             : {
      30           0 :         fprintf(stderr, "\nMaximum time expired in timelimit - killing\n");
      31           0 :         kill(-child_pid, SIGKILL);
      32           0 :         exit(1);
      33             : }
      34             : 
      35           0 : static void sig_alrm_term(int sig)
      36             : {
      37           0 :         kill(-child_pid, SIGTERM);
      38           0 :         alarm(5);
      39           0 :         signal(SIGALRM, sig_alrm_kill);
      40           0 : }
      41             : 
      42           0 : static void sig_term(int sig)
      43             : {
      44           0 :         kill(-child_pid, SIGTERM);
      45           0 :         alarm(1);
      46           0 :         signal(SIGALRM, sig_alrm_kill);
      47           0 : }
      48             : 
      49           0 : static void sig_usr1(int sig)
      50             : {
      51           0 :         kill(-child_pid, SIGTERM);
      52           0 : }
      53             : 
      54          95 : static void new_process_group(void)
      55             : {
      56          95 :         if (setpgid(0,0) == -1) {
      57           0 :                 perror("setpgid");
      58           0 :                 exit(1);
      59             :         }
      60          95 : }
      61             : 
      62             : 
      63          95 : int main(int argc, char *argv[])
      64             : {
      65          95 :         int maxtime, ret=1;
      66             : 
      67          95 :         if (argc < 3) {
      68           0 :                 usage();
      69           0 :                 exit(1);
      70             :         }
      71             : 
      72          95 :         maxtime = atoi(argv[1]);
      73             : 
      74          95 :         child_pid = fork();
      75         190 :         if (child_pid == 0) {
      76          95 :                 new_process_group();
      77          95 :                 execvp(argv[2], argv+2);
      78          95 :                 perror(argv[2]);
      79           0 :                 exit(1);
      80             :         }
      81             : 
      82          95 :         signal(SIGTERM, sig_term);
      83          95 :         signal(SIGINT,  sig_term);
      84          95 :         signal(SIGQUIT, sig_term);
      85          95 :         signal(SIGUSR1, sig_usr1);
      86          95 :         signal(SIGALRM, sig_alrm_term);
      87          95 :         alarm(maxtime);
      88             : 
      89          95 :         do {
      90             :                 int status;
      91         190 :                 pid_t pid = wait(&status);
      92         190 :                 if (pid != -1) {
      93          95 :                         ret = WEXITSTATUS(status);
      94          95 :                 } else if (errno == ECHILD) {
      95          95 :                         break;
      96             :                 }
      97             :         } while (1);
      98             : 
      99          95 :         kill(-child_pid, SIGKILL);
     100             : 
     101          95 :         exit(ret);
     102             : }

Generated by: LCOV version 1.13