File:  [local] / rpl / src / semaphores.c
Revision 1.34: download - view: text, annotated - select for diffs - revision graph
Tue Sep 20 14:36:30 2011 UTC (12 years, 7 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Patches pour MacOS X (non fonctionnels).

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

CVSweb interface <joel.bertrand@systella.fr>