--- rpl/src/rpl.c 2010/08/06 15:33:04 1.36 +++ rpl/src/rpl.c 2011/09/09 12:23:25 1.81 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.18 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.3 + Copyright (C) 1989-2011 Dr. BERTRAND Joël This file is part of RPL/2. @@ -23,9 +23,12 @@ #define MAIN_RPL #include "rpl-conv.h" -#ifdef OS2 +#ifdef IPCS_SYSV +#ifndef OS2 unsigned char *chemin_semaphores_SysV; #endif +#endif + /* ================================================================================ @@ -43,7 +46,6 @@ rplinit(int argc, char *argv[], unsigned int erreur_historique; int option_P; - int status; logical1 core; logical1 debug; @@ -102,6 +104,8 @@ rplinit(int argc, char *argv[], unsigned volatile int erreur; volatile unsigned char traitement_fichier_temporaire; + errno = 0; + # ifdef DEBUG_MEMOIRE debug_memoire_initialisation(); # endif @@ -178,14 +182,15 @@ rplinit(int argc, char *argv[], unsigned (*s_etat_processus).langue = 'E'; } + initialisation_contexte_cas(s_etat_processus); + (*s_etat_processus).exception = d_ep; (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex; + (*s_etat_processus).compteur_violation_d_acces = 0; (*s_etat_processus).rpl_home = rpl_home; - insertion_thread(s_etat_processus, d_vrai); - pthread_mutexattr_init(&attributs_mutex); pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL); pthread_mutex_init(&((*s_etat_processus).mutex), &attributs_mutex); @@ -234,7 +239,49 @@ rplinit(int argc, char *argv[], unsigned .mutex), &attributs_mutex); pthread_mutexattr_destroy(&attributs_mutex); + (*s_etat_processus).chemin_fichiers_temporaires = + recherche_chemin_fichiers_temporaires(s_etat_processus); + +# ifdef IPCS_SYSV +# ifndef OS2 + chemin_semaphores_SysV = (*s_etat_processus).chemin_fichiers_temporaires; +# endif +# endif + +# ifdef _BROKEN_SIGINFO + creation_fifos_signaux(s_etat_processus); +# ifdef return +# undef return +# endif +# define return destruction_fifos_signaux(s_etat_processus); return +# endif + + insertion_thread(s_etat_processus, d_vrai); + +# ifndef OS2 localisation_courante(s_etat_processus); +# else + if ((*s_etat_processus).erreur_systeme != d_es) + { + if (((*s_etat_processus).localisation = malloc((strlen(d_locale) + 1) * + sizeof(unsigned char))) == NULL) + { + if ((*s_etat_processus).langue == 'F') + { + uprintf("+++Système : Mémoire insuffisante\n"); + } + else + { + uprintf("+++System : Not enough memory\n"); + } + + return(EXIT_FAILURE); + } + + strcpy((*s_etat_processus).localisation, d_locale); + } +# endif + (*s_etat_processus).erreur_systeme = d_es; if ((*s_etat_processus).localisation == NULL) @@ -262,11 +309,11 @@ rplinit(int argc, char *argv[], unsigned if ((*s_etat_processus).langue == 'F') { - printf("+++Copyright (C) 1989 à 2009, 2010 BERTRAND Joël\n"); + printf("+++Copyright (C) 1989 à 2010, 2011 BERTRAND Joël\n"); } else { - printf("+++Copyright (C) 1989 to 2009, 2010 BERTRAND Joel\n"); + printf("+++Copyright (C) 1989 to 2010, 2011 BERTRAND Joel\n"); } if (getenv("HOME") != NULL) @@ -330,7 +377,7 @@ rplinit(int argc, char *argv[], unsigned // Initialisation d'une pile de signal pour récupérer les // débordement de pile -# if !defined(Cygwin) +# if !defined(Cygwin) && !defined(OpenBSD) if (((*s_etat_processus).pile_signal.ss_sp = malloc((*s_etat_processus).pile_signal.ss_size = SIGSTKSZ)) == NULL) @@ -369,7 +416,11 @@ rplinit(int argc, char *argv[], unsigned } # endif +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption1; +# else + action.sa_handler = interruption1; +# endif action.sa_flags = SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGINT, &action, NULL) != 0) @@ -389,7 +440,68 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGINT); + + if (signal_test != SIGINT) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + + if (sigaction(SIGTERM, &action, NULL) != 0) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + + signal_test = SIGTEST; + kill(getpid(), SIGTERM); + + if (signal_test != SIGTERM) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption2; +# else + action.sa_handler = interruption2; +# endif action.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGTSTP, &action, NULL) != 0) @@ -407,7 +519,32 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGTSTP); + + if (signal_test != SIGTSTP) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption4; +# else + action.sa_handler = interruption4; +# endif + // SIGCONT ne doit pas pouvoir être appelé depuis son gestionnaire. action.sa_flags = SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGSTART, &action, NULL) != 0) @@ -425,6 +562,26 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGSTART); + + if (signal_test != SIGSTART) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + if (sigaction(SIGCONT, &action, NULL) != 0) { if ((*s_etat_processus).langue == 'F') @@ -440,7 +597,31 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGCONT); + + if (signal_test != SIGCONT) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption5; +# else + action.sa_handler = interruption5; +# endif action.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGFSTOP, &action, NULL) != 0) @@ -460,7 +641,31 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGFSTOP); + + if (signal_test != SIGFSTOP) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption11; +# else + action.sa_handler = interruption11; +# endif action.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGFABORT, &action, NULL) != 0) @@ -480,7 +685,31 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGFABORT); + + if (signal_test != SIGFABORT) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption8; +# else + action.sa_handler = interruption8; +# endif action.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGURG, &action, NULL) != 0) @@ -500,7 +729,31 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGURG); + + if (signal_test != SIGURG) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption7; +# else + action.sa_handler = interruption7; +# endif action.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGPIPE, &action, NULL) != 0) @@ -520,8 +773,32 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGPIPE); + + if (signal_test != SIGPIPE) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption6; - action.sa_flags = SA_ONSTACK | SA_SIGINFO; +# else + action.sa_handler = interruption6; +# endif + action.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_NODEFER; if (sigaction(SIGINJECT, &action, NULL) != 0) { @@ -540,8 +817,32 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGINJECT); + + if (signal_test != SIGINJECT) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption9; - action.sa_flags = SA_ONSTACK | SA_SIGINFO; +# else + action.sa_handler = interruption9; +# endif + action.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_NODEFER; if (sigaction(SIGABORT, &action, NULL) != 0) { @@ -560,7 +861,31 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGABORT); + + if (signal_test != SIGABORT) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption1; +# else + action.sa_handler = interruption1; +# endif action.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGALRM, &action, NULL) != 0) @@ -580,15 +905,32 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } - action.sa_sigaction = interruption3; - action.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO; + signal_test = SIGTEST; + kill(getpid(), SIGALRM); - (*s_etat_processus).chemin_fichiers_temporaires = - recherche_chemin_fichiers_temporaires(s_etat_processus); + if (signal_test != SIGALRM) + { + erreur = d_es_signal; -# ifdef OS2 - chemin_semaphores_SysV = (*s_etat_processus).chemin_fichiers_temporaires; + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals failed\n"); + } + + return(EXIT_FAILURE); + } + +# ifndef _BROKEN_SIGINFO + action.sa_sigaction = interruption3; +# else + action.sa_handler = interruption3; # endif + action.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO; erreur = d_absence_erreur; core = d_faux; @@ -1512,7 +1854,11 @@ rplinit(int argc, char *argv[], unsigned if (option_n == d_vrai) { +# ifndef _BROKEN_SIGINFO action.sa_sigaction = interruption10; +# else + action.sa_handler = interruption10; +# endif action.sa_flags = SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGHUP, &action, NULL) != 0) @@ -1729,10 +2075,20 @@ rplinit(int argc, char *argv[], unsigned (*s_etat_processus).affichage_arguments = 'N'; (*s_etat_processus).autorisation_conversion_chaine = 'Y'; (*s_etat_processus).autorisation_evaluation_nom = 'Y'; - (*s_etat_processus).autorisation_nom_implicite = 'Y'; + + if (mode_interactif == d_vrai) + { + (*s_etat_processus).autorisation_nom_implicite = 'Y'; + } + else + { + (*s_etat_processus).autorisation_nom_implicite = 'N'; + } + (*s_etat_processus).autorisation_empilement_programme = 'N'; (*s_etat_processus).requete_arret = 'N'; (*s_etat_processus).evaluation_forcee = 'N'; + (*s_etat_processus).recherche_type = 'N'; (*s_etat_processus).constante_symbolique = 'N'; (*s_etat_processus).traitement_symbolique = 'N'; @@ -1744,10 +2100,10 @@ rplinit(int argc, char *argv[], unsigned (*s_etat_processus).l_base_pile = NULL; (*s_etat_processus).l_base_pile_last = NULL; - (*s_etat_processus).s_liste_variables = NULL; + (*s_etat_processus).s_arbre_variables = NULL; + (*s_etat_processus).l_liste_variables_par_niveau = NULL; (*s_etat_processus).gel_liste_variables = d_faux; - (*s_etat_processus).nombre_variables = 0; - (*s_etat_processus).nombre_variables_allouees = 0; + (*s_etat_processus).pointeur_variable_courante = NULL; (*s_etat_processus).s_liste_variables_statiques = NULL; (*s_etat_processus).nombre_variables_statiques = 0; (*s_etat_processus).nombre_variables_statiques_allouees = 0; @@ -1755,7 +2111,6 @@ rplinit(int argc, char *argv[], unsigned (*s_etat_processus).niveau_initial = 0; (*s_etat_processus).creation_variables_statiques = d_faux; (*s_etat_processus).creation_variables_partagees = d_faux; - (*s_etat_processus).position_variable_courante = 0; (*s_etat_processus).position_variable_statique_courante = 0; (*s_etat_processus).s_bibliotheques = NULL; @@ -1888,6 +2243,7 @@ rplinit(int argc, char *argv[], unsigned (*s_etat_processus).pid_processus_pere = getpid(); (*s_etat_processus).processus_detache = d_vrai; (*s_etat_processus).var_volatile_processus_pere = -1; + (*s_etat_processus).var_volatile_processus_racine = -1; (*s_etat_processus).var_volatile_traitement_retarde_stop = 0; (*s_etat_processus).var_volatile_alarme = 0; (*s_etat_processus).var_volatile_requete_arret = 0; @@ -1900,6 +2256,8 @@ rplinit(int argc, char *argv[], unsigned initialisation_allocateur(s_etat_processus); initialisation_drapeaux(s_etat_processus); + initialisation_variables(s_etat_processus); + initialisation_instructions(s_etat_processus); if ((*s_etat_processus).erreur_systeme != d_es) { @@ -1967,7 +2325,7 @@ rplinit(int argc, char *argv[], unsigned free((*s_etat_processus).instruction_courante); - if ((*s_etat_processus).erreur_systeme == d_es_allocation_memoire) + if ((*s_etat_processus).erreur_systeme != d_es) { erreur = d_es_allocation_memoire; } @@ -2285,7 +2643,7 @@ rplinit(int argc, char *argv[], unsigned (*s_etat_processus).position_courante = 0; (*s_etat_processus).traitement_cycle_exit = 'N'; - if ((*s_etat_processus).nombre_variables == 0) + if ((*s_etat_processus).s_arbre_variables == NULL) { if ((*s_etat_processus).langue == 'F') { @@ -2345,9 +2703,8 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } - if ((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante].niveau != 0) + if ((*(*s_etat_processus).pointeur_variable_courante) + .niveau != 0) { if ((*s_etat_processus).langue == 'F') { @@ -2433,8 +2790,6 @@ rplinit(int argc, char *argv[], unsigned fflush(stdout); - initialisation_instructions(s_etat_processus); - if (arguments != NULL) { tampon = (*s_etat_processus).definitions_chainees; @@ -2651,6 +3006,20 @@ rplinit(int argc, char *argv[], unsigned if (setjmp(contexte_initial) == 0) { erreur = sequenceur(s_etat_processus); + + if (erreur == d_absence_erreur) + { + if (((*s_etat_processus).var_volatile_alarme + == 0) && ((*s_etat_processus) + .arret_depuis_abort == 0) && + ((*s_etat_processus).at_exit + != NULL)) + { + erreur = evaluation(s_etat_processus, + (*s_etat_processus).at_exit, + 'E'); + } + } } } else @@ -2658,18 +3027,20 @@ rplinit(int argc, char *argv[], unsigned if (setjmp(contexte_initial) == 0) { erreur = sequenceur_optimise(s_etat_processus); - } - } - if (erreur == d_absence_erreur) - { - if (((*s_etat_processus).var_volatile_alarme == 0) - && ((*s_etat_processus).arret_depuis_abort - == 0) && ((*s_etat_processus).at_exit - != NULL)) - { - erreur = evaluation(s_etat_processus, - (*s_etat_processus).at_exit, 'E'); + if (erreur == d_absence_erreur) + { + if (((*s_etat_processus).var_volatile_alarme + == 0) && ((*s_etat_processus) + .arret_depuis_abort == 0) && + ((*s_etat_processus).at_exit + != NULL)) + { + erreur = evaluation(s_etat_processus, + (*s_etat_processus).at_exit, + 'E'); + } + } } } } @@ -2878,8 +3249,6 @@ rplinit(int argc, char *argv[], unsigned while((*s_etat_processus).l_base_pile_processus != NULL) { - status = 0; - l_element_courant = (void *) (*s_etat_processus).l_base_pile_processus; @@ -3103,14 +3472,9 @@ rplinit(int argc, char *argv[], unsigned * le libérer... */ - for(i = 0; i < (*s_etat_processus).nombre_variables; i++) - { - liberation(s_etat_processus, - (*s_etat_processus).s_liste_variables[i].objet); - free((*s_etat_processus).s_liste_variables[i].nom); - } - - free((*s_etat_processus).s_liste_variables); + liberation_arbre_variables(s_etat_processus, + (*s_etat_processus).s_arbre_variables, d_vrai); + free((*s_etat_processus).pointeurs_caracteres_variables); for(i = 0; i < (*s_etat_processus) .nombre_variables_statiques; i++) @@ -3418,8 +3782,6 @@ rplinit(int argc, char *argv[], unsigned l_element_courant = l_element_suivant; } - free((*s_etat_processus).chemin_fichiers_temporaires); - l_element_courant = (*s_etat_processus).s_marques; while(l_element_courant != NULL) { @@ -3471,12 +3833,6 @@ rplinit(int argc, char *argv[], unsigned } } -# ifndef Cygwin - (*s_etat_processus).pile_signal.ss_flags = SS_DISABLE; - sigaltstack(&((*s_etat_processus).pile_signal), NULL); - free((*s_etat_processus).pile_signal.ss_sp); -# endif - closelog(); pthread_mutex_destroy(&((*s_etat_processus).protection_liste_mutexes)); @@ -3514,6 +3870,14 @@ rplinit(int argc, char *argv[], unsigned sem_gestionnaires_signaux_atomique); # endif +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# undef return +# endif + + liberation_contexte_cas(s_etat_processus); + + free((*s_etat_processus).chemin_fichiers_temporaires); free(s_etat_processus); # ifdef DEBUG_MEMOIRE