--- rpl/src/instructions_r4.c 2013/03/01 09:29:30 1.71 +++ rpl/src/instructions_r4.c 2013/03/18 10:32:41 1.75 @@ -892,12 +892,10 @@ instruction_read(struct_processus *s_eta struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_courant_format; 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; @@ -909,7 +907,6 @@ 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; @@ -1054,7 +1051,7 @@ instruction_read(struct_processus *s_eta * Fichiers séquentiels */ - longueur_questure = 256; + longueur_questure = 4096; if ((tampon_lecture = malloc(longueur_questure * sizeof(unsigned char))) == NULL) @@ -1948,152 +1945,19 @@ instruction_read(struct_processus *s_eta BUG(((*descripteur).type != 'C'), uprintf("Bad filtype !\n")); - if (fread(&type_enregistrement, (size_t) sizeof(unsigned char), - 1, (*descripteur).descripteur_c) != 1) + if ((s_objet_resultat = lecture_fichier_non_formate( + s_etat_processus, (*descripteur).descripteur_c, -1, + d_faux)) == NULL) { - (*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) + if (empilement(s_etat_processus, + &((*s_etat_processus).l_base_pile), + s_objet_resultat) == d_erreur) { - (*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 @@ -2471,11 +2335,10 @@ printf("L=%d\n", longueur_enregistrement return; } - if (ios < 0) + if (ios <= 0) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); - scrutation_injection(s_etat_processus); } else { @@ -2483,11 +2346,13 @@ printf("L=%d\n", longueur_enregistrement attente.tv_nsec = GRANULARITE_us * 1000; } + scrutation_injection(s_etat_processus); + if ((*s_etat_processus).var_volatile_requete_arret == -1) { if (ios >= 0) { - longueur_effective += ios; + longueur_effective = ios; } break; @@ -2497,7 +2362,7 @@ printf("L=%d\n", longueur_enregistrement if (ios >= 0) { - longueur_effective += ios; + longueur_effective = ios; position_initiale = 0; presence_indicateur = d_faux; @@ -2985,10 +2850,492 @@ printf("L=%d\n", longueur_enregistrement } else if ((*((struct_socket *) (*s_objet_argument_1).objet)).binaire == 'Y') - { // UNFORMATTED + { // socket non formatée + longueur_questure = 4096; + longueur_effective = 0; + tampon_lecture = NULL; + + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + + trame_complete = d_faux; + position_initiale = 0; + position_finale = 0; + + do + { + presence_indicateur = d_faux; + + if ((tampon_lecture = realloc(tampon_lecture, + (longueur_effective + longueur_questure + 1) + * sizeof(unsigned char))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + +# ifndef SEMAPHORES_NOMMES + if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) +# else + if (sem_post((*s_etat_processus).semaphore_fork) != 0) +# endif + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + + if ((*((struct_socket *) (*s_objet_argument_1).objet)) + .domaine == PF_UNIX) + { + longueur_adresse = sizeof(adresse_unix); + + do + { + 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); + } while((ios == -1) && (errno == EINTR)); + } + else if ((*((struct_socket *) (*s_objet_argument_1).objet)) + .domaine == PF_INET) + { + longueur_adresse = sizeof(adresse_ipv4); + + do + { + 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); + } while((ios == -1) && (errno == EINTR)); + } + else if ((*((struct_socket *) (*s_objet_argument_1).objet)) + .domaine == PF_INET6) + { +# ifdef IPV6 + longueur_adresse = sizeof(adresse_ipv6); + + do + { + 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); + } while((ios == -1) && (errno == EINTR)); +# else + if ((*s_etat_processus).langue == 'F') + { + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + printf("+++Warning : IPv6 support " + "unavailable\n"); + } + + 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); + } + else + { + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + } + + scrutation_injection(s_etat_processus); + + if ((*s_etat_processus).var_volatile_requete_arret == -1) + { + if (ios >= 0) + { + longueur_effective += ios; + } + + break; + } + + // Une donnée a été reçue. + + if (ios == (longueur_effective + longueur_questure)) + { + longueur_effective = ios; + position_initiale = 0; + presence_indicateur = d_faux; + } + else if (ios > 0) + { + // On retire une trame du buffer. + + if ((*((struct_socket *) (*s_objet_argument_1).objet)) + .domaine == PF_UNIX) + { + do + { + longueur_adresse = sizeof(adresse_unix); + recvfrom((*((struct_socket *) + (*s_objet_argument_1).objet)).socket, + tampon_lecture, longueur_effective, + 0, (struct sockaddr *) + &adresse_unix, &longueur_adresse); + } while((ios == -1) && (errno == EINTR)); + } + else if ((*((struct_socket *) (*s_objet_argument_1) + .objet)).domaine == PF_INET) + { + do + { + longueur_adresse = sizeof(adresse_ipv4); + recvfrom((*((struct_socket *) + (*s_objet_argument_1).objet)).socket, + tampon_lecture, longueur_effective, + 0, (struct sockaddr *) + &adresse_ipv4, &longueur_adresse); + } while((ios == -1) && (errno == EINTR)); + } + else if ((*((struct_socket *) (*s_objet_argument_1) + .objet)) .domaine == PF_INET6) + { +# ifdef IPV6 + do + { + longueur_adresse = sizeof(adresse_ipv6); + recvfrom((*((struct_socket *) + (*s_objet_argument_1).objet)).socket, + tampon_lecture, longueur_effective, + 0, (struct sockaddr *) + &adresse_ipv6, &longueur_adresse); + } while((ios == -1) && (errno == EINTR)); +# else + if ((*s_etat_processus).langue == 'F') + { + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + printf("+++Warning : IPv6 support " + "unavailable\n"); + } +# endif + } + + longueur_effective = ios; + trame_complete = d_vrai; + } + +# ifndef SEMAPHORES_NOMMES + while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0) +# else + while(sem_wait((*s_etat_processus).semaphore_fork) != 0) +# endif + { + if (errno == EINTR) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + } + + if ((*s_etat_processus).var_volatile_requete_arret == -1) + { + + /* + * Si le père tue le processus courant grâce au signal + * SIGFSTOP, on ne renvoie pas d'erreur. Ce fonctionnement + * correspond à l'utilisation de STOP sur le processus + * en cours. La variable longueur_effective vaut '-1'. + */ + + free(tampon_lecture); + liberation(s_etat_processus, s_objet_argument_1); + return; + } + + if (longueur_effective == -1) + { + free(tampon_lecture); + liberation(s_etat_processus, s_objet_argument_1); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + } while(trame_complete == d_faux); + + /* + * Création de la liste de sortie + */ + + ptr = tampon_lecture; + + if ((s_objet_type = lecture_fichier_non_formate(s_etat_processus, + &ptr, longueur_effective, d_faux)) == NULL) + { + free(tampon_lecture); + + (*s_etat_processus).erreur_execution = d_ex_syntaxe; + return; + } + + if ((s_objet_resultat = allocation(s_etat_processus, LST)) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + 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_type; + + if (((*((struct_liste_chainee *) (*s_objet_resultat).objet)) + .suivant = allocation_maillon(s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + (*(*((struct_liste_chainee *) (*s_objet_resultat).objet)).suivant) + .suivant = NULL; + + if ((s_objet_adresse = allocation(s_etat_processus, LST)) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + (*(*((struct_liste_chainee *) (*s_objet_resultat).objet)).suivant) + .donnee = s_objet_adresse; + + /* + * Les informations concernant la cible sont valides si + * la socket est non connectée et des domaines INET ou INET6. + * Dans tous les autres cas, on renvoie une liste vide. + */ + + if (((*((struct_socket *) (*s_objet_argument_1).objet)).domaine + == PF_UNIX) || (strcmp((*((struct_socket *) + (*s_objet_argument_1).objet)).type, "STREAM") == 0) || + (strcmp((*((struct_socket *) (*s_objet_argument_1).objet)) + .type, "SEQUENTIAL DATAGRAM") == 0)) + { + (*s_objet_adresse).objet = NULL; + } + else if ((*((struct_socket *) (*s_objet_argument_1).objet)) + .domaine == PF_INET) + { + if (((*s_objet_adresse).objet = + allocation_maillon(s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + if (((*((struct_liste_chainee *) (*s_objet_adresse).objet)) + .donnee = allocation(s_etat_processus, VIN)) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + (*((struct_vecteur *) (*(*((struct_liste_chainee *) + (*s_objet_adresse).objet)).donnee).objet)).taille = 4; + + if (((*((struct_vecteur *) (*(*((struct_liste_chainee *) + (*s_objet_adresse).objet)).donnee).objet)).tableau = + malloc(4 * sizeof(integer8))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + ((integer8 *) (*((struct_vecteur *) + (*(*((struct_liste_chainee *) (*s_objet_adresse) + .objet)).donnee).objet)).tableau)[0] = + (ntohl(adresse_ipv4.sin_addr.s_addr) >> 24) & 0xFF; + ((integer8 *) (*((struct_vecteur *) + (*(*((struct_liste_chainee *) (*s_objet_adresse) + .objet)).donnee).objet)).tableau)[1] = + (ntohl(adresse_ipv4.sin_addr.s_addr) >> 16) & 0xFF; + ((integer8 *) (*((struct_vecteur *) + (*(*((struct_liste_chainee *) (*s_objet_adresse) + .objet)).donnee).objet)).tableau)[2] = + (ntohl(adresse_ipv4.sin_addr.s_addr) >> 8) & 0xFF; + ((integer8 *) (*((struct_vecteur *) + (*(*((struct_liste_chainee *) (*s_objet_adresse) + .objet)).donnee).objet)).tableau)[3] = + ntohl(adresse_ipv4.sin_addr.s_addr) & 0xFF; + + if (((*((struct_liste_chainee *) (*s_objet_adresse).objet)) + .suivant = allocation_maillon(s_etat_processus)) + == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + if (((*(*((struct_liste_chainee *) (*s_objet_adresse).objet)) + .suivant).donnee = allocation(s_etat_processus, INT)) + == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + (*((integer8 *) (*(*(*((struct_liste_chainee *) + (*s_objet_adresse).objet)).suivant).donnee).objet)) = + (integer8) ntohs(adresse_ipv4.sin_port); + + (*(*((struct_liste_chainee *) (*s_objet_adresse).objet)) + .suivant).suivant = NULL; + } + else if ((*((struct_socket *) (*s_objet_argument_1).objet)) + .domaine == PF_INET6) + { +# ifdef IPV6 + if (((*s_objet_adresse).objet = + allocation_maillon(s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + if (((*((struct_liste_chainee *) (*s_objet_adresse).objet)) + .donnee = allocation(s_etat_processus, VIN)) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + (*((struct_vecteur *) (*(*((struct_liste_chainee *) + (*s_objet_adresse).objet)).donnee).objet)).taille = 16; + + if (((*((struct_vecteur *) (*(*((struct_liste_chainee *) + (*s_objet_adresse).objet)).donnee).objet)).tableau = + malloc(16 * sizeof(integer8))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + for(i = 0; i < 16; i++) + { + ((integer8 *) (*((struct_vecteur *) + (*(*((struct_liste_chainee *) (*s_objet_adresse) + .objet)).donnee).objet)).tableau)[0] = + adresse_ipv6.sin6_addr.s6_addr[i]; + } + + if (((*((struct_liste_chainee *) (*s_objet_adresse).objet)) + .suivant = allocation_maillon(s_etat_processus)) + == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + if (((*(*((struct_liste_chainee *) (*s_objet_adresse).objet)) + .suivant).donnee = allocation(s_etat_processus, INT)) + == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + (*((integer8 *) (*(*(*((struct_liste_chainee *) + (*s_objet_adresse).objet)).suivant).donnee).objet)) = + (integer8) ntohs(adresse_ipv6.sin6_port); + + (*(*((struct_liste_chainee *) (*s_objet_adresse).objet)) + .suivant).suivant = NULL; +# else + if ((*s_etat_processus).langue == 'F') + { + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + printf("+++Warning : IPv6 support " + "unavailable\n"); + } +# endif + } + else + { + longueur_adresse = 0; + recvfrom((*((struct_socket *) + (*s_objet_argument_1).objet)).socket, tampon_lecture, + position_finale, MSG_DONTWAIT, + NULL, &longueur_adresse); + } + + free(tampon_lecture); + + if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), + s_objet_resultat) == d_erreur) + { + return; + } } else { // FLOW +#if 0 longueur_questure = 256; do @@ -3438,6 +3785,7 @@ printf("L=%d\n", longueur_enregistrement { return; } +#endif } } else