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