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 'alarm'
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_alarm(struct_processus *s_etat_processus)
40: {
41: double duree;
42:
43: int code_retour;
44: int erreur;
45:
46: integer8 nombre_elements;
47:
48: logical1 specification_date;
49:
50: struct_liste_chainee *l_element_courant;
51:
52: struct_objet *s_objet_argument;
53:
54: struct timespec attente;
55:
56: struct timeval debut_interruption;
57: struct timeval duree_interruption;
58: struct timeval fin_interruption;
59:
60: struct tm *s_time_actuel;
61: struct tm s_time_alarme;
62: struct tm s_time_registre;
63:
64: time_t alarme;
65: time_t st;
66:
67: (*s_etat_processus).erreur_execution = d_ex;
68:
69: if ((*s_etat_processus).affichage_arguments == 'Y')
70: {
71: printf("\n ALARM ");
72:
73: if ((*s_etat_processus).langue == 'F')
74: {
75: printf("(suspension du processus jusqu'à un instant spécifié)\n\n");
76: }
77: else
78: {
79: printf("(wait until timestamp)\n\n");
80: }
81:
82: printf(" 1: %s\n\n", d_LST);
83:
84: if ((*s_etat_processus).langue == 'F')
85: {
86: printf(" Utilisation :\n\n");
87: }
88: else
89: {
90: printf(" Usage:\n\n");
91: }
92:
93: printf(" { hours minutes } ALARM\n");
94: printf(" { hours minutes seconds } ALARM\n");
95: printf(" { hours minutes seconds day } ALARM\n");
96: printf(" { hours minutes seconds day month } ALARM\n");
97: printf(" { hours minutes seconds day month year } ALARM\n");
98:
99: return;
100: }
101: else if ((*s_etat_processus).test_instruction == 'Y')
102: {
103: (*s_etat_processus).nombre_arguments = 1;
104: return;
105: }
106:
107: if (test_cfsf(s_etat_processus, 31) == d_vrai)
108: {
109: if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
110: {
111: return;
112: }
113: }
114:
115: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
116: &s_objet_argument) == d_erreur)
117: {
118: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
119: return;
120: }
121:
122: if ((*s_objet_argument).type == LST)
123: {
124: l_element_courant = (*s_objet_argument).objet;
125: nombre_elements = 0;
126:
127: while(l_element_courant != NULL)
128: {
129: if ((*(*l_element_courant).donnee).type != INT)
130: {
131: (*s_etat_processus).erreur_execution =
132: d_ex_erreur_type_argument;
133:
134: liberation(s_etat_processus, s_objet_argument);
135: return;
136: }
137:
138: l_element_courant = (*l_element_courant).suivant;
139: nombre_elements++;
140: }
141:
142: if ((nombre_elements < 2) || (nombre_elements > 6))
143: {
144: (*s_etat_processus).erreur_execution =
145: d_ex_argument_invalide;
146:
147: liberation(s_etat_processus, s_objet_argument);
148: return;
149: }
150:
151: st = time(NULL);
152: s_time_actuel = localtime(&st);
153:
154: l_element_courant = (*s_objet_argument).objet;
155: s_time_alarme.tm_hour = (int) (*((integer8 *) (*(*l_element_courant)
156: .donnee).objet));
157: l_element_courant = (*l_element_courant).suivant;
158: s_time_alarme.tm_min = (int) (*((integer8 *) (*(*l_element_courant)
159: .donnee).objet));
160: l_element_courant = (*l_element_courant).suivant;
161:
162: specification_date = d_faux;
163:
164: if (l_element_courant != NULL)
165: {
166: s_time_alarme.tm_sec = (int) (*((integer8 *) (*(*l_element_courant)
167: .donnee).objet));
168: l_element_courant = (*l_element_courant).suivant;
169:
170: if (l_element_courant != NULL)
171: {
172: specification_date = d_vrai;
173:
174: s_time_alarme.tm_mday = (int) (*((integer8 *)
175: (*(*l_element_courant).donnee).objet));
176: l_element_courant = (*l_element_courant).suivant;
177:
178: if (l_element_courant != NULL)
179: {
180: s_time_alarme.tm_mon = (int) ((*((integer8 *)
181: (*(*l_element_courant).donnee).objet)) - 1);
182: l_element_courant = (*l_element_courant).suivant;
183:
184: if (l_element_courant != NULL)
185: {
186: s_time_alarme.tm_year = (int) ((*((integer8 *)
187: (*(*l_element_courant).donnee).objet))
188: - 1900);
189: l_element_courant = (*l_element_courant).suivant;
190: }
191: else
192: {
193: s_time_alarme.tm_year = (*s_time_actuel).tm_year;
194: }
195: }
196: else
197: {
198: s_time_alarme.tm_mon = (*s_time_actuel).tm_mon;
199: s_time_alarme.tm_year = (*s_time_actuel).tm_year;
200: }
201: }
202: else
203: {
204: s_time_alarme.tm_mday = (*s_time_actuel).tm_mday;
205: s_time_alarme.tm_mon = (*s_time_actuel).tm_mon;
206: s_time_alarme.tm_year = (*s_time_actuel).tm_year;
207: }
208: }
209: else
210: {
211: s_time_alarme.tm_sec = 0;
212: s_time_alarme.tm_mday = (*s_time_actuel).tm_mday;
213: s_time_alarme.tm_mon = (*s_time_actuel).tm_mon;
214: s_time_alarme.tm_year = (*s_time_actuel).tm_year;
215: }
216:
217: s_time_alarme.tm_isdst = -1;
218: s_time_registre = s_time_alarme;
219: alarme = mktime(&s_time_alarme);
220:
221: if ((s_time_alarme.tm_sec != s_time_registre.tm_sec) ||
222: (s_time_alarme.tm_min != s_time_registre.tm_min) ||
223: (s_time_alarme.tm_hour != s_time_registre.tm_hour) ||
224: (s_time_alarme.tm_mday != s_time_registre.tm_mday) ||
225: (s_time_alarme.tm_mon != s_time_registre.tm_mon) ||
226: (s_time_alarme.tm_year != s_time_registre.tm_year))
227: {
228: (*s_etat_processus).erreur_execution =
229: d_ex_argument_invalide;
230:
231: liberation(s_etat_processus, s_objet_argument);
232: return;
233: }
234:
235: while((duree = difftime(alarme, st)) < 0)
236: {
237: if (specification_date == d_vrai)
238: {
239: (*s_etat_processus).erreur_execution =
240: d_ex_argument_invalide;
241:
242: liberation(s_etat_processus, s_objet_argument);
243: return;
244: }
245:
246: s_time_alarme.tm_mday++;
247: alarme = mktime(&s_time_alarme);
248: }
249:
250: attente.tv_nsec = (long) ((duree - (double) (attente.tv_sec =
251: (time_t) floor(duree))) * 1000000000);
252:
253: if ((*s_etat_processus).profilage == d_vrai)
254: {
255: profilage(s_etat_processus, "Sleep function (ALARM)");
256:
257: if ((*s_etat_processus).erreur_systeme != d_es)
258: {
259: return;
260: }
261: }
262:
263: do
264: {
265: code_retour = nanosleep(&attente, &attente);
266: erreur = errno;
267:
268: if (code_retour == -1)
269: {
270: gettimeofday(&debut_interruption, NULL);
271:
272: scrutation_injection(s_etat_processus);
273:
274: if (pthread_mutex_lock(&((*s_etat_processus)
275: .mutex_interruptions)) != 0)
276: {
277: (*s_etat_processus).erreur_systeme = d_es_processus;
278: return;
279: }
280:
281: if ((*s_etat_processus).nombre_interruptions_non_affectees != 0)
282: {
283: affectation_interruptions_logicielles(s_etat_processus);
284: }
285:
286: if (pthread_mutex_unlock(&((*s_etat_processus)
287: .mutex_interruptions)) != 0)
288: {
289: (*s_etat_processus).erreur_systeme = d_es_processus;
290: return;
291: }
292:
293: if ((*s_etat_processus).nombre_interruptions_en_queue != 0)
294: {
295: traitement_interruptions_logicielles(s_etat_processus);
296: }
297:
298: gettimeofday(&fin_interruption, NULL);
299:
300: if (fin_interruption.tv_usec < debut_interruption.tv_usec)
301: {
302: duree_interruption.tv_usec = (1000000
303: + fin_interruption.tv_usec)
304: - debut_interruption.tv_usec;
305: duree_interruption.tv_sec = fin_interruption.tv_sec
306: - (debut_interruption.tv_sec + 1);
307: }
308: else
309: {
310: duree_interruption.tv_usec = fin_interruption.tv_usec
311: - debut_interruption.tv_usec;
312: duree_interruption.tv_sec = fin_interruption.tv_sec
313: - debut_interruption.tv_sec;
314: }
315:
316: if (attente.tv_nsec < (1000 * duree_interruption.tv_usec))
317: {
318: attente.tv_nsec = (1000000000 + attente.tv_nsec)
319: - (1000 * duree_interruption.tv_usec);
320: attente.tv_sec = attente.tv_sec
321: - (duree_interruption.tv_sec + 1);
322: }
323: else
324: {
325: attente.tv_nsec = attente.tv_nsec
326: - (1000 * duree_interruption.tv_usec);
327: attente.tv_sec = attente.tv_sec
328: - duree_interruption.tv_sec;
329: }
330:
331: if (attente.tv_sec < 0)
332: {
333: code_retour = 0;
334: }
335: }
336: } while(((code_retour == -1) && (erreur == EINTR))
337: && ((*s_etat_processus).var_volatile_requete_arret == 0));
338:
339: if ((*s_etat_processus).profilage == d_vrai)
340: {
341: profilage(s_etat_processus, NULL);
342: }
343: }
344: else
345: {
346: liberation(s_etat_processus, s_objet_argument);
347:
348: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
349: return;
350: }
351:
352: liberation(s_etat_processus, s_objet_argument);
353: return;
354: }
355:
356:
357: /*
358: ================================================================================
359: Fonction 'atexit'
360: ================================================================================
361: Entrées :
362: --------------------------------------------------------------------------------
363: Sorties :
364: --------------------------------------------------------------------------------
365: Effets de bord : néant
366: ================================================================================
367: */
368:
369: void
370: instruction_atexit(struct_processus *s_etat_processus)
371: {
372: struct_objet *s_objet_argument;
373:
374: (*s_etat_processus).erreur_execution = d_ex;
375:
376: if ((*s_etat_processus).affichage_arguments == 'Y')
377: {
378: printf("\n ATEXIT ");
379:
380: if ((*s_etat_processus).langue == 'F')
381: {
382: printf("(exécution d'une fonction à la sortie d'une tâche)\n\n");
383: }
384: else
385: {
386: printf("(register a function to be called on task exit)\n\n");
387: }
388:
389: printf(" 1: %s, %s\n", d_NOM, d_RPN);
390:
391: return;
392: }
393: else if ((*s_etat_processus).test_instruction == 'Y')
394: {
395: (*s_etat_processus).nombre_arguments = 1;
396: return;
397: }
398:
399: if (test_cfsf(s_etat_processus, 31) == d_vrai)
400: {
401: if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
402: {
403: return;
404: }
405: }
406:
407: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
408: &s_objet_argument) == d_erreur)
409: {
410: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
411: return;
412: }
413:
414: if ((*s_objet_argument).type == NOM)
415: {
416: liberation(s_etat_processus, (*s_etat_processus).at_exit);
417: (*s_etat_processus).at_exit = s_objet_argument;
418: }
419: else if ((*s_objet_argument).type == RPN)
420: {
421: liberation(s_etat_processus, (*s_etat_processus).at_exit);
422: (*s_etat_processus).at_exit = s_objet_argument;
423: }
424: else
425: {
426: liberation(s_etat_processus, s_objet_argument);
427:
428: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
429: return;
430: }
431:
432: return;
433: }
434:
435:
436: /*
437: ================================================================================
438: Fonction 'atpoke'
439: ================================================================================
440: Entrées :
441: --------------------------------------------------------------------------------
442: Sorties :
443: --------------------------------------------------------------------------------
444: Effets de bord : néant
445: ================================================================================
446: */
447:
448: void
449: instruction_atpoke(struct_processus *s_etat_processus)
450: {
451: struct_objet *s_objet_argument;
452:
453: (*s_etat_processus).erreur_execution = d_ex;
454:
455: if ((*s_etat_processus).affichage_arguments == 'Y')
456: {
457: printf("\n ATPOKE ");
458:
459: if ((*s_etat_processus).langue == 'F')
460: {
461: printf("(exécution d'une fonction lors de l'injection "
462: "d'une donnée)\n\n");
463: }
464: else
465: {
466: printf("(register a function to be called on data injection)\n\n");
467: }
468:
469: printf(" 1: %s, %s\n", d_NOM, d_RPN);
470:
471: return;
472: }
473: else if ((*s_etat_processus).test_instruction == 'Y')
474: {
475: (*s_etat_processus).nombre_arguments = 1;
476: return;
477: }
478:
479: if (test_cfsf(s_etat_processus, 31) == d_vrai)
480: {
481: if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
482: {
483: return;
484: }
485: }
486:
487: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
488: &s_objet_argument) == d_erreur)
489: {
490: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
491: return;
492: }
493:
494: if ((*s_objet_argument).type == NOM)
495: {
496: liberation(s_etat_processus, (*s_etat_processus).at_poke);
497: (*s_etat_processus).at_poke = s_objet_argument;
498: }
499: else if ((*s_objet_argument).type == RPN)
500: {
501: liberation(s_etat_processus, (*s_etat_processus).at_poke);
502: (*s_etat_processus).at_poke = s_objet_argument;
503: }
504: else
505: {
506: liberation(s_etat_processus, s_objet_argument);
507:
508: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
509: return;
510: }
511:
512: return;
513: }
514:
515: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>