--- rpl/src/instructions_s1.c 2010/04/17 18:57:35 1.8 +++ rpl/src/instructions_s1.c 2021/03/13 12:50:47 1.118 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.14 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.33 + Copyright (C) 1989-2021 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,7 +20,8 @@ */ -#include "rpl.conv.h" +#define DEBUG_ERREURS +#include "rpl-conv.h" /* @@ -59,34 +60,34 @@ instruction_swap(struct_processus *s_eta " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" - " %s\n", + " %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SLB, d_PRC, d_MTX, d_SQL); + d_SLB, d_PRC, d_MTX, d_SQL, d_REC); printf(" 1: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" - " %s\n", + " %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SLB, d_PRC, d_MTX, d_SQL); + d_SLB, d_PRC, d_MTX, d_SQL, d_REC); printf("-> 2: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" - " %s\n", + " %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SLB, d_PRC, d_MTX, d_SQL); + d_SLB, d_PRC, d_MTX, d_SQL, d_REC); printf(" 1: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" - " %s\n", + " %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SLB, d_PRC, d_MTX, d_SQL); + d_SLB, d_PRC, d_MTX, d_SQL, d_REC); return; } @@ -147,9 +148,9 @@ instruction_sq(struct_processus *s_etat_ struct_objet *s_objet_argument; struct_objet *s_objet_resultat; - unsigned long i; - unsigned long j; - unsigned long k; + integer8 i; + integer8 j; + integer8 k; void *accumulateur; @@ -310,8 +311,8 @@ instruction_sq(struct_processus *s_etat_ .objet))).nombre_colonnes; if (((*((struct_matrice *) (*s_objet_resultat).objet)).tableau = - malloc((*(((struct_matrice *) (*s_objet_resultat) - .objet))).nombre_lignes * sizeof(integer8 *))) == NULL) + malloc(((size_t) (*(((struct_matrice *) (*s_objet_resultat) + .objet))).nombre_lignes) * sizeof(integer8 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; @@ -323,8 +324,8 @@ instruction_sq(struct_processus *s_etat_ .objet))).nombre_lignes; i++) { if (((*((struct_matrice *) (*s_objet_resultat).objet)).tableau[i] = - malloc((*(((struct_matrice *) (*s_objet_resultat) - .objet))).nombre_colonnes * sizeof(integer8))) == NULL) + malloc(((size_t) (*(((struct_matrice *) (*s_objet_resultat) + .objet))).nombre_colonnes) * sizeof(integer8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; @@ -366,8 +367,8 @@ instruction_sq(struct_processus *s_etat_ (*s_objet_resultat).type = MRL; (*((struct_matrice *) (*s_objet_resultat).objet)).type = 'R'; - if ((accumulateur = malloc((*(((struct_matrice *) - (*s_objet_argument).objet))).nombre_colonnes * + if ((accumulateur = malloc(((size_t) (*(((struct_matrice *) + (*s_objet_argument).objet))).nombre_colonnes) * sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -381,8 +382,8 @@ instruction_sq(struct_processus *s_etat_ (*s_objet_resultat).objet)).tableau)[i]); if (((*((struct_matrice *) (*s_objet_resultat).objet)) - .tableau[i] = malloc((*(((struct_matrice *) - (*s_objet_resultat).objet))).nombre_colonnes * + .tableau[i] = malloc(((size_t) (*(((struct_matrice *) + (*s_objet_resultat).objet))).nombre_colonnes) * sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -457,15 +458,15 @@ instruction_sq(struct_processus *s_etat_ .objet))).nombre_colonnes; if (((*((struct_matrice *) (*s_objet_resultat).objet)).tableau = - malloc((*(((struct_matrice *) (*s_objet_resultat) - .objet))).nombre_lignes * sizeof(real8 *))) == NULL) + malloc(((size_t) (*(((struct_matrice *) (*s_objet_resultat) + .objet))).nombre_lignes) * sizeof(real8 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } - if ((accumulateur = malloc((*(((struct_matrice *) - (*s_objet_argument).objet))).nombre_colonnes * sizeof(real8))) + if ((accumulateur = malloc(((size_t) (*(((struct_matrice *) + (*s_objet_argument).objet))).nombre_colonnes) * sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -476,8 +477,8 @@ instruction_sq(struct_processus *s_etat_ .objet))).nombre_lignes; i++) { if (((*((struct_matrice *) (*s_objet_resultat).objet)).tableau[i] = - malloc((*(((struct_matrice *) (*s_objet_resultat) - .objet))).nombre_colonnes * sizeof(real8))) == NULL) + malloc(((size_t) (*(((struct_matrice *) (*s_objet_resultat) + .objet))).nombre_colonnes) * sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; @@ -549,15 +550,16 @@ instruction_sq(struct_processus *s_etat_ .objet))).nombre_colonnes; if (((*((struct_matrice *) (*s_objet_resultat).objet)).tableau = - malloc((*(((struct_matrice *) (*s_objet_resultat) - .objet))).nombre_lignes * sizeof(struct_complexe16 *))) == NULL) + malloc(((size_t) (*(((struct_matrice *) (*s_objet_resultat) + .objet))).nombre_lignes) * sizeof(struct_complexe16 *))) + == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } - if ((accumulateur = malloc((*(((struct_matrice *) - (*s_objet_argument).objet))).nombre_colonnes * + if ((accumulateur = malloc(((size_t) (*(((struct_matrice *) + (*s_objet_argument).objet))).nombre_colonnes) * sizeof(complex16))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -568,8 +570,8 @@ instruction_sq(struct_processus *s_etat_ .objet))).nombre_lignes; i++) { if (((*((struct_matrice *) (*s_objet_resultat).objet)).tableau[i] = - malloc((*(((struct_matrice *) (*s_objet_resultat) - .objet))).nombre_colonnes * sizeof(struct_complexe16))) + malloc(((size_t) (*(((struct_matrice *) (*s_objet_resultat) + .objet))).nombre_colonnes) * sizeof(struct_complexe16))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -1216,9 +1218,9 @@ instruction_same(struct_processus *s_eta logical1 difference; - unsigned long i; - unsigned long j; - unsigned long nombre_elements; + integer8 i; + integer8 j; + integer8 nombre_elements; (*s_etat_processus).erreur_execution = d_ex; @@ -1275,6 +1277,10 @@ instruction_same(struct_processus *s_eta printf(" 1: %s\n", d_RPN); printf("-> 1: %s\n", d_RPN); + printf(" 2: %s\n", d_PRC); + printf(" 1: %s\n", d_PRC); + printf("-> 1: %s\n", d_INT); + return; } else if ((*s_etat_processus).test_instruction == 'Y') @@ -2568,9 +2574,6 @@ instruction_start(struct_processus *s_et } } - empilement_pile_systeme(s_etat_processus); - (*(*s_etat_processus).l_base_pile_systeme).type_cloture = 'S'; - if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_1) == d_erreur) { @@ -2578,8 +2581,7 @@ instruction_start(struct_processus *s_et return; } - if (((*s_objet_1).type != INT) && - ((*s_objet_1).type != REL)) + if (((*s_objet_1).type != INT) && ((*s_objet_1).type != REL)) { liberation(s_etat_processus, s_objet_1); @@ -2596,8 +2598,7 @@ instruction_start(struct_processus *s_et return; } - if (((*s_objet_2).type != INT) && - ((*s_objet_2).type != REL)) + if (((*s_objet_2).type != INT) && ((*s_objet_2).type != REL)) { liberation(s_etat_processus, s_objet_1); liberation(s_etat_processus, s_objet_2); @@ -2606,6 +2607,15 @@ instruction_start(struct_processus *s_et return; } + empilement_pile_systeme(s_etat_processus); + + if ((*s_etat_processus).erreur_systeme != d_es) + { + return; + } + + (*(*s_etat_processus).l_base_pile_systeme).type_cloture = 'S'; + (*(*s_etat_processus).l_base_pile_systeme).indice_boucle = s_objet_2; (*(*s_etat_processus).l_base_pile_systeme).limite_indice_boucle = s_objet_1; @@ -2765,8 +2775,8 @@ instruction_step(struct_processus *s_eta return; } - if (((*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante]).variable_verrouillee == d_vrai) + if ((*(*s_etat_processus).pointeur_variable_courante) + .variable_verrouillee == d_vrai) { liberation(s_etat_processus, s_objet); @@ -2774,8 +2784,7 @@ instruction_step(struct_processus *s_eta return; } - if (((*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante]).objet == NULL) + if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL) { liberation(s_etat_processus, s_objet); @@ -2784,8 +2793,7 @@ instruction_step(struct_processus *s_eta } (*(*s_etat_processus).l_base_pile_systeme).indice_boucle = - ((*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante]).objet; + (*(*s_etat_processus).pointeur_variable_courante).objet; } /* @@ -2826,8 +2834,7 @@ instruction_step(struct_processus *s_eta */ (*(*s_etat_processus).l_base_pile_systeme).indice_boucle = NULL; - ((*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante]).objet = s_objet; + (*(*s_etat_processus).pointeur_variable_courante).objet = s_objet; } else { @@ -2911,7 +2918,7 @@ instruction_step(struct_processus *s_eta { (*s_etat_processus).niveau_courant--; - if (retrait_variable_par_niveau(s_etat_processus) == d_erreur) + if (retrait_variables_par_niveau(s_etat_processus) == d_erreur) { return; } @@ -3083,10 +3090,11 @@ instruction_stof(struct_processus *s_eta for(i = 1; i <= 64; i++) { - indice_drapeau = i - 1; + indice_drapeau = (unsigned char) (i - 1); indice_bloc = indice_drapeau / taille_bloc; indice_bit = indice_drapeau % taille_bloc; - masque = ((t_8_bits) 1) << (taille_bloc - indice_bit - 1); + masque = (t_8_bits) (((t_8_bits) 1) << + (taille_bloc - indice_bit - 1)); if (((*((logical8 *) (*s_objet).objet)) & ((logical8) 1) << indice_drapeau) != 0) @@ -3148,10 +3156,10 @@ instruction_sto(struct_processus *s_etat " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" - " %s\n", + " %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SLB, d_PRC, d_MTX, d_SQL); + d_SLB, d_PRC, d_MTX, d_SQL, d_REC); printf(" 1: %s\n", d_NOM); return; @@ -3202,8 +3210,8 @@ instruction_sto(struct_processus *s_etat * La variable est accessible. */ - if ((*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante].variable_verrouillee == d_vrai) + if ((*(*s_etat_processus).pointeur_variable_courante) + .variable_verrouillee == d_vrai) { liberation(s_etat_processus, s_objet_1); liberation(s_etat_processus, s_objet_2); @@ -3212,28 +3220,24 @@ instruction_sto(struct_processus *s_etat return; } - if ((*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante].objet == NULL) + if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL) { - if (pthread_mutex_lock(&((*(*s_etat_processus) - .s_liste_variables_partagees).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - if (recherche_variable_partagee(s_etat_processus, - (*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante].nom, - (*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante].variable_partagee, - (*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante].origine) == d_faux) - { - if (pthread_mutex_unlock(&((*(*s_etat_processus) - .s_liste_variables_partagees).mutex)) != 0) + (*(*s_etat_processus).pointeur_variable_courante).nom, + (*(*s_etat_processus).pointeur_variable_courante) + .variable_partagee, (*(*s_etat_processus) + .pointeur_variable_courante).origine) == NULL) + { + if (((*s_etat_processus).autorisation_nom_implicite == 'N') && + ((*((struct_nom *) (*s_objet_1).objet)).symbole + == d_faux)) { - (*s_etat_processus).erreur_systeme = d_es_processus; + liberation(s_etat_processus, s_objet_1); + liberation(s_etat_processus, s_objet_2); + + (*s_etat_processus).erreur_systeme = d_es; + (*s_etat_processus).erreur_execution = + d_ex_creation_variable_globale; return; } @@ -3269,16 +3273,12 @@ instruction_sto(struct_processus *s_etat else { liberation(s_etat_processus, (*(*s_etat_processus) - .s_liste_variables_partagees).table - [(*(*s_etat_processus).s_liste_variables_partagees) - .position_variable].objet); - - (*(*s_etat_processus).s_liste_variables_partagees).table - [(*(*s_etat_processus).s_liste_variables_partagees) - .position_variable].objet = s_objet_2; + .pointeur_variable_partagee_courante).objet); + (*(*s_etat_processus).pointeur_variable_partagee_courante) + .objet = s_objet_2; if (pthread_mutex_unlock(&((*(*s_etat_processus) - .s_liste_variables_partagees).mutex)) != 0) + .pointeur_variable_partagee_courante).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; @@ -3287,12 +3287,25 @@ instruction_sto(struct_processus *s_etat } else { - liberation(s_etat_processus, - (*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante].objet); + if (((*s_etat_processus).autorisation_nom_implicite == 'N') && + ((*((struct_nom *) (*s_objet_1).objet)).symbole == d_faux)) + { + if ((*(*s_etat_processus).pointeur_variable_courante) + .niveau == 1) + { + liberation(s_etat_processus, s_objet_1); + liberation(s_etat_processus, s_objet_2); - (*s_etat_processus).s_liste_variables[(*s_etat_processus) - .position_variable_courante].objet = s_objet_2; + (*s_etat_processus).erreur_execution = + d_ex_creation_variable_globale; + return; + } + } + + liberation(s_etat_processus, + (*(*s_etat_processus).pointeur_variable_courante).objet); + (*(*s_etat_processus).pointeur_variable_courante).objet = + s_objet_2; } } else @@ -3302,6 +3315,18 @@ instruction_sto(struct_processus *s_etat * une variable globale. */ + if (((*s_etat_processus).autorisation_nom_implicite == 'N') && + ((*((struct_nom *) (*s_objet_1).objet)).symbole == d_faux)) + { + liberation(s_etat_processus, s_objet_1); + liberation(s_etat_processus, s_objet_2); + + (*s_etat_processus).erreur_systeme = d_es; + (*s_etat_processus).erreur_execution = + d_ex_creation_variable_globale; + return; + } + if ((s_variable.nom = malloc((strlen((*((struct_nom *) (*s_objet_1).objet)).nom) + 1) * sizeof(unsigned char))) == NULL) @@ -3348,6 +3373,83 @@ instruction_sto(struct_processus *s_etat ================================================================================ */ +static struct +{ + struct_processus *s_etat_processus; + struct_liste_chainee *fd_stdin; + int pipe_entree; + volatile int erreur; +} arguments_stdin; + +static void * +thread_stdin(void *argument) +{ + integer8 longueur_ecriture; + + typeof(arguments_stdin) *ptr; + + struct_liste_chainee *l_element_courant; + + struct_processus *s_etat_processus; + + unsigned char *ligne; + + ptr = argument; + + l_element_courant = (*ptr).fd_stdin; + s_etat_processus = (*ptr).s_etat_processus; + (*ptr).erreur = d_es; + + while(l_element_courant != NULL) + { + if ((ligne = formateur_flux(s_etat_processus, + (unsigned char *) (*(*l_element_courant).donnee).objet, + &longueur_ecriture)) == NULL) + { + (*ptr).erreur = d_es_allocation_memoire; + close((*ptr).pipe_entree); + pthread_exit(NULL); + } + + while(write_atomic(s_etat_processus, (*ptr).pipe_entree, ligne, + (size_t) longueur_ecriture) != longueur_ecriture) + { + if (longueur_ecriture == -1) + { + (*ptr).erreur = d_es_processus; + close((*ptr).pipe_entree); + pthread_exit(NULL); + } + } + + free(ligne); + + while(write_atomic(s_etat_processus, (*ptr).pipe_entree, "\n", 1) + != 1) + { + if (longueur_ecriture == -1) + { + (*ptr).erreur = d_es_processus; + close((*ptr).pipe_entree); + pthread_exit(NULL); + } + } + + l_element_courant = (*l_element_courant).suivant; + } + + if (close((*ptr).pipe_entree) != 0) + { + (*ptr).erreur = d_es_processus; + } + else + { + (*ptr).erreur = d_es; + } + + pthread_exit(NULL); +} + void instruction_syseval(struct_processus *s_etat_processus) { @@ -3359,18 +3461,20 @@ instruction_syseval(struct_processus *s_ int pipes_sortie[2]; int status; + file *fpipe; + logical1 drapeau_fin; logical1 presence_stdin; + logical1 processus_tue; long i; long nombre_arguments; pid_t pid; - sigset_t oldset; - sigset_t set; + pthread_attr_t attributs; - ssize_t longueur_ecriture; + pthread_t thread_stdin_tid; struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_precedent; @@ -3381,9 +3485,16 @@ instruction_syseval(struct_processus *s_ struct_objet *s_objet_resultat; struct_objet *s_objet_temporaire; + struct pollfd fds; + struct sigaction action_courante; struct sigaction action_passee; + struct timespec attente; + + struct timeval horodatage_final; + struct timeval horodatage_initial; + unsigned char *ptr; unsigned char *ptr2; unsigned char registre_autorisation_empilement_programme; @@ -3391,12 +3502,13 @@ instruction_syseval(struct_processus *s_ unsigned char *registre_programme; unsigned char *tampon; - unsigned long longueur_lecture; - unsigned long longueur_tampon; - unsigned long nombre_iterations; - unsigned long nombre_lignes; - unsigned long pointeur; - unsigned long registre_position_courante; + integer8 longueur_lecture; + integer8 longueur_lue; + integer8 longueur_tampon; + integer8 longueur_traitee; + integer8 nombre_lignes; + integer8 pointeur; + integer8 registre_position_courante; (*s_etat_processus).erreur_execution = d_ex; @@ -3490,8 +3602,6 @@ instruction_syseval(struct_processus *s_ registre_programme = (*s_etat_processus).definitions_chainees; registre_position_courante = (*s_etat_processus).position_courante; - (*s_etat_processus).definitions_chainees = - (unsigned char *) (*s_objet).objet; (*s_etat_processus).position_courante = 0; (*s_etat_processus).autorisation_empilement_programme = 'N'; @@ -3499,30 +3609,14 @@ instruction_syseval(struct_processus *s_ * Échappement des guillemets */ - ptr = (*s_etat_processus).definitions_chainees; - ptr2 = ptr; - i = 0; - - while((*ptr) != d_code_fin_chaine) + if (((*s_etat_processus).definitions_chainees = + formateur_flux(s_etat_processus, (unsigned char *) + (*s_objet).objet, &longueur_traitee)) == NULL) { - if ((*ptr) == '\\') - { - switch (*(ptr + 1)) - { - case '"': - case '\\': - { - ptr++; - break; - } - } - } - - *ptr2++ = *ptr++; + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; } - *ptr2 = d_code_fin_chaine; - /* * Scission de la chaîne en différents arguments */ @@ -3534,6 +3628,8 @@ instruction_syseval(struct_processus *s_ { if (recherche_instruction_suivante(s_etat_processus) == d_erreur) { + free((*s_etat_processus).definitions_chainees); + (*s_etat_processus).autorisation_empilement_programme = registre_autorisation_empilement_programme; (*s_etat_processus).instruction_courante = @@ -3551,6 +3647,8 @@ instruction_syseval(struct_processus *s_ if ((s_objet_temporaire = allocation(s_etat_processus, CHN)) == NULL) { + free((*s_etat_processus).definitions_chainees); + (*s_etat_processus).autorisation_empilement_programme = registre_autorisation_empilement_programme; (*s_etat_processus).instruction_courante = @@ -3569,13 +3667,14 @@ instruction_syseval(struct_processus *s_ .instruction_courante; /* - * S'il y a des guillemets en début de chaîne, il y en - * a aussi à la fin de la chaîne et on les ôte. Les - * guillements intermédiaires sont protégés par une + * S'il y a des guillemets ou une apostrophe en début de + * chaîne, il y en * a aussi à la fin de la chaîne et on les + * ôte. Les guillements intermédiaires sont protégés par une * séquence d'échappement qui est enlevée. */ - if ((*s_etat_processus).instruction_courante[0] == '"') + if (((*s_etat_processus).instruction_courante[0] == '"') || + ((*s_etat_processus).instruction_courante[0] == '\'')) { if (strlen((*s_etat_processus).instruction_courante) >= 2) { @@ -3595,6 +3694,16 @@ instruction_syseval(struct_processus *s_ &((*s_etat_processus).l_base_pile), s_objet_temporaire) == d_erreur) { + free((*s_etat_processus).definitions_chainees); + + (*s_etat_processus).autorisation_empilement_programme = + registre_autorisation_empilement_programme; + (*s_etat_processus).instruction_courante = + registre_instruction_courante; + (*s_etat_processus).definitions_chainees = + registre_programme; + (*s_etat_processus).position_courante = + registre_position_courante; return; } } @@ -3607,6 +3716,8 @@ instruction_syseval(struct_processus *s_ nombre_arguments++; } while(drapeau_fin == d_faux); + free((*s_etat_processus).definitions_chainees); + (*s_etat_processus).autorisation_empilement_programme = registre_autorisation_empilement_programme; (*s_etat_processus).instruction_courante = @@ -3614,7 +3725,8 @@ instruction_syseval(struct_processus *s_ (*s_etat_processus).definitions_chainees = registre_programme; (*s_etat_processus).position_courante = registre_position_courante; - if ((arguments = malloc(nombre_arguments * sizeof(char *))) == NULL) + if ((arguments = malloc(((size_t) nombre_arguments) * sizeof(char *))) + == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; @@ -3629,23 +3741,6 @@ instruction_syseval(struct_processus *s_ l_element_courant = (*l_element_courant).suivant; } - action_courante.sa_handler = SIG_IGN; - action_courante.sa_flags = SA_NODEFER | SA_ONSTACK; - - if (sigaction(SIGINT, &action_courante, &action_passee) != 0) - { - for(i = 0; i < nombre_arguments; i++) - { - depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), - &s_objet_temporaire); - liberation(s_etat_processus, s_objet_temporaire); - } - - free(arguments); - (*s_etat_processus).erreur_systeme = d_es_signal; - return; - } - if (pipe(pipes_entree) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -3666,15 +3761,55 @@ instruction_syseval(struct_processus *s_ fflush(NULL); - sigfillset(&set); - pthread_sigmask(SIG_BLOCK, &set, &oldset); + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + + while(pthread_mutex_trylock(&mutex_sigaction) != 0) + { +# 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; + } + + nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); + +# 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; + return; + } + } + + action_courante.sa_handler = SIG_IGN; + action_courante.sa_flags = 0; + + if (sigaction(SIGINT, &action_courante, &action_passee) != 0) + { + for(i = 0; i < nombre_arguments; i++) + { + depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), + &s_objet_temporaire); + liberation(s_etat_processus, s_objet_temporaire); + } + + free(arguments); + (*s_etat_processus).erreur_systeme = d_es_signal; + return; + } verrouillage_threads_concurrents(s_etat_processus); - pid = fork(); - deverrouillage_threads_concurrents(s_etat_processus); - pthread_sigmask(SIG_SETMASK, &oldset, NULL); - sigpending(&set); + pid = fork(); if (pid < 0) { @@ -3719,22 +3854,24 @@ instruction_syseval(struct_processus *s_ } else if (pid == 0) { + (*s_etat_processus).erreur_systeme = d_es; + if (close(pipes_entree[1]) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; - return; + printf("%d\n",__LINE__); } if (close(pipes_sortie[0]) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; - return; + printf("%d\n",__LINE__); } if (close(pipes_erreur[0]) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; - return; + printf("%d\n",__LINE__); } if (pipes_entree[0] != STDIN_FILENO) @@ -3742,7 +3879,7 @@ instruction_syseval(struct_processus *s_ if (dup2(pipes_entree[0], STDIN_FILENO) == -1) { (*s_etat_processus).erreur_systeme = d_es_processus; - return; + printf("%d\n",__LINE__); } } @@ -3751,7 +3888,7 @@ instruction_syseval(struct_processus *s_ if (dup2(pipes_sortie[1], STDOUT_FILENO) == -1) { (*s_etat_processus).erreur_systeme = d_es_processus; - return; + printf("%d\n",__LINE__); } } @@ -3760,18 +3897,15 @@ instruction_syseval(struct_processus *s_ if (dup2(pipes_sortie[1], STDERR_FILENO) == -1) { (*s_etat_processus).erreur_systeme = d_es_processus; - return; + printf("%d\n",__LINE__); } } - if (nombre_arguments != 0) + if ((nombre_arguments != 0) && ((*s_etat_processus).erreur_systeme + == d_es)) { execvp(arguments[0], arguments); } - else - { - exit(EXIT_SUCCESS); - } /* * L'appel système execvp() a généré une erreur et n'a pu exécuter @@ -3800,251 +3934,154 @@ instruction_syseval(struct_processus *s_ write_atomic(s_etat_processus, pipes_erreur[1], " ", 1); close(pipes_erreur[1]); + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : erreur interne dans SYSEVAL [%d]\n", + (int) getpid()); + } + else + { + printf("+++System : SYSEVAL internal error [%d]\n", + (int) getpid()); + } + exit(EXIT_SUCCESS); } else { - if (close(pipes_entree[0]) != 0) + if (sigaction(SIGINT, &action_passee, NULL) != 0) { - (*s_etat_processus).erreur_systeme = d_es_processus; + for(i = 0; i < nombre_arguments; i++) + { + depilement(s_etat_processus, + &((*s_etat_processus).l_base_pile), + &s_objet_temporaire); + liberation(s_etat_processus, s_objet_temporaire); + } + + free(arguments); + (*s_etat_processus).erreur_systeme = d_es_signal; return; } - if (close(pipes_sortie[1]) != 0) + if (pthread_mutex_unlock(&mutex_sigaction) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } - if (close(pipes_erreur[1]) != 0) + deverrouillage_threads_concurrents(s_etat_processus); + + if (close(pipes_entree[0]) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } - if (presence_stdin == d_vrai) + if (close(pipes_sortie[1]) != 0) { - l_element_courant = l_element_stdin; - - while(l_element_courant != NULL) - { - longueur_ecriture = strlen((unsigned char *) - (*(*l_element_courant).donnee).objet); - -# 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; - } - - while(write_atomic(s_etat_processus, - pipes_entree[1], (unsigned char *) - (*(*l_element_courant).donnee).objet, - longueur_ecriture) != longueur_ecriture) - { -# ifndef SEMAPHORES_NOMMES - while(sem_wait(&((*s_etat_processus) - .semaphore_fork)) == -1) -# else - while(sem_wait((*s_etat_processus) - .semaphore_fork) == -1) -# endif - { - if (errno != EINTR) - { - (*s_etat_processus).erreur_systeme = - d_es_processus; - return; - } - } - - if (longueur_ecriture == -1) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - 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; - } - } - - while(write_atomic(s_etat_processus, - pipes_entree[1], "\n", 1) != 1) - { -# ifndef SEMAPHORES_NOMMES - while(sem_wait(&((*s_etat_processus) - .semaphore_fork)) == -1) -# else - while(sem_wait((*s_etat_processus) - .semaphore_fork) == -1) -# endif - { - if (errno != EINTR) - { - (*s_etat_processus).erreur_systeme = - d_es_processus; - return; - } - } - - if (longueur_ecriture == -1) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - 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; - } - } - -# ifndef SEMAPHORES_NOMMES - while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) -# else - while(sem_wait((*s_etat_processus).semaphore_fork) == -1) -# endif - { - if (errno != EINTR) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - } - - l_element_courant = (*l_element_courant).suivant; - } + (*s_etat_processus).erreur_systeme = d_es_processus; + return; } - if (close(pipes_entree[1]) != 0) + if (close(pipes_erreur[1]) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } - do + if (presence_stdin == d_vrai) { - if (kill(pid, 0) != 0) + // L'écriture sur stdin est dans un thread séparé pour + // ne pas bloquer. + + if (pthread_attr_init(&attributs) != 0) { - break; + (*s_etat_processus).erreur_systeme = d_es_processus; + return; } - /* - * Récupération de la valeur de retour du processus détaché - */ - -# ifndef SEMAPHORES_NOMMES - if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) -# else - if (sem_post((*s_etat_processus).semaphore_fork) != 0) -# endif + if (pthread_attr_setdetachstate(&attributs, + PTHREAD_CREATE_JOINABLE) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } - if (waitpid(pid, &status, 0) == -1) - { -# ifndef SEMAPHORES_NOMMES - if (sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) -# else - if (sem_wait((*s_etat_processus).semaphore_fork) == -1) -# endif - { - if (errno != EINTR) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - } + arguments_stdin.s_etat_processus = s_etat_processus; + arguments_stdin.fd_stdin = l_element_stdin; + arguments_stdin.pipe_entree = pipes_entree[1]; + if (pthread_create(&thread_stdin_tid, &attributs, thread_stdin, + &arguments_stdin) != 0) + { (*s_etat_processus).erreur_systeme = d_es_processus; return; } -# ifndef SEMAPHORES_NOMMES - if (sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) -# else - if (sem_wait((*s_etat_processus).semaphore_fork) == -1) -# endif + if (pthread_attr_destroy(&attributs) != 0) { - if (errno != EINTR) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } + (*s_etat_processus).erreur_systeme = d_es_processus; + return; } - } while((!WIFEXITED(status)) && (!WIFSIGNALED(status))); + } - longueur_lecture = 256; + longueur_lecture = 65536; + longueur_lue = 0; pointeur = 0; - nombre_iterations = 1; - if ((tampon = malloc((longueur_lecture + 1) * + if ((tampon = malloc(((size_t) (longueur_lecture + 1)) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } + tampon[0] = d_code_fin_chaine; + # 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 - while((ios = read_atomic(s_etat_processus, + processus_tue = d_faux; + + while((ios = (int) read_atomic_signal(s_etat_processus, pipes_sortie[0], &(tampon[pointeur]), - longueur_lecture)) > 0) + (size_t) longueur_lecture)) >= 0) { + if ((ios == 0) && ((*s_etat_processus) + .var_volatile_requete_arret == 0)) + { + // Correspond à un buffer vide en l'absence + // d'interruption. On ne boucle pas, il n'y a rien à + // lire. + + break; + } + # 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; + return; } + longueur_lue += ios; tampon[pointeur + ios] = d_code_fin_chaine; - pointeur += longueur_lecture; - nombre_iterations++; + pointeur += ios; if ((tampon = realloc(tampon, - ((nombre_iterations * longueur_lecture) + 1) * - sizeof(unsigned char))) == NULL) + ((size_t) ((longueur_lue + longueur_lecture) + 1)) + * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -4052,20 +4089,77 @@ instruction_syseval(struct_processus *s_ } # ifndef SEMAPHORES_NOMMES - if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) + 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; } + + if ((*s_etat_processus).var_volatile_requete_arret == -1) + { + gettimeofday(&horodatage_initial, NULL); + kill(pid, SIGTERM); + + if ((fpipe = fdopen(pipes_sortie[0], "r")) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + + if (kill(pid, 0) == 0) + { + while(feof(fpipe) == 0) + { + fds.fd = pipes_sortie[0]; + fds.events = POLLIN; + + if (poll(&fds, 1, 0) > 0) + { + getc(fpipe); + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + } + else + { + nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); + } + + gettimeofday(&horodatage_final, NULL); + + // Si au bout de 10 secondes après le premier + // signal, il reste des données à lire, le processus + // est sans doute encore actif. On envoie donc + // un signal 9. + + if ((horodatage_final.tv_sec - + horodatage_initial.tv_sec) > 10) + { + kill(pid, SIGKILL); + gettimeofday(&horodatage_initial, NULL); + processus_tue = d_vrai; + } + } + } + } + + if (processus_tue == d_vrai) + { + break; + } } # 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) @@ -4075,13 +4169,73 @@ instruction_syseval(struct_processus *s_ } } - if ((tampon = realloc(tampon, (strlen(tampon) + 1) * - sizeof(unsigned char))) == NULL) + if (presence_stdin == d_vrai) { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; + if (pthread_join(thread_stdin_tid, NULL) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + + if (arguments_stdin.erreur != d_es) + { + (*s_etat_processus).erreur_systeme = arguments_stdin.erreur; + return; + } } + else + { + if (close(pipes_entree[1]) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + } + + do + { + if (kill(pid, 0) != 0) + { + // Le processus n'existe plus. + break; + } + + /* + * Récupération de la valeur de retour du processus détaché + */ + +# 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; + } + + while(waitpid(pid, &status, 0) == -1) + { + if (errno != EINTR) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + } + +# 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; + } + } + } while((!WIFEXITED(status)) && (!WIFSIGNALED(status))); if (ios == -1) { @@ -4099,10 +4253,10 @@ instruction_syseval(struct_processus *s_ * Transformation de la chaîne en liste */ - longueur_tampon = strlen(tampon); + longueur_tampon = (integer8) strlen(tampon); for(i = 0, ptr = tampon, nombre_lignes = 0; - i < (long) longueur_tampon; i++, ptr++) + i < longueur_tampon; i++, ptr++) { if ((*ptr) == d_code_retour_chariot) { @@ -4136,7 +4290,7 @@ instruction_syseval(struct_processus *s_ l_element_courant = (struct_liste_chainee *) (*s_objet_resultat).objet; - for(i = 0, ptr = tampon; i < (long) nombre_lignes; i++) + for(i = 0, ptr = tampon; i < nombre_lignes; i++) { if (((*l_element_courant).donnee = allocation(s_etat_processus, CHN)) == NULL) @@ -4147,16 +4301,14 @@ instruction_syseval(struct_processus *s_ } if (((*(*l_element_courant).donnee).objet = - malloc((strlen(ptr) + 1) * sizeof(unsigned char))) - == NULL) + analyse_flux(s_etat_processus, ptr, + (integer8) strlen(ptr))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } - strcpy((*(*l_element_courant).donnee).objet, ptr); - while((*ptr) != d_code_fin_chaine) { ptr++; @@ -4187,20 +4339,6 @@ instruction_syseval(struct_processus *s_ free(tampon); } - if (sigaction(SIGINT, &action_passee, NULL) != 0) - { - for(i = 0; i < nombre_arguments; i++) - { - depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), - &s_objet_temporaire); - liberation(s_etat_processus, s_objet_temporaire); - } - - free(arguments); - (*s_etat_processus).erreur_systeme = d_es_signal; - return; - } - for(i = 0; i < nombre_arguments; i++) { depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), @@ -4208,6 +4346,8 @@ instruction_syseval(struct_processus *s_ liberation(s_etat_processus, s_objet_temporaire); } + free(arguments); + if ((tampon = malloc(sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -4215,9 +4355,9 @@ instruction_syseval(struct_processus *s_ } # ifndef SEMAPHORES_NOMMES - if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) + 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; @@ -4236,9 +4376,9 @@ instruction_syseval(struct_processus *s_ == d_erreur) { # 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) @@ -4259,9 +4399,9 @@ instruction_syseval(struct_processus *s_ } # 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) @@ -4277,7 +4417,6 @@ instruction_syseval(struct_processus *s_ return; } - free(arguments); free(tampon); } else @@ -4874,7 +5013,7 @@ instruction_sci(struct_processus *s_etat return; } - (*((logical8 *) (*s_objet).objet)) = + (*((logical8 *) (*s_objet).objet)) = (logical8) (*((integer8 *) (*s_objet_argument).objet)); i43 = test_cfsf(s_etat_processus, 43); @@ -4912,15 +5051,15 @@ instruction_sci(struct_processus *s_etat { if (valeur_binaire[i] == '0') { - cf(s_etat_processus, j++); + cf(s_etat_processus, (unsigned char) j++); } else { - sf(s_etat_processus, j++); + sf(s_etat_processus, (unsigned char) j++); } } - for(; j <= 56; cf(s_etat_processus, j++)); + for(; j <= 56; cf(s_etat_processus, (unsigned char) j++)); cf(s_etat_processus, 49); sf(s_etat_processus, 50);