File:
[local] /
rpl /
src /
Attic /
siginfo.c
Revision
1.13:
download - view:
text,
annotated -
select for diffs -
revision graph
Tue Jun 21 15:26:35 2011 UTC (13 years, 10 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Correction d'une réinitialisation sauvage de la pile des variables par niveau
dans la copie de la structure de description du processus. Cela corrige
la fonction SPAWN qui échouait sur un segmentation fault car la pile des
variables par niveau était vide alors même que l'arbre des variables contenait
bien les variables. Passage à la prerelease 2.
1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.0.prerelease.2
4: Copyright (C) 1989-2011 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: #define __BROKEN_SIGINFO_ROUTINES__
24: #include "rpl-conv.h"
25:
26: #ifdef _BROKEN_SIGINFO
27:
28: #define longueur_queue 256
29: #define nombre_queues 13
30:
31: static int *fifos;
32: static int markov;
33: static sem_t *semaphores[nombre_queues];
34: static sem_t *semaphore_global;
35:
36: #ifdef IPCS_SYSV
37: #ifndef OS2
38: static unsigned char *chemin = NULL;
39: #endif
40: #endif
41:
42: #ifdef OS2
43: PVOID ptr_os2;
44: #else
45: static int segment;
46: #endif
47:
48: static unsigned char *
49: nom_segment(unsigned char *chemin, pid_t pid)
50: {
51: unsigned char *fichier;
52:
53: # ifdef IPCS_SYSV
54:
55: # ifndef OS2
56:
57: if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
58: sizeof(unsigned char))) == NULL)
59: {
60: return(NULL);
61: }
62:
63: sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
64:
65: # else
66:
67: if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char))) == NULL)
68: {
69: return(NULL);
70: }
71:
72: sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
73:
74: # endif
75: # else
76:
77: if ((fichier = malloc((1 + 256 + 1) *
78: sizeof(unsigned char))) == NULL)
79: {
80: return(NULL);
81: }
82:
83: sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
84:
85: # endif
86:
87: return(fichier);
88: }
89:
90: static unsigned char *
91: nom_semaphore(pid_t pid, int queue)
92: {
93: unsigned char *fichier;
94:
95: if ((fichier = malloc((256 + 1) * sizeof(unsigned char))) == NULL)
96: {
97: return(NULL);
98: }
99:
100: sprintf(fichier, "/RPL-SIGSEMAPHORES-%d-%d", (int) pid, queue);
101:
102: return(fichier);
103: }
104:
105: static inline int
106: queue_de_signal(int signal)
107: {
108: switch(signal)
109: {
110: case SIGINT:
111: return(0);
112: case SIGTSTP:
113: return(1);
114: case SIGCONT:
115: return(2);
116: case SIGURG:
117: return(3);
118: case SIGPIPE:
119: return(4);
120: case SIGALRM:
121: return(5);
122: case SIGFSTOP:
123: return(6);
124: case SIGSTART:
125: return(7);
126: case SIGINJECT:
127: return(8);
128: case SIGABORT:
129: return(9);
130: case SIGFABORT:
131: return(10);
132: case SIGSEGV:
133: return(11);
134: case SIGBUS:
135: return(12);
136: }
137:
138: return(-1);
139: }
140:
141: void
142: creation_fifos_signaux(struct_processus *s_etat_processus)
143: {
144: /*
145: * Signaux utilisés
146: * SIGINT, SIGTSTP, SIGCONT, SIGURG, SIGPIPE, SIGALRM, SIGFSTOP,
147: * SIGSTART, SIGINJECT, SIGABORT, SIGFABORT
148: */
149:
150: int i;
151:
152: unsigned char *nom;
153:
154: # ifndef IPCS_SYSV // POSIX
155:
156: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
157: getpid())) == NULL)
158: {
159: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
160: return;
161: }
162:
163: if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
164: S_IRUSR | S_IWUSR)) == -1)
165: {
166: free(nom);
167: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
168: return;
169: }
170:
171: if (ftruncate(segment, nombre_queues * ((2 * longueur_queue) + 4) *
172: sizeof(int)) == -1)
173: {
174: free(nom);
175: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
176: return;
177: }
178:
179: fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
180: PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);
181: close(segment);
182:
183: if (((void *) fifos) == ((void *) -1))
184: {
185: if (shm_unlink(nom) == -1)
186: {
187: free(nom);
188: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
189: return;
190: }
191:
192: free(nom);
193: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
194: return;
195: }
196:
197: free(nom);
198:
199: # else // SystemV
200: # ifndef OS2
201:
202: file *desc;
203:
204: key_t clef;
205:
206: // Création d'un segment de données associé au PID du processus courant
207:
208: chemin = (*s_etat_processus).chemin_fichiers_temporaires;
209:
210: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
211: getpid())) == NULL)
212: {
213: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
214: return;
215: }
216:
217: if ((desc = fopen(nom, "w")) == NULL)
218: {
219: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
220: return;
221: }
222:
223: fclose(desc);
224:
225: if ((clef = ftok(nom, 1)) == -1)
226: {
227: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
228: return;
229: }
230:
231: free(nom);
232:
233: if ((segment = shmget(clef,
234: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
235: IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
236: {
237: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
238: return;
239: }
240:
241: fifos = shmat(segment, NULL, 0);
242:
243: if (((void *) fifos) == ((void *) -1))
244: {
245: if (shmctl(segment, IPC_RMID, 0) == -1)
246: {
247: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
248: return;
249: }
250:
251: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
252: return;
253: }
254:
255: # else
256:
257: if ((nom = nom_segment(NULL, getpid())) == NULL)
258: {
259: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
260: return;
261: }
262:
263: if (DosAllocSharedMem(&ptr_os2, nom, nombre_queues *
264: ((2 * longueur_queue) + 4) * sizeof(int),
265: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
266: {
267: free(nom);
268: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
269: return;
270: }
271:
272: free(nom);
273: fifos = ptr_os2;
274:
275: # endif
276: # endif
277:
278: /*
279: * Structure d'une queue
280: * 0 : pointeur en lecture sur le premier emplacement libre (int)
281: * 1 : pointeur en écriture sur le premier emplacement à lire (int)
282: * 2 : longueur de la queue (int)
283: * 3 : éléments restants (int)
284: * 4 à 4 + (2) : queue (int)
285: * 4 + (2) + 1 ) 4 + 2 * (2) : horodatage en centième de secondes.
286: */
287:
288: for(i = 0; i < nombre_queues; i++)
289: {
290: fifos[(i * (longueur_queue + 4))] = 0;
291: fifos[(i * (longueur_queue + 4)) + 1] = 0;
292: fifos[(i * (longueur_queue + 4)) + 2] = longueur_queue;
293: fifos[(i * (longueur_queue + 4)) + 3] = longueur_queue;
294: }
295:
296: // Création des sémaphores : un sémaphore par signal et par queue
297: // plus un sémaphore global pour tous les threads.
298:
299: for(i = 0; i < nombre_queues; i++)
300: {
301: if ((nom = nom_semaphore(getpid(), i)) == NULL)
302: {
303: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
304: return;
305: }
306:
307: // Le sémaphore est créé en écrasant si nécessaire un sémaphore
308: // préexistant. Comme le nom du sémaphore contient l'identifiant du
309: // processus, il est anormal d'avoir un sémaphore de même nom
310: // préexistant.
311:
312: if ((semaphores[i] = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
313: 1)) == SEM_FAILED)
314: {
315: (*s_etat_processus).erreur_systeme = d_es_semaphore;
316: return;
317: }
318:
319: free(nom);
320: }
321:
322:
323: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
324: {
325: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
326: return;
327: }
328:
329: if ((semaphore_global = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
330: 1)) == SEM_FAILED)
331: {
332: (*s_etat_processus).erreur_systeme = d_es_semaphore;
333: return;
334: }
335:
336: free(nom);
337:
338: markov = 0;
339:
340: return;
341: }
342:
343: void
344: liberation_fifos_signaux(struct_processus *s_etat_processus)
345: {
346: int i;
347:
348: # ifdef IPCS_SYSV // SystemV
349: # ifndef OS2
350:
351: if (shmdt(fifos) == -1)
352: {
353: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
354: return;
355: }
356:
357: # else
358:
359: if (DosFreeMem(fifos) != 0)
360: {
361: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
362: return;
363: }
364:
365: # endif
366: # else // POSIX
367:
368: if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int))
369: != 0)
370: {
371: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
372: return;
373: }
374:
375: # endif
376:
377: for(i = 0; i < nombre_queues; i++)
378: {
379: if (sem_close(semaphores[i]) != 0)
380: {
381: (*s_etat_processus).erreur_systeme = d_es_semaphore;
382: return;
383: }
384: }
385:
386: if (sem_close(semaphore_global) != 0)
387: {
388: (*s_etat_processus).erreur_systeme = d_es_semaphore;
389: return;
390: }
391:
392: return;
393: }
394:
395: void
396: destruction_fifos_signaux(struct_processus *s_etat_processus)
397: {
398: int i;
399:
400: unsigned char *nom;
401:
402: # ifdef IPCS_SYSV // SystemV
403: # ifndef OS2
404:
405: if (shmdt(fifos) == -1)
406: {
407: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
408: return;
409: }
410:
411: if (shmctl(segment, IPC_RMID, 0) == -1)
412: {
413: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
414: return;
415: }
416:
417: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
418: getpid())) == NULL)
419: {
420: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
421: return;
422: }
423:
424: unlink(nom);
425: free(nom);
426:
427: # else
428:
429: if (DosFreeMem(fifos) != 0)
430: {
431: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
432: return;
433: }
434:
435: # endif
436: # else // POSIX
437:
438: if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int))
439: != 0)
440: {
441: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
442: return;
443: }
444:
445: if ((nom = nom_segment(NULL, getpid())) == NULL)
446: {
447: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
448: return;
449: }
450:
451: if (shm_unlink(nom) != 0)
452: {
453: free(nom);
454: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
455: return;
456: }
457:
458: free(nom);
459:
460: # endif
461:
462: for(i = 0; i < nombre_queues; i++)
463: {
464: if ((nom = nom_semaphore(getpid(), i)) == NULL)
465: {
466: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
467: return;
468: }
469:
470: if (sem_unlink(nom) != 0)
471: {
472: (*s_etat_processus).erreur_systeme = d_es_semaphore;
473: return;
474: }
475:
476: free(nom);
477: }
478:
479: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
480: {
481: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
482: return;
483: }
484:
485: if (sem_unlink(nom) != 0)
486: {
487: (*s_etat_processus).erreur_systeme = d_es_semaphore;
488: return;
489: }
490:
491: free(nom);
492:
493: return;
494: }
495:
496: static inline int
497: horodatage()
498: {
499: int ts;
500:
501: struct timeval tv;
502:
503: gettimeofday(&tv, NULL);
504: ts = (int) ((tv.tv_sec * 100) + (tv.tv_usec / 10000));
505:
506: return(ts);
507: }
508:
509: int
510: queue_in(pid_t pid, int signal)
511: {
512: int queue;
513: int *base;
514: int *buffer;
515: int horodatage_initial;
516: # ifndef OS2
517: int identifiant;
518: # endif
519: int *projection_fifos;
520:
521: sem_t *semaphore;
522:
523: queue = queue_de_signal(signal);
524:
525: unsigned char *nom;
526:
527: # ifndef IPCS_SYSV
528:
529: // Ouverture des projections
530:
531: if ((nom = nom_segment(NULL, pid)) == NULL)
532: {
533: return(-1);
534: }
535:
536: // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
537: // il convient d'attendre que le fichier support soit effectivement
538: // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
539: // n'existe plus, le processus associé n'existe plus.
540:
541: if (signal == SIGSTART)
542: {
543: horodatage_initial = horodatage();
544:
545: while((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1)
546: {
547: if (abs(horodatage_initial - horodatage()) > 500)
548: {
549: return(-1);
550: }
551: }
552: }
553: else
554: {
555: if ((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1)
556: {
557: return(-1);
558: }
559: }
560:
561: projection_fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4)
562: * sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, identifiant, 0);
563: close(identifiant);
564:
565: if (((void *) projection_fifos) == ((void *) -1))
566: {
567: return(-1);
568: }
569:
570: # else // Traitement à l'aide d'IPCS SystemV
571:
572: # ifndef OS2
573: key_t clef;
574:
575: struct stat s_stat;
576: # endif
577:
578: // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
579: // il convient d'attendre que le fichier support soit effectivement
580: // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
581: // n'existe plus, le processus associé n'existe plus.
582:
583: # ifndef OS2
584:
585: // Ouverture des projections
586:
587: if ((nom = nom_segment(chemin, pid)) == NULL)
588: {
589: return(-1);
590: }
591:
592: if (signal == SIGSTART)
593: {
594: // On attend que le fichier sois présent
595:
596: horodatage_initial = horodatage();
597:
598: while(stat(nom, &s_stat) != 0)
599: {
600: if (abs(horodatage_initial - horodatage()) > 500)
601: {
602: return(-1);
603: }
604: }
605: }
606:
607: if ((clef = ftok(nom, 1)) == -1)
608: {
609: return(-1);
610: }
611:
612: free(nom);
613:
614: if (signal == SIGSTART)
615: {
616: while((identifiant = shmget(clef,
617: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
618: S_IRUSR | S_IWUSR)) == -1);
619: }
620: else
621: {
622: if ((identifiant = shmget(clef,
623: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
624: S_IRUSR | S_IWUSR)) == -1)
625: {
626: return(-1);
627: }
628: }
629:
630: projection_fifos = shmat(identifiant, NULL, 0);
631:
632: if (((void *) projection_fifos) == ((void *) -1))
633: {
634: return(-1);
635: }
636:
637: # else
638:
639: // Ouverture des projections
640:
641: if ((nom = nom_segment(NULL, pid)) == NULL)
642: {
643: return(-1);
644: }
645:
646: if (signal == SIGSTART)
647: {
648: horodatage_initial = horodatage();
649:
650: while(DosGetNamedSharedMem(&ptr_os2, nom,
651: PAG_READ | PAG_WRITE | PAG_COMMIT) != 0)
652: {
653: if (abs(horodatage_initial - horodatage()) > 500)
654: {
655: return(-1);
656: }
657: }
658: }
659: else
660: {
661: if (DosGetNamedSharedMem(&ptr_os2, nom,
662: PAG_READ | PAG_WRITE) != 0)
663: {
664: return(-1);
665: }
666: }
667:
668: projection_fifos = ptr_os2;
669:
670: # endif
671: # endif
672:
673: if ((nom = nom_semaphore(pid, queue)) == NULL)
674: {
675: # ifdef IPCS_SYSV
676: # ifndef OS2
677: shmdt(projection_fifos);
678: # else
679: DosFreeMem(projection_fifos);
680: # endif
681: # else
682: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
683: * sizeof(int));
684: # endif
685: return(-1);
686: }
687:
688: while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
689: free(nom);
690:
691: while(sem_wait(semaphore) != 0)
692: {
693: if (errno != EINTR)
694: {
695: # ifdef IPCS_SYSV
696: # ifndef OS2
697: shmdt(projection_fifos);
698: # else
699: DosFreeMem(projection_fifos);
700: # endif
701: # else
702: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
703: * sizeof(int));
704: # endif
705: return(-1);
706: }
707: }
708:
709: base = &(projection_fifos[(longueur_queue + 4) * queue]);
710: buffer = &(base[4]);
711:
712: // base[3] contient le nombre d'éléments restants
713:
714: if (base[3] <= 0)
715: {
716: sem_post(semaphore);
717: sem_close(semaphore);
718: # ifdef IPCS_SYSV
719: # ifndef OS2
720: shmdt(projection_fifos);
721: # else
722: DosFreeMem(projection_fifos);
723: # endif
724: # else
725: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
726: * sizeof(int));
727: # endif
728: return(-1);
729: }
730:
731: base[3]--;
732:
733: // base[1] contient le prochain élément à écrire
734:
735: buffer[base[1] + (nombre_queues * base[2])] = horodatage();
736: buffer[base[1]++] = (int) pid;
737: base[1] %= base[2];
738:
739: if (sem_post(semaphore) != 0)
740: {
741: # ifdef IPCS_SYSV
742: # ifndef OS2
743: shmdt(projection_fifos);
744: # else
745: DosFreeMem(projection_fifos);
746: # endif
747: # else
748: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
749: * sizeof(int));
750: # endif
751: sem_close(semaphore);
752: return(-1);
753: }
754:
755: sem_close(semaphore);
756:
757: // Fermeture des projections
758: # ifdef IPCS_SYSV
759: # ifndef OS2
760: shmdt(projection_fifos);
761: # else
762: DosFreeMem(projection_fifos);
763: # endif
764: # else
765: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
766: * sizeof(int));
767: # endif
768:
769: return(0);
770: }
771:
772: static inline int
773: chaine_markov(int markov, int delta)
774: {
775: double memoire = 0.9;
776: int valeur;
777:
778: valeur = (int) ((memoire * markov) + ((1 - memoire) * delta));
779: valeur = (valeur < 10) ? 10 : valeur;
780:
781: return(valeur);
782: }
783:
784: pid_t
785: origine_signal(int signal)
786: {
787: logical1 drapeau;
788:
789: int *base;
790: int *buffer;
791: int delta;
792: int pid;
793: int queue;
794:
795: queue = queue_de_signal(signal);
796:
797: BUG(queue == -1, uprintf("[%d] Unknown signal %d in this context\n",
798: (int) getpid(), signal));
799:
800: while(sem_wait(semaphores[queue]) != 0)
801: {
802: if (errno != EINTR)
803: {
804: return(-1);
805: }
806: }
807:
808: // On retire les interruptions anciennes qui ont été ratées sauf s'il
809: // s'agit de la dernière dans la queue.
810:
811: base = &(fifos[(longueur_queue + 4) * queue]);
812: buffer = &(base[4]);
813:
814: if (base[3] == (base[2] - 1))
815: {
816: delta = abs(horodatage() -
817: buffer[base[0] + (nombre_queues * base[2])]);
818: // Une seule interruption dans la queue.
819: pid = buffer[base[0]++];
820: base[0] %= base[2];
821: base[3]++;
822:
823: markov = chaine_markov(markov, delta);
824: }
825: else if (base[3] >= base[2])
826: {
827: // Aucune interruption n'est dans la queue.
828: // On a retiré trop d'interruptions de la queue.
829:
830: // (base[3] - base[2]) + 1 : nombre d'interruptions manquantes
831: // base[0] - 1 : dernière interruption lue
832: pid = buffer[((((base[0] + base[2] - 1) % base[2])
833: - ((base[3] - base[2]) + 1)) + base[2]) % base[2]];
834:
835: if (kill(pid, 0) != 0)
836: {
837: pid = getpid();
838: }
839: }
840: else
841: {
842: // Plusieurs interruptions à distribuer.
843: drapeau = d_vrai;
844:
845: do
846: {
847: delta = abs(horodatage() -
848: buffer[base[0] + (nombre_queues * base[2])]);
849: pid = buffer[base[0]++];
850: base[0] %= base[2];
851: base[3]++;
852:
853: if ((delta > (2 * markov)) && (base[3] < base[2]))
854: {
855: drapeau = d_vrai;
856: }
857: else
858: {
859: drapeau = d_faux;
860: }
861: } while(drapeau == d_vrai);
862:
863: markov = chaine_markov(markov, delta);
864: }
865:
866: if (sem_post(semaphores[queue]) != 0)
867: {
868: return(-1);
869: }
870:
871: return((pid_t) pid);
872: }
873:
874: int
875: kill_broken_siginfo(pid_t pid, int signal)
876: {
877: int ios;
878:
879: sem_t *semaphore;
880:
881: unsigned char *nom;
882:
883: /*
884: * Lorsqu'on veut interrompre le processus pid, on ouvre le segment
885: * correspondant au processus en question et ou ajoute le pid dans la
886: * queue.
887: *
888: * Le sémaphore global à tous les threads d'un même processus sert
889: * à garantir que les signaux seront traités dans l'ordre de ce qui est
890: * effectivement mis dans la queue.
891: */
892:
893: // Sémaphore acquis
894:
895: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
896: {
897: return(-1);
898: }
899:
900: while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
901: free(nom);
902:
903: while(sem_wait(semaphore) != 0)
904: {
905: if (errno != EINTR)
906: {
907: return(-1);
908: }
909: }
910:
911: if ((signal != 0) && (signal != SIGINT))
912: {
913: if (queue_in(pid, signal) != 0)
914: {
915: sem_post(semaphore);
916: sem_close(semaphore);
917: return(-1);
918: }
919: }
920:
921: ios = kill(pid, signal);
922:
923: // Sémaphore relâché
924:
925: sem_post(semaphore);
926: sem_close(semaphore);
927:
928: return(ios);
929: }
930:
931: int
932: pthread_kill_broken_siginfo(pthread_t tid, int signal)
933: {
934: int ios;
935:
936: sem_t *semaphore;
937:
938: unsigned char *nom;
939:
940: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
941: {
942: return(-1);
943: }
944:
945: while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
946: free(nom);
947:
948: while(sem_wait(semaphore) != 0)
949: {
950: if (errno != EINTR)
951: {
952: return(-1);
953: }
954: }
955:
956: if ((signal != 0) && (signal != SIGINT))
957: {
958: if (queue_in(getpid(), signal) != 0)
959: {
960: sem_post(semaphore);
961: sem_close(semaphore);
962: return(-1);
963: }
964: }
965:
966: ios = pthread_kill(tid, signal);
967:
968: sem_post(semaphore);
969: sem_close(semaphore);
970:
971: return(ios);
972: }
973:
974: #endif
975:
976: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>