--- rpl/src/instructions_r4.c 2011/03/12 15:32:03 1.28 +++ rpl/src/instructions_r4.c 2012/06/18 15:15:31 1.54 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.21 - Copyright (C) 1989-2011 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.9 + Copyright (C) 1989-2012 Dr. BERTRAND Joël This file is part of RPL/2. @@ -852,28 +852,30 @@ instruction_read(struct_processus *s_eta int ios; integer8 element; + integer8 i; integer8 id; integer8 position_clef; + integer8 longueur_effective; + integer8 longueur_enregistrement; + integer8 longueur_questure; + integer8 niveau; + integer8 pointeur; + integer8 position_finale; + integer8 position_initiale; + logical1 indicateur_48; logical1 presence_chaine; logical1 presence_indicateur; - long i; - long longueur_effective; - long longueur_enregistrement; - long longueur_questure; - long niveau; - long pointeur; - long position_finale; - long position_initiale; - socklen_t longueur_adresse; sqlite3_stmt *ppStmt; struct flock lock; + struct pollfd poll_fd; + struct sockaddr_un adresse_unix; struct sockaddr_in adresse_ipv4; # ifdef IPV6 @@ -886,10 +888,12 @@ instruction_read(struct_processus *s_eta struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_inclus; + struct_liste_chainee *l_element_suivant; struct_objet *s_objet_adresse; struct_objet *s_objet_argument_1; struct_objet *s_objet_argument_2; + struct_objet *s_objet_element; struct_objet *s_objet_resultat; struct_objet *s_objet_type; @@ -900,12 +904,10 @@ instruction_read(struct_processus *s_eta unsigned char *tampon_lecture; unsigned char *tampon; unsigned char *tampon2; + unsigned char type_enregistrement; (*s_etat_processus).erreur_execution = d_ex; - attente.tv_sec = 0; - attente.tv_nsec = GRANULARITE_us * 1000; - if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n READ "); @@ -1860,6 +1862,174 @@ instruction_read(struct_processus *s_eta /* * Fichiers non formatés */ + + if ((*((struct_fichier *) (*s_objet_argument_1).objet)).acces + == 'S') + { + /* + * Fichiers séquentiels + * + * Les fichiers séquentiels non formatés contiennent comme + * les fichiers séquentiels formatés leurs enregistrements + * sous la forme de listes les unes derrières les autres. + * + * Le quartet de poids fort du premier octet à lire + * doit donc être égal à 0100. Si ce n'est pas le cas, + * il sera impossible de lire le fichier et on renvoie + * immédiatement une erreur. Si on lit dans le fichier + * la valeur attendue, on récupère la longueur en octet + * de l'enregistrement puis on le lit. + */ + + BUG(((*descripteur).type != 'C'), uprintf("Bad filtype !\n")); + + if (fread(&type_enregistrement, (size_t) sizeof(unsigned char), + 1, (*descripteur).descripteur_c) != 1) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return; + } + + if ((type_enregistrement & 0xF0) != 0x40) + { + // L'enregistrement trouvé n'est pas une liste. + // Tout porte à croire que le fichier est corrompu. + (*s_etat_processus).erreur_execution = + d_ex_fichier_corrompu; + return; + } + + switch(type_enregistrement) + { + unsigned char taille_enregistrement[8]; + + case 0x48: + { + if (fread(taille_enregistrement, + (size_t) sizeof(unsigned char), + 1, (*descripteur).descripteur_c) != 1) + { + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + + longueur_enregistrement = taille_enregistrement[0]; + break; + } + + case 0x49: + { + if (fread(taille_enregistrement, + (size_t) sizeof(unsigned char), + 2, (*descripteur).descripteur_c) != 2) + { + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + +// A FAIRE conversion de taille_enregistrement en longueur_enregistrement + break; + } + + case 0x4A: + { + if (fread(taille_enregistrement, + (size_t) sizeof(unsigned char), + 4, (*descripteur).descripteur_c) != 4) + { + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + +// A FAIRE conversion de taille_enregistrement en longueur_enregistrement + break; + } + + case 0x4B: + { + if (fread(taille_enregistrement, + (size_t) sizeof(unsigned char), + 8, (*descripteur).descripteur_c) != 8) + { + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + +// A FAIRE conversion de taille_enregistrement en longueur_enregistrement + break; + } + + default: + { + longueur_enregistrement = type_enregistrement & 0x07; + } + } + +printf("L=%d\n", longueur_enregistrement); + // La variable longueur_enregistrement contient le nombre + // d'éléments à lire dans le fichier pour générer la liste + // contenant l'enregistrement. + + if ((s_objet_resultat = allocation(s_etat_processus, LST)) + == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + for(i = 0; i < longueur_enregistrement; i++) + { + /* A FAIRE + s_objet_element = decodage_enregistrement(s_etat_processus, + (*descripteur).descripteur_c); + */ + s_objet_element = NULL; + + if (s_objet_element == NULL) + { + liberation(s_etat_processus, s_objet_resultat); + return; + } + + if ((*s_objet_resultat).objet == NULL) + { + if (((*s_objet_resultat).objet = allocation_maillon( + s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + (*((struct_liste_chainee *) (*s_objet_resultat).objet)) + .donnee = s_objet_element; + l_element_courant = (*s_objet_resultat).objet; + } + else + { + if ((l_element_suivant = allocation_maillon( + s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + (*l_element_courant).suivant = l_element_suivant; + (*l_element_suivant).donnee = s_objet_element; + l_element_courant = l_element_suivant; + } + } + + // On saute les caractère des gestion de la commande + // BACKSPACE. + // A FAIRE + } } else { @@ -2052,18 +2222,17 @@ instruction_read(struct_processus *s_eta } # ifndef SEMAPHORES_NOMMES - if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } + if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) # else - if (sem_post((*s_etat_processus).semaphore_fork) != 0) + if (sem_post((*s_etat_processus).semaphore_fork) != 0) +# endif { (*s_etat_processus).erreur_systeme = d_es_processus; return; } -# endif + + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; for(;;) { @@ -2108,6 +2277,9 @@ instruction_read(struct_processus *s_eta printf("+++Warning : IPv6 support " "unavailable\n"); } + + longueur_adresse = 0; + longueur_effective = 0; # endif } else @@ -2116,19 +2288,15 @@ instruction_read(struct_processus *s_eta liberation(s_etat_processus, s_objet_argument_1); # ifndef SEMAPHORES_NOMMES - while(sem_wait(&((*s_etat_processus) - .semaphore_fork)) == -1) + while(sem_wait(&((*s_etat_processus) + .semaphore_fork)) != 0) # else - while(sem_wait((*s_etat_processus) - .semaphore_fork) == -1) + while(sem_wait((*s_etat_processus) + .semaphore_fork) != 0) # endif { - if (errno != EINTR) - { - (*s_etat_processus).erreur_systeme = - d_es_processus; - return; - } + (*s_etat_processus).erreur_systeme = + d_es_processus; } (*s_etat_processus).erreur_execution = @@ -2139,9 +2307,12 @@ instruction_read(struct_processus *s_eta if (longueur_effective < 0) { nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); scrutation_injection(s_etat_processus); } + // Une donnée a été reçue. + if (((*s_etat_processus).var_volatile_requete_arret == -1) || (longueur_effective >= 0)) { @@ -2150,12 +2321,12 @@ instruction_read(struct_processus *s_eta } # ifndef SEMAPHORES_NOMMES - while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) + while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0) # else - while(sem_wait((*s_etat_processus).semaphore_fork) == -1) + while(sem_wait((*s_etat_processus).semaphore_fork) != 0) # endif { - if (errno != EINTR) + if (errno == EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; @@ -2247,6 +2418,16 @@ instruction_read(struct_processus *s_eta { if (longueur_effective < longueur_questure) { + poll_fd.fd = (*((struct_socket *) + (*s_objet_argument_1).objet)).socket; + poll_fd.events = POLLIN; + + if (poll(&poll_fd, 1, 0) > 0) + { + free(tampon_lecture); + continue; + } + liberation(s_etat_processus, s_objet_argument_1); free(tampon_lecture); @@ -2353,7 +2534,7 @@ instruction_read(struct_processus *s_eta longueur_adresse = 0; recvfrom((*((struct_socket *) (*s_objet_argument_1).objet)).socket, tampon_lecture, - position_finale, MSG_DONTWAIT, + longueur_effective, MSG_DONTWAIT, NULL, &longueur_adresse); (*s_objet_adresse).objet = NULL; @@ -2364,7 +2545,7 @@ instruction_read(struct_processus *s_eta longueur_adresse = sizeof(adresse_ipv4); recvfrom((*((struct_socket *) (*s_objet_argument_1).objet)).socket, tampon_lecture, - position_finale, MSG_DONTWAIT, + longueur_effective, MSG_DONTWAIT, (struct sockaddr *) &adresse_ipv4, &longueur_adresse); if (((*s_objet_adresse).objet = @@ -2444,7 +2625,7 @@ instruction_read(struct_processus *s_eta longueur_adresse = sizeof(adresse_ipv6); recvfrom((*((struct_socket *) (*s_objet_argument_1).objet)).socket, tampon_lecture, - position_finale, MSG_DONTWAIT, + longueur_effective, MSG_DONTWAIT, (struct sockaddr *) &adresse_ipv6, &longueur_adresse); if (((*s_objet_adresse).objet = @@ -2556,18 +2737,17 @@ instruction_read(struct_processus *s_eta } # ifndef SEMAPHORES_NOMMES - if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } + if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) # else - if (sem_post((*s_etat_processus).semaphore_fork) != 0) + if (sem_post((*s_etat_processus).semaphore_fork) != 0) +# endif { (*s_etat_processus).erreur_systeme = d_es_processus; return; } -# endif + + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; for(;;) { @@ -2612,6 +2792,9 @@ instruction_read(struct_processus *s_eta printf("+++Warning : IPv6 support " "unavailable\n"); } + + longueur_adresse = 0; + longueur_effective = 0; # endif } else @@ -2620,11 +2803,11 @@ instruction_read(struct_processus *s_eta liberation(s_etat_processus, s_objet_argument_1); # ifndef SEMAPHORES_NOMMES - while(sem_wait(&((*s_etat_processus) - .semaphore_fork)) == -1) + while(sem_wait(&((*s_etat_processus) + .semaphore_fork)) != 0) # else - while(sem_wait((*s_etat_processus) - .semaphore_fork) == -1) + while(sem_wait((*s_etat_processus) + .semaphore_fork) != 0) # endif { if (errno != EINTR) @@ -2643,6 +2826,7 @@ instruction_read(struct_processus *s_eta if (longueur_effective < 0) { nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); scrutation_injection(s_etat_processus); } @@ -2654,9 +2838,9 @@ instruction_read(struct_processus *s_eta } # ifndef SEMAPHORES_NOMMES - while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) + while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0) # else - while(sem_wait((*s_etat_processus).semaphore_fork) == -1) + while(sem_wait((*s_etat_processus).semaphore_fork) != 0) # endif { if (errno != EINTR) @@ -2790,7 +2974,8 @@ instruction_read(struct_processus *s_eta /* * Les informations concernant la cible sont valides si - * la socket est non connectée et des domaines INET ou INET6. + * la socket est non connectée et que les domaines sont + * INET ou INET6. * Dans tous les autres cas, on renvoie une liste vide. */ @@ -2800,6 +2985,8 @@ instruction_read(struct_processus *s_eta (strcmp((*((struct_socket *) (*s_objet_argument_1).objet)) .type, "SEQUENTIAL DATAGRAM") == 0)) { + // POSITION_FINALE peut être utilisée sans être initialisée ! + // virer position_finale pour longueur_effective longueur_adresse = 0; recvfrom((*((struct_socket *) (*s_objet_argument_1).objet)).socket, tampon_lecture,