/* * Ejemplo de control de subprocesos: * primer parametro: Num. maximo de segundos * segundo y sucesivos: proceso a ejecutar * Nota: se deberia usar primero kill -TERM, y si falla, -KILL, no -KILL * directamente. */ #include #include #include #include int launch( char *cmd[], int time, int *status ); extern int errno; char *app; main(int argc, char **argv ) { char *excmd[2]={NULL,NULL}; int error, status; if (argc < 3 ) { fprintf(stderr,"%s: SPDsoft 1994\n", argv[0]); fprintf(stderr,"Use %s: Max_seconds Cmd [arg...]\n", argv[0]); fprintf(stderr, "Cmd will be executed, and aborted (if still alive) after Max_seconds\n"); exit(-1); } app = argv[0]; excmd[0]=argv[2]; if(0==(error=launch( &argv[2], atoi(argv[1]), &status))) { exit(status); } else if (error == -4) { fprintf(stderr,"%s: %s aborted after %s seconds\n", argv[0],argv[2],argv[1]); exit(error); } else { fprintf(stderr,"%s: %s failed (%d)\n", argv[0],argv[2],error); exit(error); } } int launch( char *cmd[], int time, int *status ) { int res=0; int st, alive=0; int pid, wdog_pid, wpid; char stime[256]; char *wdog[3]={"sleep",NULL,NULL}; wdog[1]=stime; sprintf( wdog[1], "%d", time); switch ( pid = fork() ) { case -1: /* error */ perror ( "fork" ); res = -1; break; case 0: execvp ( cmd[0], &cmd[0] ); fprintf(stderr, "%s: execvp %s: %s\n", app, cmd[0], strerror(errno)); exit(-2); break; default: *status = 0; if((wdog_pid=fork())==0) { execvp ( wdog[0], &wdog[0] ); perror("fork wdog"); exit(-5); } else if(wdog_pid == -1) { perror("fork wdog"); res = -3; } else { /* esperando un final */ alive = 1; while ( pid !=(wpid= wait ( &st )) ) if ( wpid == wdog_pid ) { /* sleep acaba antes */ kill( pid, 9 ); res=-4; alive = 0; } if(alive) kill(wdog_pid,9); if (res!=-4) { if (WIFSTOPPED(st)) { printf("%s: %s stoped %d\n", app, cmd[0], WSTOPSIG(st)); res = -6; } else if(WIFEXITED(st)) { *status = WEXITSTATUS(st); } else if(WIFSIGNALED(st)) { printf("%s: %s signaled %d\n", app, cmd[0],WTERMSIG(st)); res = -6; } if(st&0200) printf("%s: %s core dumped\n", app, cmd[0]); } wait(&st); } break; } /* Fin del switch */ return res; }