File:  [local] / rpl / src / semaphores.c
Revision 1.33: download - view: text, annotated - select for diffs - revision graph
Tue Sep 20 07:16:40 2011 UTC (12 years, 7 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Suite des patches pour les IPCS SysV.

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

CVSweb interface <joel.bertrand@systella.fr>