1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.10
4: Copyright (C) 1989-2012 Dr. BERTRAND Joël
5:
6: This file is part of RPL/2.
7:
8: RPL/2 is free software; you can redistribute it and/or modify it
9: under the terms of the CeCILL V2 License as published by the french
10: CEA, CNRS and INRIA.
11:
12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
15: for more details.
16:
17: You should have received a copy of the CeCILL License
18: along with RPL/2. If not, write to info@cecill.info.
19: ================================================================================
20: */
21:
22:
23: #include "rpl-conv.h"
24:
25:
26: /*
27: ================================================================================
28: Fonction 'poll'
29: ================================================================================
30: Entrées : pointeur sur une structure struct_processus
31: --------------------------------------------------------------------------------
32: Sorties :
33: --------------------------------------------------------------------------------
34: Effets de bord : néant
35: ================================================================================
36: */
37:
38: void
39: instruction_poll(struct_processus *s_etat_processus)
40: {
41: int erreur;
42: int i;
43: int ios;
44: int nombre_descripteurs;
45: int timeout;
46:
47: logical1 drapeau;
48:
49: short masque;
50:
51: struct_liste_chainee *l_element_courant;
52: struct_liste_chainee *l_element_courant_2;
53:
54: struct_objet *s_objet_argument_1;
55: struct_objet *s_objet_argument_2;
56: struct_objet *s_objet_liste;
57: struct_objet *s_objet_resultat;
58: struct_objet **s_objet_tmp;
59:
60: struct pollfd *s_poll;
61:
62: unsigned char *registre;
63:
64: if ((*s_etat_processus).affichage_arguments == 'Y')
65: {
66: printf("\n POLL ");
67:
68: if ((*s_etat_processus).langue == 'F')
69: {
70: printf("(attente d'un événement sur une liste de fichiers ou "
71: "de sockets)\n\n");
72: }
73: else
74: {
75: printf("(wait for event on files or sockets list)\n\n");
76: }
77:
78: printf(" 2: %s\n", d_LST);
79: printf(" 1: %s, %s\n", d_INT, d_REL);
80: printf("-> 1: %s\n\n", d_LST);
81:
82: if ((*s_etat_processus).langue == 'F')
83: {
84: printf(" Utilisation :\n\n");
85: }
86: else
87: {
88: printf(" Usage:\n\n");
89: }
90:
91: printf(" { { FILE_1 \"POLLIN\" \"POLLOUT\" }\n"
92: " { FILE_2 \"POLLPRI\" } } TIMEOUT POLL\n");
93: printf(" Input : POLLIN/POLLPRI/POLLOUT\n");
94: printf(" Output : POLLIN/POLLPRI/POLLOUT/POLLERR/POLLHUP/POLLNVAL"
95: "\n\n");
96:
97: return;
98: }
99: else if ((*s_etat_processus).test_instruction == 'Y')
100: {
101: (*s_etat_processus).nombre_arguments = -1;
102: return;
103: }
104:
105: if (test_cfsf(s_etat_processus, 31) == d_vrai)
106: {
107: if (empilement_pile_last(s_etat_processus, 3) == d_erreur)
108: {
109: return;
110: }
111: }
112:
113: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
114: &s_objet_argument_1) == d_erreur)
115: {
116: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
117: return;
118: }
119:
120: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
121: &s_objet_argument_2) == d_erreur)
122: {
123: liberation(s_etat_processus, s_objet_argument_1);
124:
125: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
126: return;
127: }
128:
129: if (((*s_objet_argument_2).type == LST) && (((*s_objet_argument_1).type ==
130: INT) || ((*s_objet_argument_1).type == REL)))
131: {
132: l_element_courant = (*s_objet_argument_2).objet;
133: nombre_descripteurs = 0;
134:
135: while(l_element_courant != NULL)
136: {
137: nombre_descripteurs++;
138: l_element_courant = (*l_element_courant).suivant;
139: }
140:
141: if ((s_poll = malloc(nombre_descripteurs * sizeof(struct pollfd)))
142: == NULL)
143: {
144: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
145: return;
146: }
147:
148: if ((s_objet_tmp = malloc(nombre_descripteurs *
149: sizeof(struct_objet *))) == NULL)
150: {
151: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
152: return;
153: }
154:
155: l_element_courant = (*s_objet_argument_2).objet;
156: i = 0;
157:
158: while(l_element_courant != NULL)
159: {
160: if ((*(*l_element_courant).donnee).type != LST)
161: {
162: liberation(s_etat_processus, s_objet_argument_1);
163: liberation(s_etat_processus, s_objet_argument_2);
164: free(s_poll);
165: free(s_objet_tmp);
166:
167: (*s_etat_processus).erreur_execution =
168: d_ex_erreur_type_argument;
169: return;
170: }
171:
172: l_element_courant_2 = (*(*l_element_courant).donnee).objet;
173: s_poll[i].events = 0;
174: s_poll[i].revents = 0;
175: drapeau = d_faux;
176:
177: while(l_element_courant_2 != NULL)
178: {
179: switch((*(*l_element_courant_2).donnee).type)
180: {
181: case SCK:
182: {
183: if (drapeau == d_vrai)
184: {
185: liberation(s_etat_processus, s_objet_argument_1);
186: liberation(s_etat_processus, s_objet_argument_2);
187: free(s_poll);
188: free(s_objet_tmp);
189:
190: (*s_etat_processus).erreur_execution =
191: d_ex_argument_invalide;
192: return;
193: }
194:
195: s_poll[i].fd = (*((struct_socket *)
196: (*(*l_element_courant_2).donnee).objet)).socket;
197: s_objet_tmp[i] = (*l_element_courant_2).donnee;
198: drapeau = d_vrai;
199: break;
200: }
201:
202: case FCH:
203: {
204: if (drapeau == d_vrai)
205: {
206: liberation(s_etat_processus, s_objet_argument_1);
207: liberation(s_etat_processus, s_objet_argument_2);
208: free(s_poll);
209: free(s_objet_tmp);
210:
211: (*s_etat_processus).erreur_execution =
212: d_ex_argument_invalide;
213: return;
214: }
215:
216: s_poll[i].fd = (*((struct_fichier *)
217: (*(*l_element_courant_2).donnee).objet))
218: .descripteur;
219: s_objet_tmp[i] = (*l_element_courant_2).donnee;
220: drapeau = d_vrai;
221: break;
222: }
223:
224: case CHN:
225: {
226: if ((registre = conversion_majuscule((unsigned char *)
227: (*(*l_element_courant_2).donnee).objet))
228: == NULL)
229: {
230: (*s_etat_processus).erreur_systeme =
231: d_es_allocation_memoire;
232: return;
233: }
234:
235: if (strcmp(registre, "POLLIN") == 0)
236: {
237: s_poll[i].events |= POLLIN;
238: }
239: else if (strcmp(registre, "POLLOUT") == 0)
240: {
241: s_poll[i].events |= POLLOUT;
242: }
243: else if (strcmp(registre, "POLLERR") == 0)
244: {
245: s_poll[i].events |= POLLERR;
246: }
247: else
248: {
249: liberation(s_etat_processus, s_objet_argument_1);
250: liberation(s_etat_processus, s_objet_argument_2);
251: free(registre);
252: free(s_poll);
253: free(s_objet_tmp);
254:
255: (*s_etat_processus).erreur_execution =
256: d_ex_erreur_parametre_fichier;
257: return;
258: }
259:
260: free(registre);
261: break;
262: }
263:
264: default:
265: {
266: liberation(s_etat_processus, s_objet_argument_1);
267: liberation(s_etat_processus, s_objet_argument_2);
268: free(s_poll);
269: free(s_objet_tmp);
270:
271: (*s_etat_processus).erreur_execution =
272: d_ex_erreur_type_argument;
273: return;
274: }
275: }
276:
277: l_element_courant_2 = (*l_element_courant_2).suivant;
278: }
279:
280: if (drapeau == d_faux)
281: {
282: liberation(s_etat_processus, s_objet_argument_1);
283: liberation(s_etat_processus, s_objet_argument_2);
284: free(s_poll);
285: free(s_objet_tmp);
286:
287: (*s_etat_processus).erreur_execution =
288: d_ex_erreur_type_argument;
289: return;
290: }
291:
292: l_element_courant = (*l_element_courant).suivant;
293: i++;
294: }
295:
296: if ((*s_objet_argument_1).type == INT)
297: {
298: timeout = (*((integer8 *) (*s_objet_argument_1).objet)) * 1000L;
299: }
300: else
301: {
302: timeout = (int) ((*((real8 *) (*s_objet_argument_1).objet))
303: * 1000L);
304: }
305:
306: do
307: {
308: drapeau = d_vrai;
309:
310: # ifndef SEMAPHORES_NOMMES
311: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
312: # else
313: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
314: # endif
315: {
316: (*s_etat_processus).erreur_systeme = d_es_processus;
317: return;
318: }
319:
320: if ((ios = poll(s_poll, nombre_descripteurs, timeout)) < 0)
321: {
322: erreur = errno;
323:
324: # ifndef SEMAPHORES_NOMMES
325: while(sem_wait(&((*s_etat_processus)
326: .semaphore_fork)) != 0)
327: # else
328: while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
329: # endif
330:
331: if (erreur != EINTR)
332: {
333: liberation(s_etat_processus, s_objet_argument_1);
334: liberation(s_etat_processus, s_objet_argument_2);
335: free(s_poll);
336: free(s_objet_tmp);
337:
338: (*s_etat_processus).erreur_execution =
339: d_ex_erreur_acces_fichier;
340: return;
341: }
342:
343: scrutation_injection(s_etat_processus);
344:
345: if ((*s_etat_processus).var_volatile_requete_arret != 0)
346: {
347: drapeau = d_vrai;
348: }
349: else
350: {
351: drapeau = d_faux;
352: }
353: }
354: else
355: {
356: # ifndef SEMAPHORES_NOMMES
357: while(sem_wait(&((*s_etat_processus)
358: .semaphore_fork)) != 0)
359: # else
360: while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
361: # endif
362: {
363: if (errno != EINTR)
364: {
365: (*s_etat_processus).erreur_systeme =
366: d_es_processus;
367: return;
368: }
369: }
370: }
371: } while(drapeau == d_faux);
372:
373: if ((s_objet_resultat = allocation(s_etat_processus, LST)) == NULL)
374: {
375: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
376: return;
377: }
378:
379: if (ios > 0)
380: {
381: // Sortie sur un événement
382:
383: masque = POLLIN | POLLPRI | POLLOUT | POLLERR | POLLHUP | POLLNVAL;
384:
385: for(i = nombre_descripteurs - 1; i >= 0; i--)
386: {
387: if ((s_poll[i].revents & masque) != 0)
388: {
389: if ((s_objet_liste = allocation(s_etat_processus, LST))
390: == NULL)
391: {
392: (*s_etat_processus).erreur_systeme =
393: d_es_allocation_memoire;
394: return;
395: }
396:
397: if ((s_poll[i].revents & POLLNVAL) != 0)
398: {
399: l_element_courant = (*s_objet_liste).objet;
400:
401: if (((*s_objet_liste).objet = allocation_maillon(
402: s_etat_processus)) == NULL)
403: {
404: (*s_etat_processus).erreur_systeme =
405: d_es_allocation_memoire;
406: return;
407: }
408:
409: if (((*((struct_liste_chainee *) (*s_objet_liste)
410: .objet)).donnee = allocation(s_etat_processus,
411: CHN)) == NULL)
412: {
413: (*s_etat_processus).erreur_systeme =
414: d_es_allocation_memoire;
415: return;
416: }
417:
418: if (((*(*((struct_liste_chainee *) (*s_objet_liste)
419: .objet)).donnee).objet = malloc(9 *
420: sizeof(unsigned char))) == NULL)
421: {
422: (*s_etat_processus).erreur_systeme =
423: d_es_allocation_memoire;
424: return;
425: }
426:
427: strcpy((unsigned char *) (*(*((struct_liste_chainee *)
428: (*s_objet_liste).objet)).donnee).objet,
429: "POLLNVAL");
430: (*((struct_liste_chainee *) (*s_objet_liste).objet))
431: .suivant = l_element_courant;
432: }
433: else if ((s_poll[i].revents & POLLHUP) != 0)
434: {
435: l_element_courant = (*s_objet_liste).objet;
436:
437: if (((*s_objet_liste).objet = allocation_maillon(
438: s_etat_processus)) == NULL)
439: {
440: (*s_etat_processus).erreur_systeme =
441: d_es_allocation_memoire;
442: return;
443: }
444:
445: if (((*((struct_liste_chainee *) (*s_objet_liste)
446: .objet)).donnee = allocation(s_etat_processus,
447: CHN)) == NULL)
448: {
449: (*s_etat_processus).erreur_systeme =
450: d_es_allocation_memoire;
451: return;
452: }
453:
454: if (((*(*((struct_liste_chainee *) (*s_objet_liste)
455: .objet)).donnee).objet = malloc(8 *
456: sizeof(unsigned char))) == NULL)
457: {
458: (*s_etat_processus).erreur_systeme =
459: d_es_allocation_memoire;
460: return;
461: }
462:
463: strcpy((unsigned char *) (*(*((struct_liste_chainee *)
464: (*s_objet_liste).objet)).donnee).objet,
465: "POLLHUP");
466: (*((struct_liste_chainee *) (*s_objet_liste).objet))
467: .suivant = l_element_courant;
468: }
469: else if ((s_poll[i].revents & POLLERR) != 0)
470: {
471: l_element_courant = (*s_objet_liste).objet;
472:
473: if (((*s_objet_liste).objet = allocation_maillon(
474: s_etat_processus)) == NULL)
475: {
476: (*s_etat_processus).erreur_systeme =
477: d_es_allocation_memoire;
478: return;
479: }
480:
481: if (((*((struct_liste_chainee *) (*s_objet_liste)
482: .objet)).donnee = allocation(s_etat_processus,
483: CHN)) == NULL)
484: {
485: (*s_etat_processus).erreur_systeme =
486: d_es_allocation_memoire;
487: return;
488: }
489:
490: if (((*(*((struct_liste_chainee *) (*s_objet_liste)
491: .objet)).donnee).objet = malloc(8 *
492: sizeof(unsigned char))) == NULL)
493: {
494: (*s_etat_processus).erreur_systeme =
495: d_es_allocation_memoire;
496: return;
497: }
498:
499: strcpy((unsigned char *) (*(*((struct_liste_chainee *)
500: (*s_objet_liste).objet)).donnee).objet,
501: "POLLERR");
502: (*((struct_liste_chainee *) (*s_objet_liste).objet))
503: .suivant = l_element_courant;
504: }
505: else if ((s_poll[i].revents & POLLOUT) != 0)
506: {
507: l_element_courant = (*s_objet_liste).objet;
508:
509: if (((*s_objet_liste).objet = allocation_maillon(
510: s_etat_processus)) == NULL)
511: {
512: (*s_etat_processus).erreur_systeme =
513: d_es_allocation_memoire;
514: return;
515: }
516:
517: if (((*((struct_liste_chainee *) (*s_objet_liste)
518: .objet)).donnee = allocation(s_etat_processus,
519: CHN)) == NULL)
520: {
521: (*s_etat_processus).erreur_systeme =
522: d_es_allocation_memoire;
523: return;
524: }
525:
526: if (((*(*((struct_liste_chainee *) (*s_objet_liste)
527: .objet)).donnee).objet = malloc(8 *
528: sizeof(unsigned char))) == NULL)
529: {
530: (*s_etat_processus).erreur_systeme =
531: d_es_allocation_memoire;
532: return;
533: }
534:
535: strcpy((unsigned char *) (*(*((struct_liste_chainee *)
536: (*s_objet_liste).objet)).donnee).objet,
537: "POLLOUT");
538: (*((struct_liste_chainee *) (*s_objet_liste).objet))
539: .suivant = l_element_courant;
540: }
541: else if ((s_poll[i].revents & POLLPRI) != 0)
542: {
543: l_element_courant = (*s_objet_liste).objet;
544:
545: if (((*s_objet_liste).objet = allocation_maillon(
546: s_etat_processus)) == NULL)
547: {
548: (*s_etat_processus).erreur_systeme =
549: d_es_allocation_memoire;
550: return;
551: }
552:
553: if (((*((struct_liste_chainee *) (*s_objet_liste)
554: .objet)).donnee = allocation(s_etat_processus,
555: CHN)) == NULL)
556: {
557: (*s_etat_processus).erreur_systeme =
558: d_es_allocation_memoire;
559: return;
560: }
561:
562: if (((*(*((struct_liste_chainee *) (*s_objet_liste)
563: .objet)).donnee).objet = malloc(8 *
564: sizeof(unsigned char))) == NULL)
565: {
566: (*s_etat_processus).erreur_systeme =
567: d_es_allocation_memoire;
568: return;
569: }
570:
571: strcpy((unsigned char *) (*(*((struct_liste_chainee *)
572: (*s_objet_liste).objet)).donnee).objet,
573: "POLLPRI");
574: (*((struct_liste_chainee *) (*s_objet_liste).objet))
575: .suivant = l_element_courant;
576: }
577: else if ((s_poll[i].revents & POLLIN) != 0)
578: {
579: l_element_courant = (*s_objet_liste).objet;
580:
581: if (((*s_objet_liste).objet = allocation_maillon(
582: s_etat_processus)) == NULL)
583: {
584: (*s_etat_processus).erreur_systeme =
585: d_es_allocation_memoire;
586: return;
587: }
588:
589: if (((*((struct_liste_chainee *) (*s_objet_liste)
590: .objet)).donnee = allocation(s_etat_processus,
591: CHN)) == NULL)
592: {
593: (*s_etat_processus).erreur_systeme =
594: d_es_allocation_memoire;
595: return;
596: }
597:
598: if (((*(*((struct_liste_chainee *) (*s_objet_liste)
599: .objet)).donnee).objet = malloc(7 *
600: sizeof(unsigned char))) == NULL)
601: {
602: (*s_etat_processus).erreur_systeme =
603: d_es_allocation_memoire;
604: return;
605: }
606:
607: strcpy((unsigned char *) (*(*((struct_liste_chainee *)
608: (*s_objet_liste).objet)).donnee).objet,
609: "POLLIN");
610: (*((struct_liste_chainee *) (*s_objet_liste).objet))
611: .suivant = l_element_courant;
612: }
613:
614: l_element_courant = (*s_objet_liste).objet;
615:
616: if (((*s_objet_liste).objet = allocation_maillon(
617: s_etat_processus)) == NULL)
618: {
619: (*s_etat_processus).erreur_systeme =
620: d_es_allocation_memoire;
621: return;
622: }
623:
624: if (((*((struct_liste_chainee *) (*s_objet_liste)
625: .objet)).donnee = copie_objet(s_etat_processus,
626: s_objet_tmp[i], 'P')) == NULL)
627: {
628: (*s_etat_processus).erreur_systeme =
629: d_es_allocation_memoire;
630: return;
631: }
632:
633: (*((struct_liste_chainee *) (*s_objet_liste).objet))
634: .suivant = l_element_courant;
635:
636: // Ajout de la liste fille au résultat.
637:
638: l_element_courant = (*s_objet_resultat).objet;
639:
640: if (((*s_objet_resultat).objet = allocation_maillon(
641: s_etat_processus)) == NULL)
642: {
643: (*s_etat_processus).erreur_systeme =
644: d_es_allocation_memoire;
645: return;
646: }
647:
648: (*((struct_liste_chainee *) (*s_objet_resultat).objet))
649: .donnee = s_objet_liste;
650: (*((struct_liste_chainee *) (*s_objet_resultat).objet))
651: .suivant = l_element_courant;
652: }
653: }
654: }
655: else
656: {
657: // Sortie sur timeout : on renvoit une liste vide.
658: (*s_objet_resultat).objet = NULL;
659: }
660:
661: liberation(s_etat_processus, s_objet_argument_1);
662: liberation(s_etat_processus, s_objet_argument_2);
663: free(s_poll);
664: free(s_objet_tmp);
665:
666: if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
667: s_objet_resultat) == d_erreur)
668: {
669: return;
670: }
671: }
672: else
673: {
674: liberation(s_etat_processus, s_objet_argument_1);
675: liberation(s_etat_processus, s_objet_argument_2);
676:
677: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
678: return;
679: }
680:
681: return;
682: }
683:
684: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>