![]() ![]() | ![]() |
Passage de la branche 4.1 en branche stable.
1: /* 2: ================================================================================ 3: RPL/2 (R) version 4.1.0 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: #include "rpl-conv.h" 24: 25: #ifdef SEMAPHORES_NOMMES 26: 27: /* 28: ================================================================================ 29: Fonctions d'émulation de sémaphores anonymes 30: ================================================================================ 31: Entrées : 32: -------------------------------------------------------------------------------- 33: Sorties : 34: -------------------------------------------------------------------------------- 35: Effets de bord : néant 36: ================================================================================ 37: */ 38: 39: sem_t * 40: sem_init2(unsigned int valeur, enum t_semaphore semaphore) 41: { 42: snprintf(noms_semaphores[semaphore], LONGUEUR_NOM_SEMAPHORE, 43: "/RPL-SEM-%d-%llu-%d", (int) getpid(), 44: (unsigned long long) pthread_self(), 45: (int) semaphore); 46: return(sem_open(noms_semaphores[semaphore], O_CREAT, 47: (S_IRUSR | S_IWUSR), valeur)); 48: } 49: 50: int 51: sem_destroy2(sem_t *semaphore_p, enum t_semaphore semaphore) 52: { 53: sem_close(semaphore_p); 54: return(sem_unlink(noms_semaphores[semaphore])); 55: } 56: 57: #undef sem_post 58: #undef sem_wait 59: #undef sem_trywait 60: 61: int 62: sem_getvalue2(sem_t *semaphore, int *valeur) 63: { 64: int i; 65: 66: logical1 drapeau_fin; 67: 68: pthread_mutex_lock(&mutex_sem); 69: 70: (*valeur) = 0; 71: drapeau_fin = d_faux; 72: 73: do 74: { 75: if (sem_trywait(semaphore) == -1) 76: { 77: if (errno == EAGAIN) 78: { 79: // Le sémaphore avait une valeur nulle 80: drapeau_fin = d_vrai; 81: } 82: else 83: { 84: // Autre erreur 85: pthread_mutex_unlock(&mutex_sem); 86: return(-1); 87: } 88: } 89: else 90: { 91: (*valeur)++; 92: } 93: } while(drapeau_fin == d_faux); 94: 95: for(i = 0; i < (*valeur); i++) 96: { 97: if (sem_post(semaphore) != 0) 98: { 99: pthread_mutex_unlock(&mutex_sem); 100: return(-1); 101: } 102: } 103: 104: pthread_mutex_unlock(&mutex_sem); 105: return(0); 106: } 107: 108: #endif 109: 110: #ifdef IPCS_SYSV 111: 112: /* 113: ================================================================================ 114: Fonctions d'émulation de sémaphores POSIX en fonction des sémaphores SysV 115: ================================================================================ 116: Entrées : 117: -------------------------------------------------------------------------------- 118: Sorties : 119: -------------------------------------------------------------------------------- 120: Effets de bord : néant 121: ================================================================================ 122: */ 123: 124: #ifndef OS2 125: extern unsigned char *chemin_semaphores_SysV; 126: #else 127: unsigned char racine_semaphores_OS2[] = "\\SEM32\\"; 128: unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\"; 129: #endif 130: 131: int 132: sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur) 133: { 134: // Création d'un sémaphore anonyme qui devra être supprimé par 135: // sem_destroy_SysV 136: # ifndef OS2 137: 138: int ios; 139: 140: union semun argument; 141: 142: if (shared != 0) 143: { 144: errno = ENOSYS; 145: return(-1); 146: } 147: 148: (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 149: S_IRUSR | S_IWUSR); 150: (*semaphore).path = NULL; 151: (*semaphore).pid = getpid(); 152: 153: if ((*semaphore).sem == -1) 154: { 155: errno = EINVAL; 156: return(-1); 157: } 158: 159: argument.val = valeur; 160: ios = semctl((*semaphore).sem, 0, SETVAL, argument); 161: 162: return(ios); 163: 164: # else 165: 166: sem_t *psem; 167: 168: psem = semaphore; 169: 170: if (shared != 0) 171: { 172: errno = ENOSYS; 173: return(-1); 174: } 175: 176: if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL) 177: { 178: free(psem); 179: errno = ENOMEM; 180: return(-1); 181: } 182: 183: if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL) 184: { 185: free((*psem).cnt); 186: free(psem); 187: errno = ENOMEM; 188: return(-1); 189: } 190: 191: if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0) 192: { 193: free((*psem).cnt); 194: free((*psem).nopened); 195: free(psem); 196: return(-1); 197: } 198: 199: if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0) != 0) 200: { 201: DosCloseMutexSem((*psem).hmtx); 202: free((*psem).cnt); 203: free((*psem).nopened); 204: free(psem); 205: return(-1); 206: } 207: 208: (*(*psem).cnt) = valeur; 209: (*(*psem).nopened) = 1; 210: (*psem).shared = shared; 211: (*psem).allocated = 0; 212: 213: return(0); 214: 215: # endif 216: } 217: 218: int 219: sem_destroy_SysV(sem_t *semaphore) 220: { 221: // Détruit un sémaphore anonmyme 222: # ifndef OS2 223: 224: if ((*semaphore).path != NULL) 225: { 226: return(EINVAL); 227: } 228: 229: if ((*semaphore).pid != getpid()) 230: { 231: return(0); 232: } 233: 234: if (semctl((*semaphore).sem, 0, IPC_RMID) == -1) 235: { 236: return(EINVAL); 237: } 238: 239: return(0); 240: 241: # else 242: 243: sem_t *psem; 244: 245: psem = semaphore; 246: 247: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) 248: { 249: return(EINVAL); 250: } 251: 252: if (DosCloseMutexSem((*psem).hmtx) != 0) 253: { 254: return(EINVAL); 255: } 256: 257: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY) 258: { 259: DosPostEventSem((*psem).hev); 260: } 261: 262: (*(*psem).nopened)--; 263: 264: if ((*psem).shared == 0) 265: { 266: free((*psem).cnt); 267: free((*psem).nopened); 268: } 269: else 270: { 271: if ((*(*psem).nopened) == 0) 272: { 273: DosFreeMem((*psem).cnt); 274: } 275: } 276: 277: if ((*psem).allocated != 0) 278: { 279: free(psem); 280: } 281: 282: return(0); 283: 284: # endif 285: } 286: 287: int 288: sem_wait_SysV(sem_t *semaphore) 289: { 290: # ifndef OS2 291: 292: struct sembuf commande; 293: 294: commande.sem_num = 0; 295: commande.sem_op = -1; 296: commande.sem_flg = 0; 297: 298: while(semop((*semaphore).sem, &commande, 1) == -1) 299: { 300: if (errno != EINTR) 301: { 302: errno = EINVAL; 303: return(-1); 304: } 305: } 306: 307: return(0); 308: 309: # else 310: 311: sem_t *psem; 312: 313: ULONG cnt; 314: 315: psem = semaphore; 316: 317: if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0) 318: { 319: errno = EINVAL; 320: return(-1); 321: } 322: 323: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) 324: { 325: errno = EINVAL; 326: return(-1); 327: } 328: 329: if ((*(*psem).cnt) > 0) 330: { 331: (*(*psem).cnt)--; 332: } 333: 334: if ((*(*psem).cnt) == 0) 335: { 336: DosResetEventSem((*psem).hev, &cnt); 337: } 338: 339: DosReleaseMutexSem((*psem).hmtx); 340: return(0); 341: 342: # endif 343: } 344: 345: int 346: sem_trywait_SysV(sem_t *semaphore) 347: { 348: # ifndef OS2 349: 350: struct sembuf commande; 351: 352: commande.sem_num = 0; 353: commande.sem_op = -1; 354: commande.sem_flg = IPC_NOWAIT; 355: 356: while(semop((*semaphore).sem, &commande, 1) == -1) 357: { 358: if (errno != EINTR) 359: { 360: errno = EINVAL; 361: return(-1); 362: } 363: } 364: 365: return(0); 366: 367: # else 368: 369: int ios; 370: 371: sem_t *psem; 372: 373: ULONG cnt; 374: 375: psem = semaphore; 376: 377: if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0) 378: { 379: errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL; 380: return(-1); 381: } 382: 383: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) 384: { 385: errno = EINVAL; 386: return(-1); 387: } 388: 389: if ((*(*psem).cnt) > 0) 390: { 391: (*(*psem).cnt)--; 392: } 393: 394: if ((*(*psem).cnt) == 0) 395: { 396: DosResetEventSem((*psem).hev, &cnt); 397: } 398: 399: DosReleaseMutexSem((*psem).hmtx); 400: return(0); 401: 402: # endif 403: } 404: 405: int 406: sem_post_SysV(sem_t *semaphore) 407: { 408: # ifndef OS2 409: 410: struct sembuf commande; 411: 412: commande.sem_num = 0; 413: commande.sem_op = 1; 414: commande.sem_flg = 0; 415: 416: while(semop((*semaphore).sem, &commande, 1) == -1) 417: { 418: if (errno != EINTR) 419: { 420: errno = EINVAL; 421: return(-1); 422: } 423: } 424: 425: return(0); 426: 427: # else 428: 429: sem_t *psem; 430: 431: psem = semaphore; 432: 433: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) 434: { 435: errno = EINVAL; 436: return(-1); 437: } 438: 439: (*(*psem).cnt)++; 440: DosPostEventSem((*psem).hev); 441: DosReleaseMutexSem((*psem).hmtx); 442: 443: return(0); 444: 445: # endif 446: } 447: 448: int 449: sem_getvalue_SysV(sem_t *semaphore, int *valeur) 450: { 451: # ifndef OS2 452: 453: (*valeur) = semctl((*semaphore).sem, 0, GETVAL); 454: 455: if ((*valeur) < 0) 456: { 457: return(EINVAL); 458: } 459: 460: return(0); 461: 462: # else 463: 464: sem_t *psem; 465: 466: psem = semaphore; 467: 468: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) 469: { 470: errno = EINVAL; 471: return(-1); 472: } 473: 474: (*valeur) = (*(*psem).cnt); 475: DosReleaseMutexSem((*psem).hmtx); 476: 477: return(0); 478: 479: # endif 480: } 481: 482: sem_t 483: *sem_open_SysV(const char *nom, int oflag, ...) 484: //*sem_open(const char *nom, int oflag) 485: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value) 486: { 487: mode_t mode; 488: 489: sem_t *semaphore; 490: 491: # ifndef OS2 492: file *desc; 493: 494: key_t clef; 495: 496: union semun argument; 497: # endif 498: 499: unsigned char *nom_absolu; 500: 501: unsigned int valeur; 502: 503: va_list liste; 504: 505: # ifdef OS2 506: sem_t *psem; 507: 508: PVOID base; 509: 510: unsigned char *ptr; 511: unsigned char *nom_segment; 512: # endif 513: 514: # ifndef OS2 515: 516: if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom) 517: + 1) * sizeof(unsigned char))) == NULL) 518: { 519: return(SEM_FAILED); 520: } 521: 522: sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom); 523: 524: if ((semaphore = malloc(sizeof(sem_t))) == NULL) 525: { 526: return(SEM_FAILED); 527: } 528: 529: # else 530: 531: if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1) 532: * sizeof(unsigned char))) == NULL) 533: { 534: return(SEM_FAILED); 535: } 536: 537: sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom); 538: ptr = nom_segment; 539: 540: while((*ptr) != d_code_fin_chaine) 541: { 542: if ((*ptr) == '/') 543: { 544: (*ptr) = '\\'; 545: } 546: 547: ptr++; 548: } 549: 550: if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom) 551: + 2) * sizeof(unsigned char))) == NULL) 552: { 553: return(SEM_FAILED); 554: } 555: 556: sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom); 557: ptr = nom_absolu; 558: 559: while((*ptr) != d_code_fin_chaine) 560: { 561: if ((*ptr) == '/') 562: { 563: (*ptr) = '\\'; 564: } 565: 566: ptr++; 567: } 568: 569: (*(ptr + 1)) = d_code_fin_chaine; 570: 571: if ((psem = malloc(sizeof(sem_t))) == NULL) 572: { 573: return(SEM_FAILED); 574: } 575: 576: (*psem).allocated = 1; 577: 578: # endif 579: 580: if ((oflag & O_CREAT) == 0) 581: { 582: // 2 arguments 583: 584: # ifndef OS2 585: 586: clef = ftok(nom_absolu, 1); 587: 588: if (clef == -1) 589: { 590: return(SEM_FAILED); 591: } 592: 593: (*semaphore).sem = semget(clef, 0, 0); 594: (*semaphore).path = nom_absolu; 595: (*semaphore).pid = getpid(); 596: 597: if ((*semaphore).sem == -1) 598: { 599: free(semaphore); 600: free(nom_absolu); 601: 602: return(SEM_FAILED); 603: } 604: 605: # else 606: 607: if ((psem = malloc(sizeof(sem_t))) == NULL) 608: { 609: free(nom_absolu); 610: free(nom_segment); 611: return(SEM_FAILED); 612: } 613: 614: (*ptr) = 'M'; 615: 616: if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0) 617: { 618: free(psem); 619: free(nom_absolu); 620: free(nom_segment); 621: 622: return(SEM_FAILED); 623: } 624: 625: (*ptr) = 'S'; 626: 627: if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0) 628: { 629: DosCloseMutexSem((*psem).hmtx); 630: 631: free(psem); 632: free(nom_absolu); 633: free(nom_segment); 634: 635: return(SEM_FAILED); 636: } 637: 638: if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ) != 0) 639: { 640: DosCloseMutexSem((*psem).hmtx); 641: 642: free(nom_absolu); 643: free(nom_segment); 644: free(psem); 645: 646: return(SEM_FAILED); 647: } 648: 649: free(nom_segment); 650: 651: (*psem).cnt = (ULONG *) base; 652: (*psem).nopened = ((ULONG *) base) + 1; 653: (*psem).shared = 1; 654: 655: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) 656: { 657: DosCloseMutexSem((*psem).hmtx); 658: 659: free(nom_absolu); 660: free(nom_segment); 661: free(psem); 662: 663: return(SEM_FAILED); 664: } 665: 666: (*((*psem).nopened))++; 667: 668: DosReleaseMutexSem((*psem).hmtx); 669: 670: semaphore = psem; 671: 672: # endif 673: } 674: else 675: { 676: // 4 arguments 677: 678: // O_CREAT O_EXCL 679: // S_IRUSR S_IWUSR 680: 681: va_start(liste, oflag); 682: mode = va_arg(liste, mode_t); 683: valeur = va_arg(liste, unsigned int); 684: va_end(liste); 685: 686: # ifndef OS2 687: 688: if ((desc = fopen(nom_absolu, "w")) == NULL) 689: { 690: free(semaphore); 691: free(nom_absolu); 692: 693: return(SEM_FAILED); 694: } 695: 696: fclose(desc); 697: 698: if ((clef = ftok(nom_absolu, 1)) == -1) 699: { 700: free(semaphore); 701: free(nom_absolu); 702: 703: return(SEM_FAILED); 704: } 705: 706: (*semaphore).sem = semget(clef, 1, 707: (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) | 708: (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) | 709: (int) mode); 710: (*semaphore).path = nom_absolu; 711: (*semaphore).pid = getpid(); 712: 713: if ((*semaphore).sem == -1) 714: { 715: free(semaphore); 716: free(nom_absolu); 717: 718: return(SEM_FAILED); 719: } 720: 721: argument.val = valeur; 722: semctl((*semaphore).sem, 0, SETVAL, argument); 723: 724: # else 725: 726: if ((psem = malloc(sizeof(sem_t))) == NULL) 727: { 728: free(nom_absolu); 729: free(nom_segment); 730: 731: return(SEM_FAILED); 732: } 733: 734: (*ptr) = 'M'; 735: 736: if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0) 737: { 738: free(psem); 739: free(nom_absolu); 740: free(nom_segment); 741: 742: return(SEM_FAILED); 743: } 744: 745: (*ptr) = 'S'; 746: 747: if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0, 748: (valeur != 0) ? 1 : 0) != 0) 749: { 750: DosCloseMutexSem((*psem).hmtx); 751: 752: free(nom_absolu); 753: free(nom_segment); 754: free(psem); 755: 756: return(SEM_FAILED); 757: } 758: 759: if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG), 760: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0) 761: { 762: DosCloseMutexSem((*psem).hmtx); 763: 764: free(nom_absolu); 765: free(nom_segment); 766: free(psem); 767: 768: return(SEM_FAILED); 769: } 770: 771: free(nom_segment); 772: 773: (*psem).cnt = (ULONG *) base; 774: (*psem).nopened = ((ULONG *) base) + 1; 775: (*(*psem).cnt) = valeur; 776: (*(*psem).nopened) = 1; 777: (*psem).shared = 1; 778: semaphore = psem; 779: 780: # endif 781: } 782: 783: return(semaphore); 784: } 785: 786: int 787: sem_close_SysV(sem_t *semaphore) 788: { 789: // Ferme un sémaphore nommé créé par sem_open_SysV() 790: # ifndef OS2 791: 792: if ((*semaphore).path != NULL) 793: { 794: free((*semaphore).path); 795: } 796: 797: free(semaphore); 798: return(0); 799: 800: # else 801: 802: sem_t *psem; 803: 804: psem = semaphore; 805: 806: if (DosCloseMutexSem((*psem).hmtx) != 0) 807: { 808: return(EINVAL); 809: } 810: 811: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY) 812: { 813: DosPostEventSem((*psem).hev); 814: } 815: 816: (*(*psem).nopened)--; 817: 818: if ((*psem).shared == 0) 819: { 820: free((*psem).cnt); 821: free((*psem).nopened); 822: } 823: else 824: { 825: if ((*(*psem).nopened) == 0) 826: { 827: DosFreeMem((*psem).cnt); 828: } 829: } 830: 831: if ((*psem).allocated != 0) 832: { 833: free(psem); 834: } 835: 836: return(0); 837: 838: # endif 839: } 840: 841: int 842: sem_unlink_SysV(const char *nom) 843: { 844: // Détruit un sémaphore nommé créé par sem_open_SysV() 845: # ifndef OS2 846: 847: unsigned char *nom_absolu; 848: 849: if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom) 850: + 1) * sizeof(unsigned char))) == NULL) 851: { 852: return(ENOMEM); 853: } 854: 855: sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom); 856: semctl(semget(ftok(nom_absolu, 1), 0, 0), 0, IPC_RMID); 857: 858: if (unlink(nom_absolu) == -1) 859: { 860: free(nom_absolu); 861: return(EACCES); 862: } 863: 864: free(nom_absolu); 865: 866: return(0); 867: 868: # else 869: 870: return(0); 871: 872: # endif 873: } 874: 875: #endif 876: 877: // vim: ts=4