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