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

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

CVSweb interface <joel.bertrand@systella.fr>