Annotation of rpl/src/semaphores.c, revision 1.34

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

CVSweb interface <joel.bertrand@systella.fr>