/* This file is part of GNU Pies testsuite. Copyright (C) 2019 Sergey Poznyakoff GNU Pies is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Pies is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Pies. If not, see . */ #include #include #include #include #include #include #include #include int volatile got_sigchld, got_sigalrm; void sighan (int sig) { switch (sig) { case SIGCHLD: got_sigchld = 1; break; case SIGALRM: got_sigalrm = 1; break; } } int main (int argc, char **argv) { char *progname = argv[0]; unsigned long n; char *p; pid_t pid, ret; int status; if (argc < 3) { fprintf (stderr, "usage: %s TIMEOUT COMMAND ...\n", progname); exit (1); } errno = 0; n = strtoul (argv[1], &p, 10); if (errno || *p || n == 0) { fprintf (stderr, "%s: %s is not a valid timeout\n", progname, argv[1]); exit (1); } argc -= 2; argv += 2; signal (SIGALRM, sighan); signal (SIGCHLD, sighan); pid = fork (); if (pid == -1) { perror ("fork"); exit (127); } if (pid == 0) { execvp (argv[0], argv); perror (argv[0]); exit (127); } alarm (n); while (1) { pause (); if (got_sigchld) { alarm (0); break; } if (got_sigalrm) { fprintf (stderr, "%s: timed out\n", progname); kill (pid, SIGKILL); exit (127); } } ret = wait (&status); if (ret != pid) { perror ("wait"); exit (127); } if (WIFEXITED (status)) return WEXITSTATUS (status); if (WIFSIGNALED (status)) fprintf (stderr, "%s: %s terminated on signal %d\n", progname, argv[0], WTERMSIG (status)); else if (WIFSTOPPED (status)) fprintf (stderr, "%s: %s stopped\n", progname, argv[0]); else fprintf (stderr, "%s: %s exited with unrecognized status %d\n", progname, argv[0], status); return 127; }