/* ================================================================================ RPL/2 (R) version 4.1.22 Copyright (C) 1989-2015 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 'poll' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_poll(struct_processus *s_etat_processus) { int erreur; int i; int ios; int nombre_descripteurs; integer8 timeout; logical1 drapeau; short masque; struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_courant_2; struct_objet *s_objet_argument_1; struct_objet *s_objet_argument_2; struct_objet *s_objet_liste; struct_objet *s_objet_resultat; struct_objet **s_objet_tmp; struct pollfd *s_poll; unsigned char *registre; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n POLL "); if ((*s_etat_processus).langue == 'F') { printf("(attente d'un événement sur une liste de fichiers ou " "de sockets)\n\n"); } else { printf("(wait for event on files or sockets list)\n\n"); } printf(" 2: %s\n", d_LST); printf(" 1: %s, %s\n", d_INT, d_REL); printf("-> 1: %s\n\n", d_LST); if ((*s_etat_processus).langue == 'F') { printf(" Utilisation :\n\n"); } else { printf(" Usage:\n\n"); } printf(" { { FILE_1 \"POLLIN\" \"POLLOUT\" }\n" " { FILE_2 \"POLLPRI\" } } TIMEOUT POLL\n"); printf(" Input : POLLIN/POLLPRI/POLLOUT\n"); printf(" Output : POLLIN/POLLPRI/POLLOUT/POLLERR/POLLHUP/POLLNVAL" "\n\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, 2) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_1) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_2) == d_erreur) { liberation(s_etat_processus, s_objet_argument_1); (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (((*s_objet_argument_2).type == LST) && (((*s_objet_argument_1).type == INT) || ((*s_objet_argument_1).type == REL))) { l_element_courant = (*s_objet_argument_2).objet; nombre_descripteurs = 0; while(l_element_courant != NULL) { nombre_descripteurs++; l_element_courant = (*l_element_courant).suivant; } if ((s_poll = malloc(((size_t) nombre_descripteurs) * sizeof(struct pollfd))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if ((s_objet_tmp = malloc(((size_t) nombre_descripteurs) * sizeof(struct_objet *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } l_element_courant = (*s_objet_argument_2).objet; i = 0; while(l_element_courant != NULL) { if ((*(*l_element_courant).donnee).type != LST) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); free(s_poll); free(s_objet_tmp); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } l_element_courant_2 = (*(*l_element_courant).donnee).objet; s_poll[i].events = 0; s_poll[i].revents = 0; drapeau = d_faux; while(l_element_courant_2 != NULL) { switch((*(*l_element_courant_2).donnee).type) { case SCK: { if (drapeau == d_vrai) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); free(s_poll); free(s_objet_tmp); (*s_etat_processus).erreur_execution = d_ex_argument_invalide; return; } s_poll[i].fd = (*((struct_socket *) (*(*l_element_courant_2).donnee).objet)).socket; s_objet_tmp[i] = (*l_element_courant_2).donnee; drapeau = d_vrai; break; } case FCH: { if (drapeau == d_vrai) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); free(s_poll); free(s_objet_tmp); (*s_etat_processus).erreur_execution = d_ex_argument_invalide; return; } s_poll[i].fd = (*((struct_fichier *) (*(*l_element_courant_2).donnee).objet)) .descripteur; s_objet_tmp[i] = (*l_element_courant_2).donnee; drapeau = d_vrai; break; } case CHN: { if ((registre = conversion_majuscule(s_etat_processus, (unsigned char *) (*(*l_element_courant_2) .donnee).objet)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (strcmp(registre, "POLLIN") == 0) { s_poll[i].events |= POLLIN; } else if (strcmp(registre, "POLLOUT") == 0) { s_poll[i].events |= POLLOUT; } else if (strcmp(registre, "POLLERR") == 0) { s_poll[i].events |= POLLERR; } else { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); free(registre); free(s_poll); free(s_objet_tmp); (*s_etat_processus).erreur_execution = d_ex_erreur_parametre_fichier; return; } free(registre); break; } default: { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); free(s_poll); free(s_objet_tmp); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } } l_element_courant_2 = (*l_element_courant_2).suivant; } if (drapeau == d_faux) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); free(s_poll); free(s_objet_tmp); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } l_element_courant = (*l_element_courant).suivant; i++; } if ((*s_objet_argument_1).type == INT) { timeout = (*((integer8 *) (*s_objet_argument_1).objet)) * 1000L; } else { timeout = (int) ((*((real8 *) (*s_objet_argument_1).objet)) * 1000L); } do { drapeau = d_vrai; # 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; } if ((ios = poll(s_poll, (nfds_t) nombre_descripteurs, (int) timeout)) < 0) { erreur = errno; # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus).semaphore_fork) != 0) # endif if (erreur != EINTR) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); free(s_poll); free(s_objet_tmp); (*s_etat_processus).erreur_execution = d_ex_erreur_acces_fichier; return; } scrutation_injection(s_etat_processus); if ((*s_etat_processus).var_volatile_requete_arret != 0) { drapeau = d_vrai; } else { drapeau = d_faux; } } else { # 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(drapeau == d_faux); if ((s_objet_resultat = allocation(s_etat_processus, LST)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (ios > 0) { // Sortie sur un événement masque = POLLIN | POLLPRI | POLLOUT | POLLERR | POLLHUP | POLLNVAL; for(i = nombre_descripteurs - 1; i >= 0; i--) { if ((s_poll[i].revents & masque) != 0) { if ((s_objet_liste = allocation(s_etat_processus, LST)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if ((s_poll[i].revents & POLLNVAL) != 0) { l_element_courant = (*s_objet_liste).objet; if (((*s_objet_liste).objet = allocation_maillon( s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee = allocation(s_etat_processus, CHN)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*(*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee).objet = malloc(9 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } strcpy((unsigned char *) (*(*((struct_liste_chainee *) (*s_objet_liste).objet)).donnee).objet, "POLLNVAL"); (*((struct_liste_chainee *) (*s_objet_liste).objet)) .suivant = l_element_courant; } else if ((s_poll[i].revents & POLLHUP) != 0) { l_element_courant = (*s_objet_liste).objet; if (((*s_objet_liste).objet = allocation_maillon( s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee = allocation(s_etat_processus, CHN)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*(*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee).objet = malloc(8 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } strcpy((unsigned char *) (*(*((struct_liste_chainee *) (*s_objet_liste).objet)).donnee).objet, "POLLHUP"); (*((struct_liste_chainee *) (*s_objet_liste).objet)) .suivant = l_element_courant; } else if ((s_poll[i].revents & POLLERR) != 0) { l_element_courant = (*s_objet_liste).objet; if (((*s_objet_liste).objet = allocation_maillon( s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee = allocation(s_etat_processus, CHN)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*(*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee).objet = malloc(8 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } strcpy((unsigned char *) (*(*((struct_liste_chainee *) (*s_objet_liste).objet)).donnee).objet, "POLLERR"); (*((struct_liste_chainee *) (*s_objet_liste).objet)) .suivant = l_element_courant; } else if ((s_poll[i].revents & POLLOUT) != 0) { l_element_courant = (*s_objet_liste).objet; if (((*s_objet_liste).objet = allocation_maillon( s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee = allocation(s_etat_processus, CHN)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*(*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee).objet = malloc(8 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } strcpy((unsigned char *) (*(*((struct_liste_chainee *) (*s_objet_liste).objet)).donnee).objet, "POLLOUT"); (*((struct_liste_chainee *) (*s_objet_liste).objet)) .suivant = l_element_courant; } else if ((s_poll[i].revents & POLLPRI) != 0) { l_element_courant = (*s_objet_liste).objet; if (((*s_objet_liste).objet = allocation_maillon( s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee = allocation(s_etat_processus, CHN)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*(*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee).objet = malloc(8 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } strcpy((unsigned char *) (*(*((struct_liste_chainee *) (*s_objet_liste).objet)).donnee).objet, "POLLPRI"); (*((struct_liste_chainee *) (*s_objet_liste).objet)) .suivant = l_element_courant; } else if ((s_poll[i].revents & POLLIN) != 0) { l_element_courant = (*s_objet_liste).objet; if (((*s_objet_liste).objet = allocation_maillon( s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee = allocation(s_etat_processus, CHN)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*(*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee).objet = malloc(7 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } strcpy((unsigned char *) (*(*((struct_liste_chainee *) (*s_objet_liste).objet)).donnee).objet, "POLLIN"); (*((struct_liste_chainee *) (*s_objet_liste).objet)) .suivant = l_element_courant; } l_element_courant = (*s_objet_liste).objet; if (((*s_objet_liste).objet = allocation_maillon( s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*((struct_liste_chainee *) (*s_objet_liste) .objet)).donnee = copie_objet(s_etat_processus, s_objet_tmp[i], 'P')) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*((struct_liste_chainee *) (*s_objet_liste).objet)) .suivant = l_element_courant; // Ajout de la liste fille au résultat. l_element_courant = (*s_objet_resultat).objet; 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_liste; (*((struct_liste_chainee *) (*s_objet_resultat).objet)) .suivant = l_element_courant; } } } else { // Sortie sur timeout : on renvoit une liste vide. (*s_objet_resultat).objet = NULL; } liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); free(s_poll); free(s_objet_tmp); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } } else { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } return; } // vim: ts=4