File:  [local] / rpl / src / semaphores.c
Revision 1.35: download - view: text, annotated - select for diffs - revision graph
Tue Sep 20 15:45:53 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-SIGSEMAPHORE-%d-%llX",
  301:                     racine_segment, pthread_self(),
  302:                     (int) getpid(), pthread_self());
  303: 
  304:             if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL,
  305:                     S_IRUSR | S_IWUSR)) == -1)
  306:             {
  307:                 free((*semaphore).path);
  308:                 return(-1);
  309:             }
  310: 
  311:             (*semaphore).pid = getpid();
  312:             (*semaphore).tid = pthread_slef();
  313:             clef = ftok((*semaphore).path, 1);
  314:             close(desc);
  315: 
  316:             if (clef == -1)
  317:             {
  318:                 free((*semaphore).path);
  319:                 return(-1);
  320:             }
  321: 
  322:             (*semaphore).alloue = 0;
  323:             (*semaphore).sem = semget(clef, 1, IPC_CREAT | IPC_EXCL |
  324:                     S_IRUSR | S_IWUSR);
  325:         }
  326: 
  327:         if ((*semaphore).sem == -1)
  328:         {
  329:             errno = EINVAL;
  330:             return(-1);
  331:         }
  332: 
  333:         argument.val = valeur;
  334:         ios = semctl((*semaphore).sem, 0, SETVAL, argument);
  335: 
  336:         return(ios);
  337: #   else // OS/2
  338: 
  339:     sem_t           *psem;
  340: 
  341:     psem = semaphore;
  342: 
  343:     if (shared != 0)
  344:     {
  345:         errno = ENOSYS;
  346:         return(-1);
  347:     }
  348: 
  349:     if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)
  350:     {
  351:         free(psem);
  352:         errno = ENOMEM;
  353:         return(-1);
  354:     }
  355: 
  356:     if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)
  357:     {
  358:         free((*psem).cnt);
  359:         free(psem);
  360:         errno = ENOMEM;
  361:         return(-1);
  362:     }
  363: 
  364:     if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
  365:     {
  366:         free((*psem).cnt);
  367:         free((*psem).nopened);
  368:         free(psem);
  369:         return(-1);
  370:     }
  371: 
  372:     if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0) != 0)
  373:     {
  374:         DosCloseMutexSem((*psem).hmtx);
  375:         free((*psem).cnt);
  376:         free((*psem).nopened);
  377:         free(psem);
  378:         return(-1);
  379:     }
  380: 
  381:     (*(*psem).cnt) = valeur;
  382:     (*(*psem).nopened) = 1;
  383:     (*psem).shared = shared;
  384:     (*psem).allocated = 0;
  385: 
  386:     return(0);
  387: 
  388: #   endif
  389: }
  390: 
  391: int
  392: sem_destroy_SysV(sem_t *semaphore)
  393: {
  394:     // Détruit un sémaphore anonmyme
  395: 
  396: #   ifndef OS2 // IPCS_SYSV
  397:         if ((*semaphore).path != NULL)
  398:         {
  399:             return(EINVAL);
  400:         }
  401: 
  402:         if ((*semaphore).pid != getpid())
  403:         {
  404:             return(0);
  405:         }
  406: 
  407:         if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
  408:         {
  409:             return(EINVAL);
  410:         }
  411: 
  412:         return(0);
  413: #   else // OS/2
  414: 
  415:     sem_t       *psem;
  416: 
  417:     psem = semaphore;
  418: 
  419:     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  420:     {
  421:         return(EINVAL);
  422:     }
  423: 
  424:     if (DosCloseMutexSem((*psem).hmtx) != 0)
  425:     {
  426:         return(EINVAL);
  427:     }
  428: 
  429:     while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
  430:     {
  431:         DosPostEventSem((*psem).hev);
  432:     }
  433: 
  434:     (*(*psem).nopened)--;
  435: 
  436:     if ((*psem).shared == 0)
  437:     {
  438:         free((*psem).cnt);
  439:         free((*psem).nopened);
  440:     }
  441:     else
  442:     {
  443:         if ((*(*psem).nopened) == 0)
  444:         {
  445:             DosFreeMem((*psem).cnt);
  446:         }
  447:     }
  448: 
  449:     if ((*psem).allocated != 0)
  450:     {   
  451:         free(psem);
  452:     }
  453: 
  454:     return(0);
  455: 
  456: #   endif
  457: }
  458: 
  459: int
  460: sem_wait_SysV(sem_t *semaphore)
  461: {
  462: #   ifndef OS2 // IPCS_SYSV
  463:         struct sembuf       commande;
  464: 
  465:         commande.sem_num = 0;
  466:         commande.sem_op = -1;
  467:         commande.sem_flg = 0;
  468: 
  469:         while(semop((*semaphore).sem, &commande, 1) == -1)
  470:         {
  471:             if (errno != EINTR)
  472:             {
  473:                 errno = EINVAL;
  474:                 return(-1);
  475:             }
  476:         }
  477: 
  478:         return(0);
  479: #   else // OS/2
  480: 
  481:     sem_t       *psem;
  482: 
  483:     ULONG       cnt;
  484: 
  485:     psem = semaphore;
  486: 
  487:     if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
  488:     {
  489:         errno = EINVAL;
  490:         return(-1);
  491:     }
  492: 
  493:     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  494:     {
  495:         errno = EINVAL;
  496:         return(-1);
  497:     }
  498: 
  499:     if ((*(*psem).cnt) > 0)
  500:     {
  501:         (*(*psem).cnt)--;
  502:     }
  503: 
  504:     if ((*(*psem).cnt) == 0)
  505:     {
  506:         DosResetEventSem((*psem).hev, &cnt);
  507:     }
  508: 
  509:     DosReleaseMutexSem((*psem).hmtx);
  510:     return(0);
  511: 
  512: #   endif
  513: }
  514: 
  515: int
  516: sem_trywait_SysV(sem_t *semaphore)
  517: {
  518: #   ifndef OS2 // IPCS_SYSV
  519:         struct sembuf       commande;
  520: 
  521:         commande.sem_num = 0;
  522:         commande.sem_op = -1;
  523:         commande.sem_flg = IPC_NOWAIT;
  524: 
  525:         while(semop((*semaphore).sem, &commande, 1) == -1)
  526:         {
  527:             if (errno != EINTR)
  528:             {
  529:                 errno = EINVAL;
  530:                 return(-1);
  531:             }
  532:         }
  533: 
  534:         return(0);
  535: #   else // OS/2
  536: 
  537:     int         ios;
  538: 
  539:     sem_t       *psem;
  540: 
  541:     ULONG       cnt;
  542: 
  543:     psem = semaphore;
  544: 
  545:     if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
  546:     {
  547:         errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
  548:         return(-1);
  549:     }
  550: 
  551:     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  552:     {
  553:         errno = EINVAL;
  554:         return(-1);
  555:     }
  556: 
  557:     if ((*(*psem).cnt) > 0)
  558:     {
  559:         (*(*psem).cnt)--;
  560:     }
  561: 
  562:     if ((*(*psem).cnt) == 0)
  563:     {
  564:         DosResetEventSem((*psem).hev, &cnt);
  565:     }
  566: 
  567:     DosReleaseMutexSem((*psem).hmtx);
  568:     return(0);
  569: 
  570: #   endif
  571: }
  572: 
  573: int
  574: sem_post_SysV(sem_t *semaphore)
  575: {
  576: #   ifndef OS2 // IPCS_SYSV
  577:         struct sembuf       commande;
  578: 
  579:         commande.sem_num = 0;
  580:         commande.sem_op = 1;
  581:         commande.sem_flg = 0;
  582: 
  583:         while(semop((*semaphore).sem, &commande, 1) == -1)
  584:         {
  585:             if (errno != EINTR)
  586:             {
  587:                 errno = EINVAL;
  588:                 return(-1);
  589:             }
  590:         }
  591: 
  592:         return(0);
  593: #   else // OS/2
  594: 
  595:     sem_t               *psem;
  596: 
  597:     psem = semaphore;
  598: 
  599:     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  600:     {
  601:         errno = EINVAL;
  602:         return(-1);
  603:     }
  604: 
  605:     (*(*psem).cnt)++;
  606:     DosPostEventSem((*psem).hev);
  607:     DosReleaseMutexSem((*psem).hmtx);
  608: 
  609:     return(0);
  610: 
  611: #   endif
  612: }
  613: 
  614: int
  615: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
  616: {
  617: #   ifndef OS2 // IPCS_SYSV
  618:         (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
  619: 
  620:         if ((*valeur) < 0)
  621:         {
  622:             return(EINVAL);
  623:         }
  624: 
  625:         return(0);
  626: #   else
  627: 
  628:     sem_t               *psem;
  629: 
  630:     psem = semaphore;
  631: 
  632:     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  633:     {
  634:         errno = EINVAL;
  635:         return(-1);
  636:     }
  637: 
  638:     (*valeur) = (*(*psem).cnt);
  639:     DosReleaseMutexSem((*psem).hmtx);
  640: 
  641:     return(0);
  642: 
  643: #   endif
  644: }
  645: 
  646: sem_t
  647: *sem_open_SysV(const char *nom, int oflag, ...)
  648: //*sem_open(const char *nom, int oflag)
  649: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
  650: {
  651:     mode_t              mode;
  652: 
  653:     sem_t               *semaphore;
  654: 
  655: #   ifndef OS2
  656:         int             desc;
  657: 
  658:         key_t           clef;
  659: 
  660:         union semun     argument;
  661: #   endif
  662: 
  663:     unsigned char       *nom_absolu;
  664: 
  665:     unsigned int        valeur;
  666: 
  667:     va_list             liste;
  668: 
  669: #   ifdef OS2
  670:         sem_t           *psem;
  671: 
  672:         PVOID           base;
  673: 
  674:         unsigned char   *ptr;
  675:         unsigned char   *nom_segment;
  676: #   endif
  677: 
  678: #   ifndef OS2 // IPCS_SYSV
  679:         if ((nom_absolu = malloc((strlen(racine_segment) + strlen(nom)
  680:                 + 2) * sizeof(unsigned char))) == NULL)
  681:         {
  682:             return(SEM_FAILED);
  683:         }
  684: 
  685:         sprintf(nom_absolu, "%s/%s", racine_segment, nom);
  686: 
  687:         if ((semaphore = malloc(sizeof(sem_t))) == NULL)
  688:         {
  689:             return(SEM_FAILED);
  690:         }
  691: 
  692:         (*semaphore).alloue = -1;
  693:         (*semaphore).pid = getpid();
  694:         (*semaphore).tid = pthread_self();
  695: #   else
  696: 
  697:     if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)
  698:             * sizeof(unsigned char))) == NULL)
  699:     {
  700:         return(SEM_FAILED);
  701:     }   
  702: 
  703:     sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
  704:     ptr = nom_segment;
  705: 
  706:     while((*ptr) != d_code_fin_chaine)
  707:     {
  708:         if ((*ptr) == '/')
  709:         {
  710:             (*ptr) = '\\';
  711:         }
  712: 
  713:         ptr++;
  714:     }
  715: 
  716:     if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom)
  717:             + 2) * sizeof(unsigned char))) == NULL)
  718:     {
  719:         return(SEM_FAILED);
  720:     }
  721: 
  722:     sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);
  723:     ptr = nom_absolu;
  724: 
  725:     while((*ptr) != d_code_fin_chaine)
  726:     {
  727:         if ((*ptr) == '/')
  728:         {
  729:             (*ptr) = '\\';
  730:         }
  731: 
  732:         ptr++;
  733:     }
  734: 
  735:     (*(ptr + 1)) = d_code_fin_chaine;
  736: 
  737:     if ((psem = malloc(sizeof(sem_t))) == NULL)
  738:     {
  739:         return(SEM_FAILED);
  740:     }
  741: 
  742:     (*psem).allocated = 1;
  743: 
  744: #   endif
  745: 
  746:     if ((oflag & O_CREAT) == 0)
  747:     {
  748:         // 2 arguments
  749: 
  750: #       ifndef OS2 // IPCS_SYSV
  751:             clef = ftok(nom_absolu, 1);
  752: 
  753:             if (clef == -1)
  754:             {
  755:                 return(SEM_FAILED);
  756:             }
  757: 
  758:             (*semaphore).sem = semget(clef, 0, 0);
  759:             (*semaphore).path = nom_absolu;
  760:             (*semaphore).pid = getpid();
  761: 
  762:             if ((*semaphore).sem == -1)
  763:             {   
  764:                 free(semaphore);
  765:                 free(nom_absolu);
  766: 
  767:                 return(SEM_FAILED);
  768:             }
  769: #       else // OS/2
  770:         if ((psem = malloc(sizeof(sem_t))) == NULL)
  771:         {
  772:             free(nom_absolu);
  773:             free(nom_segment);
  774:             return(SEM_FAILED);
  775:         }
  776: 
  777:         (*ptr) = 'M';
  778: 
  779:         if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
  780:         {
  781:             free(psem);
  782:             free(nom_absolu);
  783:             free(nom_segment);
  784: 
  785:             return(SEM_FAILED);
  786:         }
  787: 
  788:         (*ptr) = 'S';
  789: 
  790:         if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
  791:         {
  792:             DosCloseMutexSem((*psem).hmtx);
  793: 
  794:             free(psem);
  795:             free(nom_absolu);
  796:             free(nom_segment);
  797: 
  798:             return(SEM_FAILED);
  799:         }
  800: 
  801:         if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ) != 0)
  802:         {
  803:             DosCloseMutexSem((*psem).hmtx);
  804: 
  805:             free(nom_absolu);
  806:             free(nom_segment);
  807:             free(psem);
  808: 
  809:             return(SEM_FAILED);
  810:         }
  811: 
  812:         free(nom_segment);
  813: 
  814:         (*psem).cnt = (ULONG *) base;
  815:         (*psem).nopened = ((ULONG *) base) + 1;
  816:         (*psem).shared = 1;
  817: 
  818:         if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  819:         {
  820:             DosCloseMutexSem((*psem).hmtx);
  821: 
  822:             free(nom_absolu);
  823:             free(nom_segment);
  824:             free(psem);
  825: 
  826:             return(SEM_FAILED);
  827:         }
  828: 
  829:         (*((*psem).nopened))++;
  830: 
  831:         DosReleaseMutexSem((*psem).hmtx);
  832: 
  833:         semaphore = psem;
  834: 
  835: #       endif
  836:     }
  837:     else
  838:     {
  839:         // 4 arguments
  840: 
  841:         // O_CREAT O_EXCL
  842:         // S_IRUSR S_IWUSR
  843: 
  844:         va_start(liste, oflag);
  845:         mode = va_arg(liste, mode_t);
  846:         valeur = va_arg(liste, unsigned int);
  847:         va_end(liste);
  848: 
  849: #       ifndef OS2 // IPCS_SYSV
  850:             if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR,
  851:                     S_IRUSR | S_IWUSR)) == -1)
  852:             {
  853:                 free(semaphore);
  854:                 free(nom_absolu);
  855: 
  856:                 return(SEM_FAILED);
  857:             }
  858: 
  859:             if ((clef = ftok(nom_absolu, 1)) == -1)
  860:             {
  861:                 close(desc);
  862:                 free(semaphore);
  863:                 free(nom_absolu);
  864: 
  865:                 return(SEM_FAILED);
  866:             }
  867: 
  868:             close(desc);
  869: 
  870:             (*semaphore).sem = semget(clef, 1,
  871:                     (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |
  872:                     (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |
  873:                     (int) mode);
  874:             (*semaphore).path = nom_absolu;
  875:             (*semaphore).pid = getpid();
  876: 
  877:             if ((*semaphore).sem == -1)
  878:             {   
  879:                 free(semaphore);
  880:                 free(nom_absolu);
  881: 
  882:                 return(SEM_FAILED);
  883:             }
  884: 
  885:             argument.val = valeur;
  886:             semctl((*semaphore).sem, 0, SETVAL, argument);
  887: #       else // OS/2
  888: 
  889:         if ((psem = malloc(sizeof(sem_t))) == NULL)
  890:         {
  891:             free(nom_absolu);
  892:             free(nom_segment);
  893: 
  894:             return(SEM_FAILED);
  895:         }
  896: 
  897:         (*ptr) = 'M';
  898: 
  899:         if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
  900:         {
  901:             free(psem);
  902:             free(nom_absolu);
  903:             free(nom_segment);
  904: 
  905:             return(SEM_FAILED);
  906:         }
  907: 
  908:         (*ptr) = 'S';
  909: 
  910:         if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
  911:                 (valeur != 0) ? 1 : 0) != 0)
  912:         {
  913:             DosCloseMutexSem((*psem).hmtx);
  914: 
  915:             free(nom_absolu);
  916:             free(nom_segment);
  917:             free(psem);
  918: 
  919:             return(SEM_FAILED);
  920:         }
  921: 
  922:         if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
  923:                 PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
  924:         {
  925:             DosCloseMutexSem((*psem).hmtx);
  926: 
  927:             free(nom_absolu);
  928:             free(nom_segment);
  929:             free(psem);
  930: 
  931:             return(SEM_FAILED);
  932:         }
  933: 
  934:         free(nom_segment);
  935: 
  936:         (*psem).cnt = (ULONG *) base;
  937:         (*psem).nopened = ((ULONG *) base) + 1;
  938:         (*(*psem).cnt) = valeur;
  939:         (*(*psem).nopened) = 1;
  940:         (*psem).shared = 1;
  941:         semaphore = psem;
  942: 
  943: #       endif
  944:     }
  945: 
  946:     return(semaphore);
  947: }
  948: 
  949: int
  950: sem_close_SysV(sem_t *semaphore)
  951: {
  952:     // Ferme un sémaphore nommé créé par sem_open_SysV()
  953: #   ifndef OS2 // IPCS_SYSV
  954:         if ((*semaphore).path != NULL)
  955:         {
  956:             free((*semaphore).path);
  957:         }
  958: 
  959:         if ((*semaphore).alloue == -1)
  960:         {
  961:             free(semaphore);
  962:         }
  963: 
  964:         return(0);
  965: #   else
  966: 
  967:     sem_t       *psem;
  968: 
  969:     psem = semaphore;
  970: 
  971:     if (DosCloseMutexSem((*psem).hmtx) != 0)
  972:     {
  973:         return(EINVAL);
  974:     }
  975: 
  976:     while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
  977:     {
  978:         DosPostEventSem((*psem).hev);
  979:     }
  980: 
  981:     (*(*psem).nopened)--;
  982: 
  983:     if ((*psem).shared == 0)
  984:     {
  985:         free((*psem).cnt);
  986:         free((*psem).nopened);
  987:     }
  988:     else
  989:     {
  990:         if ((*(*psem).nopened) == 0)
  991:         {
  992:             DosFreeMem((*psem).cnt);
  993:         }
  994:     }
  995: 
  996:     if ((*psem).allocated != 0)
  997:     {
  998:         free(psem);
  999:     }
 1000: 
 1001:     return(0);
 1002: 
 1003: #   endif
 1004: }
 1005: 
 1006: int
 1007: sem_unlink_SysV(const char *nom)
 1008: {
 1009:     // Détruit un sémaphore nommé créé par sem_open_SysV()
 1010: #   ifndef OS2 // IPCS_SYSV
 1011:         semctl(semget(ftok(nom_absolu, 1), 0, 0), 0, IPC_RMID);
 1012: 
 1013:         if (unlink(nom_absolu) == -1)
 1014:         {
 1015:             free(nom_absolu);
 1016:             return(EACCES);
 1017:         }
 1018: 
 1019:         free(nom_absolu);
 1020:         return(0);
 1021: #   else
 1022: 
 1023:     return(0);
 1024: 
 1025: #   endif
 1026: }
 1027: 
 1028: #endif
 1029: 
 1030: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>