--- rpl/src/instructions_r4.c 2012/12/20 15:32:52 1.67 +++ rpl/src/instructions_r4.c 2013/03/10 17:01:05 1.72 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.12 - Copyright (C) 1989-2012 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.13 + Copyright (C) 1989-2013 Dr. BERTRAND Joël This file is part of RPL/2. @@ -851,7 +851,6 @@ instruction_read(struct_processus *s_eta int c; int ios; - integer8 ancienne_longueur_effective; integer8 element; integer8 i; integer8 id; @@ -878,14 +877,14 @@ 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 struct sockaddr_in6 adresse_ipv6; # endif + struct pollfd poll_fd; + struct timespec attente; struct_descripteur_fichier *descripteur; @@ -893,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; @@ -906,12 +903,10 @@ instruction_read(struct_processus *s_eta unsigned char *clef_utf8; unsigned char *commande; unsigned char *format_chaine; - unsigned char poubelle[256]; unsigned char *ptr; unsigned char *tampon_lecture; unsigned char *tampon; unsigned char *tampon2; - unsigned char type_enregistrement; (*s_etat_processus).erreur_execution = d_ex; @@ -1313,42 +1308,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; + } - liberation(s_etat_processus, s_objet_argument_1); - liberation(s_etat_processus, s_objet_argument_2); + 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_TEXT) { @@ -1469,11 +1480,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) { @@ -1525,42 +1554,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) { @@ -1604,6 +1649,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)) @@ -1782,6 +1830,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 = @@ -1889,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) - { - (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; - return; - } - - if ((type_enregistrement & 0xF0) != 0x40) + if ((s_objet_resultat = lecture_fichier_non_formate( + s_etat_processus, (*descripteur).descripteur_c, -1, + d_faux)) == NULL) { - // 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 @@ -2294,7 +2217,7 @@ printf("L=%d\n", longueur_enregistrement if ((*((struct_socket *) (*s_objet_argument_1).objet)).binaire == 'N') { // Socket formatée - longueur_questure = 256; + longueur_questure = 4096; longueur_effective = 0; tampon_lecture = NULL; @@ -2337,8 +2260,8 @@ printf("L=%d\n", longueur_enregistrement { ios = recvfrom((*((struct_socket *) (*s_objet_argument_1).objet)).socket, - tampon_lecture + longueur_effective, - longueur_questure, + tampon_lecture, + longueur_effective + longueur_questure, MSG_PEEK | MSG_DONTWAIT, (struct sockaddr *) &adresse_unix, &longueur_adresse); } while((ios == -1) && (errno == EINTR)); @@ -2352,8 +2275,8 @@ printf("L=%d\n", longueur_enregistrement { ios = recvfrom((*((struct_socket *) (*s_objet_argument_1).objet)).socket, - tampon_lecture + longueur_effective, - longueur_questure, + tampon_lecture, + longueur_effective + longueur_questure, MSG_PEEK | MSG_DONTWAIT, (struct sockaddr *) &adresse_ipv4, &longueur_adresse); } while((ios == -1) && (errno == EINTR)); @@ -2368,8 +2291,8 @@ printf("L=%d\n", longueur_enregistrement { ios = recvfrom((*((struct_socket *) (*s_objet_argument_1).objet)).socket, - tampon_lecture + longueur_effective, - longueur_questure, + tampon_lecture, + longueur_effective + longueur_questure, MSG_PEEK | MSG_DONTWAIT, (struct sockaddr *) &adresse_ipv6, &longueur_adresse); } while((ios == -1) && (errno == EINTR)); @@ -2438,7 +2361,6 @@ printf("L=%d\n", longueur_enregistrement if (ios >= 0) { - ancienne_longueur_effective = longueur_effective; longueur_effective += ios; position_initiale = 0; presence_indicateur = d_faux; @@ -2509,80 +2431,79 @@ printf("L=%d\n", longueur_enregistrement } } - // 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); - - 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); + // On retire une trame du buffer. - 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) + if (trame_complete == d_vrai) { -# ifdef IPV6 - longueur_adresse = sizeof(adresse_ipv6); - - do + if ((*((struct_socket *) (*s_objet_argument_1).objet)) + .domaine == PF_UNIX) { - 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') + 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) { - printf("+++Attention : Support du protocole" - " IPv6 indisponible\n"); + 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 + else if ((*((struct_socket *) (*s_objet_argument_1) + .objet)) .domaine == PF_INET6) { - printf("+++Warning : IPv6 support " - "unavailable\n"); +# 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_adresse = 0; -# endif + longueur_effective = ios; } - - if (presence_indicateur == d_faux) + else { + // Installation d'un timeout pour sortir de + // l'instruction dans le cas où la transmission serait + // invalide et que la trame reçue serait erronée. + poll_fd.fd = (*((struct_socket *) (*s_objet_argument_1).objet)).socket; poll_fd.events = POLLIN; while((ios = poll(&poll_fd, 1, 10000)) <= 0) { - // La fin de la trame n'est pas atteinte - // et il reste quelque chose à lire. + // La fin de la trame n'est pas atteinte. switch(ios) { @@ -2656,8 +2577,7 @@ printf("L=%d\n", longueur_enregistrement tampon_lecture[++position_finale] = d_code_fin_chaine; tampon = (*s_etat_processus).instruction_courante; - (*s_etat_processus).instruction_courante = &(tampon_lecture - [position_initiale]); + (*s_etat_processus).instruction_courante = tampon_lecture; indicateur_48 = test_cfsf(s_etat_processus, 48); cf(s_etat_processus, 48);