Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - allnex

#1
Hola, muy buenas.

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.


struct sigaction trataSenial ;

void handler(int sig)
{
if (sig == SIGUSR1)
{
printf("[H] [%d] recibe la señal SIGUSR1\n", getpid());
exit(0);
}
}

void handler_padre(int sig) {
if (sig == SIGUSR1)
{
printf("[P] [%d] recibe la señal SIGUSR1\n", getpid());
exit(0);
}
}

void siguientePassword ( char * pwd )               /* orden lexicografico */
{                                                              /* circular */
    int lenPwd = strlen(pwd) ;
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 lenPwd = strlen(pwd) ;
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 lenPwd = strlen(pwd) ;
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)
    {
        printf(
    "\n"
" formato: despara2 <palabra_cifrada> <pwd_0> <pwd_1> [-v|-p] \n"
"\n"
) ;
        return(1) ;
    }

pwd_0 = argv[2] ;
pwd_1 = argv[3] ;
length_pwd = strlen(pwd_0) ;
if (strlen(pwd_1) != length_pwd)
{
        printf(
    "\n"
" <pwd_0> y <pwd_1> deben tener la misma longitud \n"
"\n"
) ;
        return(2) ;
}

for ( i = 0 ; i < length_pwd ; i++ )
if (!(isalpha(pwd_0[i]) && islower(pwd_0[i]) && 
      isalpha(pwd_1[i]) && islower(pwd_1[i])))
    {
printf(
    "\n"
" <pwd_0> y <pwd_1> deben contener solo letras minusculas \n"
"\n"
) ;
        return(3) ;
}

    if (strcmp(pwd_0, pwd_1) > 0) {
printf(
    "\n"
" <pwd_0> debe ser <= que <pwd_1> en orden lexicográfico \n"
"\n"
) ;
        return(4) ;
}

if (strncmp(argv[1], "aa", 2) != 0)
{
printf(
    "\n"
" la clave cifrada \"%s\" debe comenzar con \"aa\" \n"
"\n", argv[1]
) ;
        return(5) ;
    }

if (argc >= 5)
{
    if (strcmp(argv[4], "-v") == 0) *verbose = 1 ;
    else if (strcmp(argv[4], "-p") == 0) *verbose = 2 ;
    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 ;

length_pwd = strlen(pwd_0) ;
pwd = malloc(length_pwd+1) ;
strcpy(pwd, pwd_0) ;

    printf("\n") ;
for ( i = i_0 ; i <= i_1 ; i++ )
{
        macro_verbose ;      /* macro para mostrar el progreso con -v o -p */

        if (strcmp(claveCifrada, crypt(pwd, "aa")) == 0)
        {
            if (verbose > 0) printf("\n\n") ;
            printf ("la password es: %s (iteraciones = %d = %2d %c)\n",
          pwd, i-i_0+1, (100*(i-i_0+1))/(i_1-i_0+1),'%') ;
          free(pwd);   
    kill(-pidOtro, SIGUSR1);
    exit(0);
        }

        siguientePassword(pwd) ;
    }
    if (verbose > 0) printf("\n\n") ;
printf(" la clave \"%s\" no es una clave cifrada \n", claveCifrada) ;
    free(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) ;

    strcpy(pwdMedio, pwd_0) ;

    obtenPwd((valor(pwd_0)+valor(pwd_1))/2, (char *)&pwdMedio) ;     

printf("pwdMedio = \"%s\"\n\n", pwdMedio) ;
printf("[P] [%d] iniciado\n", getpid());
                                                /* ver: setsid, kill(0, _) */

pid_1 = fork() ;
if (pid_1 == 0) {
printf("[H1] [%d] iniciado", getpid());
signal(SIGUSR1, handler);
    resultado =
    buscaEImprimeClave(claveCifrada, pwd_0, pwdMedio, 0, parent) ;
return(resultado) ;
}
pid_2 = fork() ;
if (pid_2 == 0) {
printf("[H2] [%d] iniciado\n", getpid());
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) ;*/

printf("\n fin del proceso padre\n\n") ;
    return(0) ;
}