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

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

CVSweb interface <joel.bertrand@systella.fr>