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

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

CVSweb interface <joel.bertrand@systella.fr>