/* intr like command NAME intr - allow a command to be interruptible SYNOPSIS intr [ -anvs ] [ -t seconds ] command [ arguments ] OPTIONS -v Echo the command in the form ' command' (note leading SPACE). -a Echo the command and its arguments. -n Do not echo a NEWLINE after the command or argu- ments (for example `echo -n ...'). -t secs Arrange to have a SIGALRM signal delivered to the command in secs seconds. -s Silently in SIGALRM message. */ #include #include #include #include static char rcsid[] = "@(#) $Id: intr.c,v 1.3 1992/07/09 04:52:32 mit Exp $" ; /* * command option flags */ /* -v : Echo Command name */ int echo_command = 0 ; /* -a : Echo Command Arguments */ int echo_args = 0 ; /* -n : Do not Echo NEWLINE, default echo newline */ int echo_newline = 1 ; /* -t secs : Time out, default no time out */ int time_out = 0 ; /* -s : Silentry */ int silent = 0 ; char *command = NULL ; char **args = NULL ; /* * internal function's */ static void init_args() ; static void usage() ; static int execute() ; main(argc, argv) int argc ; char *argv[] ; { init_args(argc, argv) ; return execute(command, args, time_out) ; } static void usage() { fprintf(stderr, "Usage : intr [-anvs] [-t secs] command [ args ]\n") ; exit(1) ; } extern char *optarg ; extern int optind ; static void init_args(argc, argv) int argc ; char *argv[] ; { int i ; int c ; while((c = getopt(argc, argv, "anvst:")) != -1) { switch(c) { case 'v' : echo_command = 1 ; break ; case 'a' : echo_args = 1 ; break ; case 'n' : echo_newline = 0 ; break ; case 't' : time_out = atoi(optarg) ; break ; case 's' : silent = 1 ; break ; default: abort() ; /*NOTREACHED*/ break ; } } command = argv[optind] ; if (command == NULL) { usage() ; /* NOTREACHED */ } args = (char **)malloc((sizeof(char *) * argc)) ; bzero(args, (sizeof(char *) * argc)) ; optind++ ; args[0] = command ; for(i = 1 ; optind < argc ; optind++, i++) { args[i] = argv[optind] ; } #ifdef DEBUG fprintf(stderr, "command : %s", command) ; for(i = 0 ; args[i] ; i++) { fprintf(stderr, " %s", args[i]) ; } fprintf(stderr, "\n") ; #endif } static int execute(cmd, arg, timeout) char *cmd ; char **arg ; int timeout ; { int pid ; union wait status ; int i ; int err ; pid = fork() ; if (pid == -1) { perror("fork") ; return 1 ; } if (pid == 0) { /* Child */ if (echo_command || echo_args) fprintf(stderr, "%s", cmd) ; if (echo_args) { for(i = 1 ; args[i] ; i++) { fprintf(stderr, " %s", args[i]) ; } } if (echo_command || echo_args) fprintf(stderr, (echo_newline ? "\n" : " ")) ; if (timeout > 0) { alarm(timeout) ; } execvp(cmd, arg) ; perror(cmd) ; exit(1) ; } while((err = wait((union wait *)&status)) != pid) /* infinite loop */ ; if (WIFSIGNALED(status)) { if (status.w_termsig == SIGALRM) { /* Child process terminate by SIGALRM */ if (! silent) { fprintf(stderr, "%s : Alarm clock\n", cmd) ; } } return 1 ; } /* return child status */ return status.w_retcode ; }