Tengo un problema con el manejo de señales. El siguiente programa crea dos procesos hijo y busca secuencialmente una contraseña cifrada. El primer hijo busca desde el principio hasta la mitad, y el segundo hijo desde la mitad hasta el final. El principio y fin lo pasa el usuario a través de argumentos.
El programa funciona bien si se ejecuta, cuando encuentra la contraseña se matan a los hijos y se sale, pero si ejecuto el comando "time ./programa ...." solo finaliza el hijo que ha encontrado la clave, el otro hasta el final no acaba.
No sé que estoy haciendo mal para que funciona normalmente, pero con time no lo haga correctamente.
Muchas gracias.
Código
struct sigaction trataSenial ; void handler(int sig) { if (sig == SIGUSR1) { } } void handler_padre(int sig) { if (sig == SIGUSR1) { } } void siguientePassword ( char * pwd ) /* orden lexicografico */ { /* circular */ int i = lenPwd-1 ; while ( i >= 0) if (++(pwd[i]) > 'z') pwd[i--] = 'a' ; else return ; } int valor ( const char * pwd ) /* valor de la clave (base 'z'-'a' + 1) */ { int base = 'z' - 'a' + 1 ; int acum = 0 ; int i = 0 ; for ( i = 0 ; i < lenPwd ; i++ ) acum = base*acum + (pwd[i] - 'a') ; return(acum) ; } int obtenPwd ( int valor, char * pwd ) { int base = 'z' - 'a' + 1 ; int resto = valor ; int i = lenPwd-1 ; while ((i >= 0) && (resto > 0)) { pwd[i] = 'a' + (char)(resto % base) ; resto = resto / base ; i-- ; } while ( i >= 0) pwd[i--] = 'a' ; } int analizarArgumentos ( int argc, char * argv [ ], int * verbose ) { char * pwd_0 ; /* password inicial (de comienzo de la busqueda) */ char * pwd_1 ; /* password final (de fin de la busqueda) */ int length_pwd ; /* longitud de los passwords */ int i ; if (argc < 4) { "\n" " formato: despara2 <palabra_cifrada> <pwd_0> <pwd_1> [-v|-p] \n" "\n" ) ; return(1) ; } pwd_0 = argv[2] ; pwd_1 = argv[3] ; { "\n" " <pwd_0> y <pwd_1> deben tener la misma longitud \n" "\n" ) ; return(2) ; } for ( i = 0 ; i < length_pwd ; i++ ) { "\n" " <pwd_0> y <pwd_1> deben contener solo letras minusculas \n" "\n" ) ; return(3) ; } "\n" " <pwd_0> debe ser <= que <pwd_1> en orden lexicográfico \n" "\n" ) ; return(4) ; } { "\n" " la clave cifrada \"%s\" debe comenzar con \"aa\" \n" "\n", argv[1] ) ; return(5) ; } if (argc >= 5) { else *verbose = 0 ; } else verbose = 0 ; return(0) ; } #define macro_verbose \ if (verbose == 1) \ { \ printf("\r") ; \ printf(" test i = %10d probando con pwd = %s", i-i_0+1, pwd) ; \ } \ else if (verbose == 2) \ { \ printf("\r") ; \ printf(" progreso = %2d %c", (100*(i-i_0+1))/(i_1-i_0+1),'%') ;\ } \ int buscaEImprimeClave ( char * claveCifrada, char * pwd_0, char * pwd_1, int verbose, int pidOtro ) { char * pwd ; int length_pwd ; int i_0 = valor(pwd_0) ; int i_1 = valor(pwd_1) ; int i, j ; for ( i = i_0 ; i <= i_1 ; i++ ) { macro_verbose ; /* macro para mostrar el progreso con -v o -p */ { pwd, i-i_0+1, (100*(i-i_0+1))/(i_1-i_0+1),'%') ; kill(-pidOtro, SIGUSR1); } siguientePassword(pwd) ; } return(6) ; } int main ( int argc, char * argv [ ] ) { char * claveCifrada = argv[1] ; /* resultado de cifrar el password */ char * pwd_0 = argv[2] ; /* password inicial de busqueda */ char * pwd_1 = argv[3] ; /* password final de busqueda */ int verbose ; /* 0, 1 o 2 (grado de escritura de mensajes con printf) */ int pid, pid_1, pid_2 ; char pwdMedio [6] ; int estado ; int parent = getpid(); trataSenial.sa_handler = handler_padre ; sigaction(SIGUSR1, &trataSenial, NULL) ; int resultado = analizarArgumentos(argc, argv, &verbose) ; if (resultado != 0) return(resultado) ; obtenPwd((valor(pwd_0)+valor(pwd_1))/2, (char *)&pwdMedio) ; /* ver: setsid, kill(0, _) */ pid_1 = fork() ; if (pid_1 == 0) { signal(SIGUSR1, handler); resultado = buscaEImprimeClave(claveCifrada, pwd_0, pwdMedio, 0, parent) ; return(resultado) ; } pid_2 = fork() ; if (pid_2 == 0) { signal(SIGUSR1, handler); siguientePassword(pwdMedio) ; resultado = buscaEImprimeClave(claveCifrada, pwdMedio, pwd_1, 0, parent) ; return(resultado) ; } waitpid(pid_1, &estado, 0) ; waitpid(pid_2, &estado, 0) ; /*pid = wait((int *)&estado) ; pid = wait((int *)&estado) ;*/ return(0) ; }