File:  [local] / rpl / src / semaphores.c
Revision 1.76: download - view: text, annotated - select for diffs - revision graph
Tue Mar 22 09:22:23 2016 UTC (8 years, 1 month ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Test de l'existence des fichiers pour les sémaphores et les segments de mémoire
partagée.

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

CVSweb interface <joel.bertrand@systella.fr>