--- rpl/src/instructions_s1.c 2019/05/16 12:03:01 1.107 +++ rpl/src/instructions_s1.c 2022/06/09 12:40:57 1.119 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.31 - Copyright (C) 1989-2019 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. @@ -3460,8 +3460,11 @@ 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; @@ -3481,11 +3484,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; @@ -3658,13 +3666,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) { @@ -3869,7 +3878,7 @@ instruction_syseval(struct_processus *s_ if (dup2(pipes_entree[0], STDIN_FILENO) == -1) { (*s_etat_processus).erreur_systeme = d_es_processus; - printf("%d\n",__LINE__); + printf("%d\n",__LINE__); } } @@ -3878,7 +3887,7 @@ instruction_syseval(struct_processus *s_ if (dup2(pipes_sortie[1], STDOUT_FILENO) == -1) { (*s_etat_processus).erreur_systeme = d_es_processus; - printf("%d\n",__LINE__); + printf("%d\n",__LINE__); } } @@ -3887,7 +3896,7 @@ instruction_syseval(struct_processus *s_ if (dup2(pipes_sortie[1], STDERR_FILENO) == -1) { (*s_etat_processus).erreur_systeme = d_es_processus; - printf("%d\n",__LINE__); + printf("%d\n",__LINE__); } } @@ -3926,7 +3935,7 @@ instruction_syseval(struct_processus *s_ if ((*s_etat_processus).langue == 'F') { - printf("+++Système : erreurinterne dans SYSEVAL [%d]\n", + printf("+++Système : erreur interne dans SYSEVAL [%d]\n", (int) getpid()); } else @@ -4039,10 +4048,22 @@ instruction_syseval(struct_processus *s_ return; } + processus_tue = d_faux; + while((ios = (int) read_atomic_signal(s_etat_processus, pipes_sortie[0], &(tampon[pointeur]), - (size_t) 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)) != 0) # else @@ -4078,15 +4099,60 @@ instruction_syseval(struct_processus *s_ if ((*s_etat_processus).var_volatile_requete_arret == -1) { - if ((*s_etat_processus).var_volatile_alarme == -1) + gettimeofday(&horodatage_initial, NULL); + kill(pid, SIGTERM); + + if ((fpipe = fdopen(pipes_sortie[0], "r")) == NULL) { - kill(pid, SIGKILL); + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; } - else + + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + + if (kill(pid, 0) == 0) { - kill(pid, SIGTERM); + 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