Path: utzoo!attcan!uunet!convex!convex.com!tchrist From: tchrist@convex.com (Tom Christiansen) Newsgroups: alt.sources Subject: timeout command Message-ID: <1925@convex.UUCP> Date: 1 Oct 89 18:46:31 GMT Sender: usenet@convex.UUCP Reply-To: tchrist@convex.com (Tom Christiansen) Organization: Convex Computer Corporation, Richardson, Tx. Lines: 81 It is occasionally useful to set a timeout on a command that would otherwise hang or run forever. Instead of building a timeout into each command, the UNIX philosophy would be to build a tool to do the timeout for you, so here it is. It's pretty easy to write, and has surely been done many times before, but I didn't have one handy when I needed it, so here it is. #include#include #include #include int pid,count; union wait status; int bang(); char **commands; main(ac,av) char **av; { if (ac < 3) { usage: fprintf (stderr, "usage: %s seconds command\n",*av); exit (EX_USAGE); } if ((count=atoi(av[1])) < 1) { fprintf (stderr, "seconds (%s) malformed or nonpositive\n",av[1]); goto usage; } commands = &av[2]; switch (pid=fork()) { default: parent(); break; case 0: child(); /* NOTREACHED */ case -1: perror("fork"); exit(EX_OSERR); /* NOTREACHED */ } printf("exit status was %d\n",status.w_retcode); printf("termsig was %d\n",status.w_termsig); } parent() { (void) signal(SIGALRM,bang); alarm(count); while(wait(&status) != pid) /* VOID */; if (WIFSIGNALED(status)) exit(-status.w_termsig); exit(status.w_retcode); } bang() { fprintf(stderr,"Timeout!\n"); (void) signal(SIGALRM,SIG_DFL); (void) kill(pid,SIGTERM); if (!kill(pid,0)) { sleep(3); (void) kill(pid,SIGKILL); } exit(EX_TEMPFAIL); } child() { execvp(*commands,commands); perror(*commands); _exit(EX_DATAERR); /* NOTREACHED */ } /* lint output: * timeout.c: */ Tom Christiansen {uunet,uiucdcs,sun}!convex!tchrist Convex Computer Corporation tchrist@convex.COM "EMACS belongs in : Editor too big!"