--- rpl/src/instructions_r4.c 2012/06/19 09:59:34 1.56 +++ rpl/src/instructions_r4.c 2013/02/26 19:56:15 1.69 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.9 - Copyright (C) 1989-2012 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.12 + Copyright (C) 1989-2013 Dr. BERTRAND Joël This file is part of RPL/2. @@ -864,9 +864,13 @@ instruction_read(struct_processus *s_eta integer8 position_finale; integer8 position_initiale; + logical1 format_degenere; logical1 indicateur_48; logical1 presence_chaine; logical1 presence_indicateur; + logical1 trame_complete; + + long longueur; socklen_t longueur_adresse; @@ -887,6 +891,7 @@ instruction_read(struct_processus *s_eta struct_descripteur_fichier *descripteur; 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; @@ -900,6 +905,7 @@ instruction_read(struct_processus *s_eta unsigned char caractere; unsigned char *clef_utf8; unsigned char *commande; + unsigned char *format_chaine; unsigned char poubelle[256]; unsigned char *ptr; unsigned char *tampon_lecture; @@ -1307,42 +1313,58 @@ instruction_read(struct_processus *s_eta (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return; } - - switch(sqlite3_step(ppStmt)) + + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + + do { - case SQLITE_ROW: - { - // Résultat attendu - break; - } + ios = sqlite3_step(ppStmt); - case SQLITE_DONE: + switch(ios) { - // Aucun enregistrement - if (sqlite3_finalize(ppStmt) != SQLITE_OK) + case SQLITE_ROW: { - (*s_etat_processus).erreur_systeme = - d_es_erreur_fichier; - return; + // Résultat attendu + break; } - free(commande); + case SQLITE_DONE: + { + // Aucun enregistrement + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + + free(commande); - liberation(s_etat_processus, s_objet_argument_1); - liberation(s_etat_processus, s_objet_argument_2); + liberation(s_etat_processus, s_objet_argument_1); + liberation(s_etat_processus, s_objet_argument_2); - (*s_etat_processus).erreur_execution = - d_ex_enregistrement_inexistant; - return; - } + (*s_etat_processus).erreur_execution = + d_ex_enregistrement_inexistant; + return; + } - default: - { - (*s_etat_processus).erreur_systeme = - d_es_erreur_fichier; - return; + case SQLITE_BUSY: + case SQLITE_LOCKED: + { + nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); + break; + } + + default: + { + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } } - } + } while(ios != SQLITE_ROW); if (sqlite3_column_type(ppStmt, 0) != SQLITE_TEXT) { @@ -1463,11 +1485,29 @@ instruction_read(struct_processus *s_eta return; } - if (sqlite3_step(ppStmt) != SQLITE_ROW) + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + + do { - (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; - return; - } + ios = sqlite3_step(ppStmt); + + if (ios == SQLITE_ROW) + { + break; + } + else if ((ios == SQLITE_BUSY) || (ios == SQLITE_LOCKED)) + { + nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); + } + else + { + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + } while(ios != SQLITE_ROW); if (sqlite3_column_type(ppStmt, 0) != SQLITE_INTEGER) { @@ -1519,42 +1559,58 @@ instruction_read(struct_processus *s_eta return; } - switch(sqlite3_step(ppStmt)) + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + + do { - case SQLITE_ROW: - { - // Résultat attendu : une clef correspond. - break; - } + ios = sqlite3_step(ppStmt); - case SQLITE_DONE: + switch(ios) { - // Aucun enregistrement - if (sqlite3_finalize(ppStmt) != SQLITE_OK) + case SQLITE_ROW: { - (*s_etat_processus).erreur_systeme = - d_es_erreur_fichier; - return; + // Résultat attendu : une clef correspond. + break; } - free(clef_utf8); - free(commande); + case SQLITE_DONE: + { + // Aucun enregistrement + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } - liberation(s_etat_processus, s_objet_argument_1); - liberation(s_etat_processus, s_objet_argument_2); + free(clef_utf8); + free(commande); - (*s_etat_processus).erreur_execution = - d_ex_enregistrement_inexistant; - return; - } + liberation(s_etat_processus, s_objet_argument_1); + liberation(s_etat_processus, s_objet_argument_2); - default: - { - (*s_etat_processus).erreur_systeme = - d_es_erreur_fichier; - return; + (*s_etat_processus).erreur_execution = + d_ex_enregistrement_inexistant; + return; + } + + case SQLITE_BUSY: + case SQLITE_LOCKED: + { + nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); + break; + } + + default: + { + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } } - } + } while(ios != SQLITE_ROW); if (sqlite3_column_type(ppStmt, 0) != SQLITE_INTEGER) { @@ -1598,6 +1654,9 @@ instruction_read(struct_processus *s_eta element = 1; + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + do { switch(ios = sqlite3_step(ppStmt)) @@ -1776,6 +1835,14 @@ instruction_read(struct_processus *s_eta break; } + case SQLITE_BUSY: + case SQLITE_LOCKED: + { + nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); + break; + } + default: { (*s_etat_processus).erreur_systeme = @@ -1783,7 +1850,6 @@ instruction_read(struct_processus *s_eta return; } } - } while(ios != SQLITE_DONE); if (sqlite3_finalize(ppStmt) != SQLITE_OK) @@ -2055,33 +2121,10 @@ printf("L=%d\n", longueur_enregistrement return; } - do - { - c = getc((*descripteur).descripteur_c); - longueur_enregistrement++; - } while((c != '\n') && (c != EOF)); - - if (fseek((*descripteur).descripteur_c, position_initiale, - SEEK_SET) != 0) - { - liberation(s_etat_processus, s_objet_argument_1); - - (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; - return; - } - - if ((tampon_lecture = malloc((longueur_enregistrement + 1) - * sizeof(unsigned char))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } - - longueur_effective = fread(tampon_lecture, - (size_t) sizeof(unsigned char), - (size_t) longueur_enregistrement, - (*descripteur).descripteur_c); + l_element_courant_format = (struct_liste_chainee *) + (*(*((struct_fichier *) (*s_objet_argument_1).objet)) + .format).objet; + l_element_courant = NULL; if ((s_objet_resultat = allocation(s_etat_processus, LST)) == NULL) @@ -2091,71 +2134,173 @@ printf("L=%d\n", longueur_enregistrement return; } - if (((*s_objet_resultat).objet = - allocation_maillon(s_etat_processus)) == NULL) + while(l_element_courant_format != NULL) { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } + if ((*(*l_element_courant_format).donnee).type != CHN) + { + liberation(s_etat_processus, s_objet_argument_1); + liberation(s_etat_processus, s_objet_resultat); - (*((struct_liste_chainee *) (*s_objet_resultat).objet)) - .suivant = NULL; + (*s_etat_processus).erreur_execution = + d_ex_erreur_type_argument; + return; + } - if (((*((struct_liste_chainee *) (*s_objet_resultat).objet)) - .donnee = allocation(s_etat_processus, CHN)) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } + if ((format_chaine = conversion_majuscule((unsigned char *) + (*(*l_element_courant_format).donnee).objet)) + == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + if (strncmp("LENGTH*(", format_chaine, 8) != 0) + { + liberation(s_etat_processus, s_objet_argument_1); + liberation(s_etat_processus, s_objet_resultat); + free(format_chaine); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_format_fichier; + return; + } - longueur_enregistrement = 1; + longueur = strlen(format_chaine); - for(i = 0; i < longueur_effective; i++) - { - if (isprint(tampon_lecture[i]) != 0) + if (format_chaine[longueur - 1] != ')') { - longueur_enregistrement += 4; + liberation(s_etat_processus, s_objet_argument_1); + liberation(s_etat_processus, s_objet_resultat); + free(format_chaine); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_format_fichier; + return; + } + + format_chaine[longueur] = d_code_fin_chaine; + + if (format_chaine[8] == '*') + { + format_degenere = d_vrai; } else { - longueur_enregistrement++; + // Détermination de la longueur + format_degenere = d_faux; + + if (sscanf(&(format_chaine[8]), "%ld", &longueur) != 1) + { + liberation(s_etat_processus, s_objet_argument_1); + liberation(s_etat_processus, s_objet_resultat); + free(format_chaine); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_format_fichier; + return; + } } - } - if ((tampon = malloc(longueur_enregistrement * - sizeof(unsigned char))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } + free(format_chaine); - ptr = tampon; + if (format_degenere == d_vrai) + { + do + { + c = getc((*descripteur).descripteur_c); + longueur_enregistrement++; + } while((c != '\n') && (c != EOF)); - for(i = 0; i < longueur_effective; i++) - { - if (isprint(tampon_lecture[i]) != 0) + if (fseek((*descripteur).descripteur_c, + position_initiale, SEEK_SET) != 0) + { + liberation(s_etat_processus, s_objet_argument_1); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + } + else + { + longueur_enregistrement = longueur; + } + + if ((tampon_lecture = malloc((longueur_enregistrement) + * sizeof(unsigned char))) == NULL) { - (*ptr) = tampon_lecture[i]; - ptr++; + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + longueur_effective = fread(tampon_lecture, + (size_t) sizeof(unsigned char), + (size_t) longueur_enregistrement, + (*descripteur).descripteur_c); + + if (l_element_courant == NULL) + { + // Premier maillon de la liste + if (((*s_objet_resultat).objet = + allocation_maillon(s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + l_element_courant = (*s_objet_resultat).objet; } else { - (*ptr) = '\\'; - ptr++; - (*ptr) = 'x'; - ptr++; - sprintf(ptr, "%02X", tampon_lecture[i]); - ptr += 2; + if (((*l_element_courant).suivant = + allocation_maillon(s_etat_processus)) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + l_element_courant = (*l_element_courant).suivant; } - } - (*ptr) = d_code_fin_chaine; - free(tampon_lecture); - ((*(*((struct_liste_chainee *) (*s_objet_resultat).objet)) - .donnee)).objet = tampon; + (*l_element_courant).suivant = NULL; + + if (((*l_element_courant).donnee = + allocation(s_etat_processus, CHN)) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + if (format_degenere == d_vrai) + { + if (((*(*l_element_courant).donnee).objet = + analyse_flux(s_etat_processus, tampon_lecture, + longueur_enregistrement - 1)) == NULL) + { + return; + } + } + else + { + if (((*(*l_element_courant).donnee).objet = + analyse_flux(s_etat_processus, tampon_lecture, + longueur_enregistrement)) == NULL) + { + return; + } + } + + free(tampon_lecture); + + l_element_courant_format = + (*l_element_courant_format).suivant; + } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), @@ -2217,12 +2362,16 @@ printf("L=%d\n", longueur_enregistrement 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) + (longueur_effective + longueur_questure + 1) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -2244,35 +2393,47 @@ printf("L=%d\n", longueur_enregistrement .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); + + 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); - 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); + + 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); - 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); + + 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') { @@ -2326,7 +2487,11 @@ printf("L=%d\n", longueur_enregistrement if ((*s_etat_processus).var_volatile_requete_arret == -1) { - longueur_effective += ios; + if (ios >= 0) + { + longueur_effective += ios; + } + break; } @@ -2363,9 +2528,21 @@ printf("L=%d\n", longueur_enregistrement if (caractere == '"') { - presence_chaine = - (presence_chaine == d_vrai) - ? d_faux : d_vrai; + if (position_finale > 0) + { + if (tampon_lecture[position_finale - 1] + != '\\') + { + presence_chaine = (presence_chaine == + d_vrai) ? d_faux : d_vrai; + } + } + else + { + presence_chaine = + (presence_chaine == d_vrai) + ? d_faux : d_vrai; + } } else { @@ -2385,6 +2562,7 @@ printf("L=%d\n", longueur_enregistrement if (niveau == 0) { presence_indicateur = d_vrai; + trame_complete = d_vrai; break; } @@ -2399,35 +2577,47 @@ printf("L=%d\n", longueur_enregistrement .domaine == PF_UNIX) { longueur_adresse = sizeof(adresse_unix); - ios = recvfrom((*((struct_socket *) - (*s_objet_argument_1).objet)).socket, - poubelle, position_finale - - ancienne_longueur_effective, - MSG_DONTWAIT, (struct sockaddr *) - &adresse_unix, &longueur_adresse); + + do + { + ios = recvfrom((*((struct_socket *) + (*s_objet_argument_1).objet)).socket, + poubelle, position_finale + - ancienne_longueur_effective, + 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); - ios = recvfrom((*((struct_socket *) - (*s_objet_argument_1).objet)).socket, - poubelle, position_finale - - ancienne_longueur_effective, - MSG_DONTWAIT, (struct sockaddr *) - &adresse_ipv4, &longueur_adresse); + + do + { + ios = recvfrom((*((struct_socket *) + (*s_objet_argument_1).objet)).socket, + poubelle, position_finale + - ancienne_longueur_effective, + 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); - ios = recvfrom((*((struct_socket *) - (*s_objet_argument_1).objet)).socket, - poubelle, position_finale - - ancienne_longueur_effective, - MSG_DONTWAIT, (struct sockaddr *) - &adresse_ipv6, &longueur_adresse); + + do + { + ios = recvfrom((*((struct_socket *) + (*s_objet_argument_1).objet)).socket, + poubelle, position_finale + - ancienne_longueur_effective, + MSG_DONTWAIT, (struct sockaddr *) + &adresse_ipv6, &longueur_adresse); + } while((ios == -1) && (errno == EINTR)); # else if ((*s_etat_processus).langue == 'F') { @@ -2450,7 +2640,7 @@ printf("L=%d\n", longueur_enregistrement (*s_objet_argument_1).objet)).socket; poll_fd.events = POLLIN; - while((ios = poll(&poll_fd, 1, 100)) <= 0) + while((ios = poll(&poll_fd, 1, 10000)) <= 0) { // La fin de la trame n'est pas atteinte // et il reste quelque chose ŕ lire. @@ -2459,6 +2649,15 @@ printf("L=%d\n", longueur_enregistrement { case EINTR: { + if ((*s_etat_processus) + .var_volatile_requete_arret == -1) + { + liberation(s_etat_processus, + s_objet_argument_1); + free(tampon_lecture); + return; + } + break; } @@ -2514,7 +2713,7 @@ printf("L=%d\n", longueur_enregistrement d_ex_erreur_acces_fichier; return; } - } while(presence_indicateur == d_faux); + } while(trame_complete == d_faux); tampon_lecture[++position_finale] = d_code_fin_chaine; tampon = (*s_etat_processus).instruction_courante; @@ -2531,6 +2730,20 @@ printf("L=%d\n", longueur_enregistrement (*s_etat_processus).instruction_courante = tampon; free(tampon_lecture); + if (indicateur_48 == d_vrai) + { + sf(s_etat_processus, 48); + } + else + { + cf(s_etat_processus, 48); + } + + if ((*s_etat_processus).var_volatile_requete_arret == -1) + { + (*s_etat_processus).erreur_execution = d_ex; + } + liberation(s_etat_processus, s_objet_argument_1); return; }