File:  [local] / rpl / src / semaphores.c
Revision 1.47: download - view: text, annotated - select for diffs - revision graph
Tue Jul 3 13:56:32 2012 UTC (11 years, 10 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Patches pour NetBSD et les IPC SysV.

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

CVSweb interface <joel.bertrand@systella.fr>