File:  [local] / rpl / src / semaphores.c
Revision 1.39: download - view: text, annotated - select for diffs - revision graph
Mon Oct 10 10:58:12 2011 UTC (12 years, 6 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_4, HEAD
Toute une série de patches pour OS/2 et eComStation.

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

CVSweb interface <joel.bertrand@systella.fr>