--- rpl/src/instructions_p8.c 2012/04/13 14:12:58 1.8 +++ rpl/src/instructions_p8.c 2012/05/20 17:28:26 1.9 @@ -39,19 +39,25 @@ void instruction_poll(struct_processus *s_etat_processus) { int erreur; + int i; int ios; + int nombre_descripteurs; int 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_argument_3; + struct_objet *s_objet_liste; struct_objet *s_objet_resultat; + struct_objet **s_objet_tmp; - struct pollfd s_poll; + struct pollfd *s_poll; unsigned char *registre; @@ -61,13 +67,18 @@ instruction_poll(struct_processus *s_eta if ((*s_etat_processus).langue == 'F') { - printf("(attente d'un événement sur un fichier ou une socket)\n\n"); + printf("(attente d'un événement sur une liste de fichiers ou " + "de sockets)\n\n"); } else { - printf("(wait for event on file or socket)\n\n"); + 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"); @@ -77,11 +88,11 @@ instruction_poll(struct_processus *s_eta printf(" Usage:\n\n"); } - printf(" FILE { \"POLLIN\" \"POLLOUT\" } TIMEOUT POLL\n\n"); - printf(" 3: %s, %s\n", d_SCK, d_FCH); - printf(" 2: %s\n", d_LST); - printf(" 1: %s, %s\n", d_INT, d_REL); - printf("-> 1: %s\n", d_INT); + 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; } @@ -115,109 +126,182 @@ instruction_poll(struct_processus *s_eta return; } - if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), - &s_objet_argument_3) == d_erreur) + if (((*s_objet_argument_2).type == LST) && (((*s_objet_argument_1).type == + INT) || ((*s_objet_argument_1).type == REL))) { - liberation(s_etat_processus, s_objet_argument_1); - liberation(s_etat_processus, s_objet_argument_2); - - (*s_etat_processus).erreur_execution = d_ex_manque_argument; - return; - } + l_element_courant = (*s_objet_argument_2).objet; + nombre_descripteurs = 0; - if (((*s_objet_argument_3).type == SCK) || - ((*s_objet_argument_3).type == FCH)) - { - if ((*s_objet_argument_3).type == SCK) + while(l_element_courant != NULL) { - s_poll.fd = (*((struct_socket *) - (*s_objet_argument_3).objet)).socket; + nombre_descripteurs++; + l_element_courant = (*l_element_courant).suivant; } - else + + if ((s_poll = malloc(nombre_descripteurs * sizeof(struct pollfd))) + == NULL) { - s_poll.fd = (*((struct_fichier *) - (*s_objet_argument_3).objet)).descripteur; + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; } - if ((*s_objet_argument_2).type != LST) + if ((s_objet_tmp = malloc(nombre_descripteurs * + sizeof(struct_objet *))) == NULL) { - liberation(s_etat_processus, s_objet_argument_1); - liberation(s_etat_processus, s_objet_argument_2); - liberation(s_etat_processus, s_objet_argument_3); - - (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } l_element_courant = (*s_objet_argument_2).objet; - s_poll.events = 0; + i = 0; while(l_element_courant != NULL) { - if ((*(*l_element_courant).donnee).type != CHN) + if ((*(*l_element_courant).donnee).type != LST) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); - liberation(s_etat_processus, s_objet_argument_3); + free(s_poll); + free(s_objet_tmp); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } - if ((registre = conversion_majuscule((unsigned char *) - (*(*l_element_courant).donnee).objet)) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } + l_element_courant_2 = (*(*l_element_courant).donnee).objet; + s_poll[i].events = 0; + s_poll[i].revents = 0; + drapeau = d_faux; - if (strcmp(registre, "POLLIN") == 0) + while(l_element_courant_2 != NULL) { - s_poll.events |= POLLIN; - } - else if (strcmp(registre, "POLLOUT") == 0) - { - s_poll.events |= POLLOUT; + 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((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; } - else - { - free(registre); + if (drapeau == d_faux) + { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); - liberation(s_etat_processus, s_objet_argument_3); + free(s_poll); + free(s_objet_tmp); (*s_etat_processus).erreur_execution = - d_ex_erreur_parametre_fichier; + d_ex_erreur_type_argument; return; } - free(registre); l_element_courant = (*l_element_courant).suivant; + i++; } - s_poll.revents = 0; - if ((*s_objet_argument_1).type == INT) { timeout = (*((integer8 *) (*s_objet_argument_1).objet)) * 1000L; } - else if ((*s_objet_argument_1).type == REL) + else { timeout = (int) ((*((real8 *) (*s_objet_argument_1).objet)) * 1000L); } - else - { - liberation(s_etat_processus, s_objet_argument_1); - liberation(s_etat_processus, s_objet_argument_2); - liberation(s_etat_processus, s_objet_argument_3); - - (*s_etat_processus).erreur_execution = - d_ex_erreur_type_argument; - return; - } do { @@ -233,7 +317,7 @@ instruction_poll(struct_processus *s_eta return; } - if ((ios = poll(&s_poll, 1, timeout)) < 0) + if ((ios = poll(s_poll, nombre_descripteurs, timeout)) < 0) { erreur = errno; @@ -248,7 +332,8 @@ instruction_poll(struct_processus *s_eta { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); - liberation(s_etat_processus, s_objet_argument_3); + free(s_poll); + free(s_objet_tmp); (*s_etat_processus).erreur_execution = d_ex_erreur_acces_fichier; @@ -285,7 +370,7 @@ instruction_poll(struct_processus *s_eta } } while(drapeau == d_faux); - if ((s_objet_resultat = allocation(s_etat_processus, INT)) == NULL) + if ((s_objet_resultat = allocation(s_etat_processus, LST)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; @@ -294,17 +379,289 @@ instruction_poll(struct_processus *s_eta if (ios > 0) { // Sortie sur un événement - (*((integer8 *) (*s_objet_resultat).objet)) = -1; + + 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 - (*((integer8 *) (*s_objet_resultat).objet)) = 0; + // 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); - liberation(s_etat_processus, s_objet_argument_3); + free(s_poll); + free(s_objet_tmp); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) @@ -316,7 +673,6 @@ instruction_poll(struct_processus *s_eta { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); - liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return;