--- rpl/src/instructions_r4.c 2011/11/15 07:01:37 1.46 +++ rpl/src/instructions_r4.c 2012/06/19 09:59:34 1.56 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.4 - 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. @@ -851,6 +851,7 @@ instruction_read(struct_processus *s_eta int c; int ios; + integer8 ancienne_longueur_effective; integer8 element; integer8 i; integer8 id; @@ -863,7 +864,6 @@ instruction_read(struct_processus *s_eta integer8 position_finale; integer8 position_initiale; - logical1 indicateur_48; logical1 presence_chaine; logical1 presence_indicateur; @@ -874,6 +874,8 @@ instruction_read(struct_processus *s_eta struct flock lock; + struct pollfd poll_fd; + struct sockaddr_un adresse_unix; struct sockaddr_in adresse_ipv4; # ifdef IPV6 @@ -898,6 +900,7 @@ instruction_read(struct_processus *s_eta unsigned char caractere; unsigned char *clef_utf8; unsigned char *commande; + unsigned char poubelle[256]; unsigned char *ptr; unsigned char *tampon_lecture; unsigned char *tampon; @@ -2208,11 +2211,19 @@ printf("L=%d\n", longueur_enregistrement if ((*((struct_socket *) (*s_objet_argument_1).objet)).binaire == 'N') { // Socket formatée longueur_questure = 256; + longueur_effective = 0; + tampon_lecture = NULL; + + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; do { - if ((tampon_lecture = malloc((longueur_questure + 1) * - sizeof(unsigned char))) == NULL) + presence_indicateur = d_faux; + + if ((tampon_lecture = realloc(tampon_lecture, + (longueur_effective + longueur_questure) + * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -2229,42 +2240,194 @@ printf("L=%d\n", longueur_enregistrement return; } - attente.tv_sec = 0; - attente.tv_nsec = GRANULARITE_us * 1000; + if ((*((struct_socket *) (*s_objet_argument_1).objet)) + .domaine == PF_UNIX) + { + longueur_adresse = sizeof(adresse_unix); + ios = recvfrom((*((struct_socket *) + (*s_objet_argument_1).objet)).socket, + tampon_lecture + longueur_effective, + longueur_questure, + MSG_PEEK | MSG_DONTWAIT, (struct sockaddr *) + &adresse_unix, &longueur_adresse); + } + else if ((*((struct_socket *) (*s_objet_argument_1).objet)) + .domaine == PF_INET) + { + longueur_adresse = sizeof(adresse_ipv4); + ios = recvfrom((*((struct_socket *) + (*s_objet_argument_1).objet)).socket, + tampon_lecture + longueur_effective, + longueur_questure, + MSG_PEEK | MSG_DONTWAIT, (struct sockaddr *) + &adresse_ipv4, &longueur_adresse); + } + else if ((*((struct_socket *) (*s_objet_argument_1).objet)) + .domaine == PF_INET6) + { +# ifdef IPV6 + longueur_adresse = sizeof(adresse_ipv6); + ios = recvfrom((*((struct_socket *) + (*s_objet_argument_1).objet)).socket, + tampon_lecture + longueur_effective, + longueur_questure, + MSG_PEEK | MSG_DONTWAIT, (struct sockaddr *) + &adresse_ipv6, &longueur_adresse); +# else + if ((*s_etat_processus).langue == 'F') + { + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + printf("+++Warning : IPv6 support " + "unavailable\n"); + } - for(;;) + longueur_adresse = 0; + longueur_effective = 0; + ios = 0; +# endif + } + else + { + free(tampon_lecture); + liberation(s_etat_processus, s_objet_argument_1); + +# ifndef SEMAPHORES_NOMMES + while(sem_wait(&((*s_etat_processus) + .semaphore_fork)) != 0) +# else + while(sem_wait((*s_etat_processus) + .semaphore_fork) != 0) +# endif + { + (*s_etat_processus).erreur_systeme = + d_es_processus; + } + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + + if (ios < 0) + { + nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); + scrutation_injection(s_etat_processus); + } + else { + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + } + + if ((*s_etat_processus).var_volatile_requete_arret == -1) + { + longueur_effective += ios; + break; + } + + // Une donnée a été reçue. + + if (ios >= 0) + { + ancienne_longueur_effective = longueur_effective; + longueur_effective += ios; + position_initiale = 0; + presence_indicateur = d_faux; + + do + { + if (tampon_lecture[position_initiale] == '{') + { + presence_indicateur = d_vrai; + break; + } + + position_initiale++; + } while(position_initiale < longueur_effective); + + if (presence_indicateur == d_vrai) + { + position_finale = position_initiale + 1; + presence_chaine = d_faux; + presence_indicateur = d_faux; + niveau = 1; + + while(position_finale < longueur_effective) + { + caractere = tampon_lecture[position_finale]; + + if (caractere == '"') + { + presence_chaine = + (presence_chaine == d_vrai) + ? d_faux : d_vrai; + } + else + { + if (presence_chaine == d_faux) + { + if (caractere == '{') + { + niveau++; + } + else if (caractere == '}') + { + niveau--; + } + } + } + + if (niveau == 0) + { + presence_indicateur = d_vrai; + break; + } + + position_finale++; + } + } + + // On retire du buffer position_finale - + // ancienne_longueur_effective octets. + if ((*((struct_socket *) (*s_objet_argument_1).objet)) .domaine == PF_UNIX) { longueur_adresse = sizeof(adresse_unix); - longueur_effective = recvfrom((*((struct_socket *) + ios = recvfrom((*((struct_socket *) (*s_objet_argument_1).objet)).socket, - tampon_lecture, longueur_questure, - MSG_PEEK | MSG_DONTWAIT, (struct sockaddr *) + poubelle, position_finale + - ancienne_longueur_effective, + MSG_DONTWAIT, (struct sockaddr *) &adresse_unix, &longueur_adresse); } - else if ((*((struct_socket *) (*s_objet_argument_1).objet)) - .domaine == PF_INET) + else if ((*((struct_socket *) (*s_objet_argument_1) + .objet)).domaine == PF_INET) { longueur_adresse = sizeof(adresse_ipv4); - longueur_effective = recvfrom((*((struct_socket *) + ios = recvfrom((*((struct_socket *) (*s_objet_argument_1).objet)).socket, - tampon_lecture, longueur_questure, - MSG_PEEK | MSG_DONTWAIT, (struct sockaddr *) + poubelle, position_finale + - ancienne_longueur_effective, + MSG_DONTWAIT, (struct sockaddr *) &adresse_ipv4, &longueur_adresse); } - else if ((*((struct_socket *) (*s_objet_argument_1).objet)) - .domaine == PF_INET6) + else if ((*((struct_socket *) (*s_objet_argument_1) + .objet)) .domaine == PF_INET6) { # ifdef IPV6 longueur_adresse = sizeof(adresse_ipv6); - longueur_effective = recvfrom((*((struct_socket *) + ios = recvfrom((*((struct_socket *) (*s_objet_argument_1).objet)).socket, - tampon_lecture, longueur_questure, - MSG_PEEK | MSG_DONTWAIT, (struct sockaddr *) + poubelle, position_finale + - ancienne_longueur_effective, + MSG_DONTWAIT, (struct sockaddr *) &adresse_ipv6, &longueur_adresse); - # else if ((*s_etat_processus).langue == 'F') { @@ -2276,43 +2439,41 @@ printf("L=%d\n", longueur_enregistrement printf("+++Warning : IPv6 support " "unavailable\n"); } + + longueur_adresse = 0; # endif } - else + + if (presence_indicateur == d_faux) { - free(tampon_lecture); - liberation(s_etat_processus, s_objet_argument_1); + poll_fd.fd = (*((struct_socket *) + (*s_objet_argument_1).objet)).socket; + poll_fd.events = POLLIN; -# ifndef SEMAPHORES_NOMMES - while(sem_wait(&((*s_etat_processus) - .semaphore_fork)) != 0) -# else - while(sem_wait((*s_etat_processus) - .semaphore_fork) != 0) -# endif + while((ios = poll(&poll_fd, 1, 100)) <= 0) { - (*s_etat_processus).erreur_systeme = - d_es_processus; - } + // La fin de la trame n'est pas atteinte + // et il reste quelque chose à lire. - (*s_etat_processus).erreur_execution = - d_ex_erreur_acces_fichier; - return; - } - - if (longueur_effective < 0) - { - nanosleep(&attente, NULL); - INCR_GRANULARITE(attente.tv_nsec); - scrutation_injection(s_etat_processus); - } + switch(ios) + { + case EINTR: + { + break; + } - // Une donnée a été reçue. + case 0: + { + liberation(s_etat_processus, + s_objet_argument_1); + free(tampon_lecture); - if (((*s_etat_processus).var_volatile_requete_arret == -1) - || (longueur_effective >= 0)) - { - break; + (*s_etat_processus).erreur_execution = + d_ex_fin_de_fichier_atteinte; + return; + } + } + } } } @@ -2353,78 +2514,6 @@ printf("L=%d\n", longueur_enregistrement d_ex_erreur_acces_fichier; return; } - - position_initiale = 0; - presence_indicateur = d_faux; - - do - { - if (tampon_lecture[position_initiale] == '{') - { - presence_indicateur = d_vrai; - break; - } - - position_initiale++; - } while(position_initiale < longueur_effective); - - - if (presence_indicateur == d_vrai) - { - position_finale = position_initiale + 1; - presence_chaine = d_faux; - presence_indicateur = d_faux; - niveau = 1; - - while(position_finale < longueur_effective) - { - caractere = tampon_lecture[position_finale]; - - if (caractere == '"') - { - presence_chaine = (presence_chaine == d_vrai) - ? d_faux : d_vrai; - } - else - { - if (presence_chaine == d_faux) - { - if (caractere == '{') - { - niveau++; - } - else if (caractere == '}') - { - niveau--; - } - } - } - - if (niveau == 0) - { - presence_indicateur = d_vrai; - break; - } - - position_finale++; - } - } - - if (presence_indicateur == d_faux) - { - if (longueur_effective < longueur_questure) - { - liberation(s_etat_processus, s_objet_argument_1); - free(tampon_lecture); - - (*s_etat_processus).erreur_execution = - d_ex_fin_de_fichier_atteinte; - return; - } - - free(tampon_lecture); - longueur_questure *= 2; - } } while(presence_indicateur == d_faux); tampon_lecture[++position_finale] = d_code_fin_chaine; @@ -2517,23 +2606,11 @@ printf("L=%d\n", longueur_enregistrement (strcmp((*((struct_socket *) (*s_objet_argument_1).objet)) .type, "SEQUENTIAL DATAGRAM") == 0)) { - longueur_adresse = 0; - recvfrom((*((struct_socket *) - (*s_objet_argument_1).objet)).socket, tampon_lecture, - longueur_effective, MSG_DONTWAIT, - NULL, &longueur_adresse); - (*s_objet_adresse).objet = NULL; } else if ((*((struct_socket *) (*s_objet_argument_1).objet)) .domaine == PF_INET) { - longueur_adresse = sizeof(adresse_ipv4); - recvfrom((*((struct_socket *) - (*s_objet_argument_1).objet)).socket, tampon_lecture, - longueur_effective, MSG_DONTWAIT, - (struct sockaddr *) &adresse_ipv4, &longueur_adresse); - if (((*s_objet_adresse).objet = allocation_maillon(s_etat_processus)) == NULL) { @@ -2608,12 +2685,6 @@ printf("L=%d\n", longueur_enregistrement .domaine == PF_INET6) { # ifdef IPV6 - longueur_adresse = sizeof(adresse_ipv6); - recvfrom((*((struct_socket *) - (*s_objet_argument_1).objet)).socket, tampon_lecture, - longueur_effective, MSG_DONTWAIT, - (struct sockaddr *) &adresse_ipv6, &longueur_adresse); - if (((*s_objet_adresse).objet = allocation_maillon(s_etat_processus)) == NULL) { @@ -2778,6 +2849,9 @@ printf("L=%d\n", longueur_enregistrement printf("+++Warning : IPv6 support " "unavailable\n"); } + + longueur_adresse = 0; + longueur_effective = 0; # endif } else