File:  [local] / rpl / src / semaphores.c
Revision 1.51: download - view: text, annotated - select for diffs - revision graph
Tue Dec 18 13:19:40 2012 UTC (11 years, 4 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
En route pour la 4.1.12 !

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

CVSweb interface <joel.bertrand@systella.fr>