File:  [local] / rpl / src / semaphores.c
Revision 1.29: download - view: text, annotated - select for diffs - revision graph
Sun Sep 18 12:42:50 2011 UTC (12 years, 7 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Première série de patches pour porter la nouvelle gestion des signaux sous
MacOS X. La compilation se déroule bien, mais une opération de l'émulation
de sem_getvalue() n'est pas atomique et peut aboutir à une condition
bloquante.

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

CVSweb interface <joel.bertrand@systella.fr>