/* ================================================================================ RPL/2 (R) version 4.1.32 Copyright (C) 1989-2020 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" /* ================================================================================ Fonction 'alarm' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_alarm(struct_processus *s_etat_processus) { double duree; int code_retour; int erreur; integer8 nombre_elements; logical1 specification_date; struct_liste_chainee *l_element_courant; struct_objet *s_objet_argument; struct timeb st; struct timespec attente; struct timeval debut_interruption; struct timeval duree_interruption; struct timeval fin_interruption; struct tm *s_time_actuel; struct tm s_time_alarme; struct tm s_time_registre; time_t alarme; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n ALARM "); if ((*s_etat_processus).langue == 'F') { printf("(suspension du processus jusqu'à un instant spécifié)\n\n"); } else { printf("(wait until timestamp)\n\n"); } printf(" 1: %s\n\n", d_LST); if ((*s_etat_processus).langue == 'F') { printf(" Utilisation :\n\n"); } else { printf(" Usage:\n\n"); } printf(" { hours minutes } ALARM\n"); printf(" { hours minutes seconds } ALARM\n"); printf(" { hours minutes seconds day } ALARM\n"); printf(" { hours minutes seconds day month } ALARM\n"); printf(" { hours minutes seconds day month year } ALARM\n"); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = 1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet_argument).type == LST) { l_element_courant = (*s_objet_argument).objet; nombre_elements = 0; while(l_element_courant != NULL) { if ((*(*l_element_courant).donnee).type != INT) { (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; liberation(s_etat_processus, s_objet_argument); return; } l_element_courant = (*l_element_courant).suivant; nombre_elements++; } if ((nombre_elements < 2) || (nombre_elements > 6)) { (*s_etat_processus).erreur_execution = d_ex_argument_invalide; liberation(s_etat_processus, s_objet_argument); return; } st.time = time(NULL); s_time_actuel = localtime(&(st.time)); l_element_courant = (*s_objet_argument).objet; s_time_alarme.tm_hour = (int) (*((integer8 *) (*(*l_element_courant) .donnee).objet)); l_element_courant = (*l_element_courant).suivant; s_time_alarme.tm_min = (int) (*((integer8 *) (*(*l_element_courant) .donnee).objet)); l_element_courant = (*l_element_courant).suivant; specification_date = d_faux; if (l_element_courant != NULL) { s_time_alarme.tm_sec = (int) (*((integer8 *) (*(*l_element_courant) .donnee).objet)); l_element_courant = (*l_element_courant).suivant; if (l_element_courant != NULL) { specification_date = d_vrai; s_time_alarme.tm_mday = (int) (*((integer8 *) (*(*l_element_courant).donnee).objet)); l_element_courant = (*l_element_courant).suivant; if (l_element_courant != NULL) { s_time_alarme.tm_mon = (int) ((*((integer8 *) (*(*l_element_courant).donnee).objet)) - 1); l_element_courant = (*l_element_courant).suivant; if (l_element_courant != NULL) { s_time_alarme.tm_year = (int) ((*((integer8 *) (*(*l_element_courant).donnee).objet)) - 1900); l_element_courant = (*l_element_courant).suivant; } else { s_time_alarme.tm_year = (*s_time_actuel).tm_year; } } else { s_time_alarme.tm_mon = (*s_time_actuel).tm_mon; s_time_alarme.tm_year = (*s_time_actuel).tm_year; } } else { s_time_alarme.tm_mday = (*s_time_actuel).tm_mday; s_time_alarme.tm_mon = (*s_time_actuel).tm_mon; s_time_alarme.tm_year = (*s_time_actuel).tm_year; } } else { s_time_alarme.tm_sec = 0; s_time_alarme.tm_mday = (*s_time_actuel).tm_mday; s_time_alarme.tm_mon = (*s_time_actuel).tm_mon; s_time_alarme.tm_year = (*s_time_actuel).tm_year; } s_time_alarme.tm_isdst = -1; s_time_registre = s_time_alarme; alarme = mktime(&s_time_alarme); if ((s_time_alarme.tm_sec != s_time_registre.tm_sec) || (s_time_alarme.tm_min != s_time_registre.tm_min) || (s_time_alarme.tm_hour != s_time_registre.tm_hour) || (s_time_alarme.tm_mday != s_time_registre.tm_mday) || (s_time_alarme.tm_mon != s_time_registre.tm_mon) || (s_time_alarme.tm_year != s_time_registre.tm_year)) { (*s_etat_processus).erreur_execution = d_ex_argument_invalide; liberation(s_etat_processus, s_objet_argument); return; } while((duree = difftime(alarme, st.time)) < 0) { if (specification_date == d_vrai) { (*s_etat_processus).erreur_execution = d_ex_argument_invalide; liberation(s_etat_processus, s_objet_argument); return; } s_time_alarme.tm_mday++; alarme = mktime(&s_time_alarme); } attente.tv_nsec = (long) ((duree - (double) (attente.tv_sec = (time_t) floor(duree))) * 1000000000); if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, "Sleep function (ALARM)"); if ((*s_etat_processus).erreur_systeme != d_es) { return; } } do { code_retour = nanosleep(&attente, &attente); erreur = errno; if (code_retour == -1) { gettimeofday(&debut_interruption, NULL); scrutation_injection(s_etat_processus); if (pthread_mutex_lock(&((*s_etat_processus) .mutex_interruptions)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if ((*s_etat_processus).nombre_interruptions_non_affectees != 0) { affectation_interruptions_logicielles(s_etat_processus); } if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_interruptions)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if ((*s_etat_processus).nombre_interruptions_en_queue != 0) { traitement_interruptions_logicielles(s_etat_processus); } gettimeofday(&fin_interruption, NULL); if (fin_interruption.tv_usec < debut_interruption.tv_usec) { duree_interruption.tv_usec = (1000000 + fin_interruption.tv_usec) - debut_interruption.tv_usec; duree_interruption.tv_sec = fin_interruption.tv_sec - (debut_interruption.tv_sec + 1); } else { duree_interruption.tv_usec = fin_interruption.tv_usec - debut_interruption.tv_usec; duree_interruption.tv_sec = fin_interruption.tv_sec - debut_interruption.tv_sec; } if (attente.tv_nsec < (1000 * duree_interruption.tv_usec)) { attente.tv_nsec = (1000000000 + attente.tv_nsec) - (1000 * duree_interruption.tv_usec); attente.tv_sec = attente.tv_sec - (duree_interruption.tv_sec + 1); } else { attente.tv_nsec = attente.tv_nsec - (1000 * duree_interruption.tv_usec); attente.tv_sec = attente.tv_sec - duree_interruption.tv_sec; } if (attente.tv_sec < 0) { code_retour = 0; } } } while(((code_retour == -1) && (erreur == EINTR)) && ((*s_etat_processus).var_volatile_requete_arret == 0)); if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } } else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet_argument); return; } /* ================================================================================ Fonction 'atexit' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_atexit(struct_processus *s_etat_processus) { struct_objet *s_objet_argument; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n ATEXIT "); if ((*s_etat_processus).langue == 'F') { printf("(exécution d'une fonction à la sortie d'une tâche)\n\n"); } else { printf("(register a function to be called on task exit)\n\n"); } printf(" 1: %s, %s\n", d_NOM, d_RPN); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = 1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet_argument).type == NOM) { liberation(s_etat_processus, (*s_etat_processus).at_exit); (*s_etat_processus).at_exit = s_objet_argument; } else if ((*s_objet_argument).type == RPN) { liberation(s_etat_processus, (*s_etat_processus).at_exit); (*s_etat_processus).at_exit = s_objet_argument; } else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } return; } /* ================================================================================ Fonction 'atpoke' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_atpoke(struct_processus *s_etat_processus) { struct_objet *s_objet_argument; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n ATPOKE "); if ((*s_etat_processus).langue == 'F') { printf("(exécution d'une fonction lors de l'injection " "d'une donnée)\n\n"); } else { printf("(register a function to be called on data injection)\n\n"); } printf(" 1: %s, %s\n", d_NOM, d_RPN); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = 1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet_argument).type == NOM) { liberation(s_etat_processus, (*s_etat_processus).at_poke); (*s_etat_processus).at_poke = s_objet_argument; } else if ((*s_objet_argument).type == RPN) { liberation(s_etat_processus, (*s_etat_processus).at_poke); (*s_etat_processus).at_poke = s_objet_argument; } else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } return; } // vim: ts=4