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

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.9       bertrand  211: #ifndef OS2
                    212:    extern unsigned char *chemin_semaphores_SysV;
                    213: #else
                    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: #  ifndef OS2
                    224: 
1.8       bertrand  225:    int             ios;
                    226: 
1.6       bertrand  227:    union semun     argument;
                    228: 
                    229:    if (shared != 0)
                    230:    {
1.9       bertrand  231:        errno = ENOSYS;
                    232:        return(-1);
1.6       bertrand  233:    }
                    234: 
1.11      bertrand  235:    (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL |
                    236:            S_IRUSR | S_IWUSR);
                    237:    (*semaphore).path = NULL;
                    238:    (*semaphore).pid = getpid();
1.6       bertrand  239: 
1.11      bertrand  240:    if ((*semaphore).sem == -1)
1.6       bertrand  241:    {
1.9       bertrand  242:        errno = EINVAL;
                    243:        return(-1);
1.6       bertrand  244:    }
                    245: 
                    246:    argument.val = valeur;
1.11      bertrand  247:    ios = semctl((*semaphore).sem, 0, SETVAL, argument);
1.6       bertrand  248: 
1.8       bertrand  249:    return(ios);
1.9       bertrand  250: 
                    251: #  else
                    252: 
                    253:    sem_t           *psem;
                    254: 
                    255:    psem = semaphore;
                    256: 
                    257:    if (shared != 0)
                    258:    {
                    259:        errno = ENOSYS;
                    260:        return(-1);
                    261:    }
                    262: 
                    263:    if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)
                    264:    {
                    265:        free(psem);
                    266:        errno = ENOMEM;
                    267:        return(-1);
                    268:    }
                    269: 
                    270:    if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)
                    271:    {
                    272:        free((*psem).cnt);
                    273:        free(psem);
                    274:        errno = ENOMEM;
                    275:        return(-1);
                    276:    }
                    277: 
                    278:    if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
                    279:    {
                    280:        free((*psem).cnt);
                    281:        free((*psem).nopened);
                    282:        free(psem);
                    283:        return(-1);
                    284:    }
                    285: 
                    286:    if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0) != 0)
                    287:    {
                    288:        DosCloseMutexSem((*psem).hmtx);
                    289:        free((*psem).cnt);
                    290:        free((*psem).nopened);
                    291:        free(psem);
                    292:        return(-1);
                    293:    }
                    294: 
                    295:    (*(*psem).cnt) = valeur;
                    296:    (*(*psem).nopened) = 1;
                    297:    (*psem).shared = shared;
                    298:    (*psem).allocated = 0;
                    299: 
                    300:    return(0);
                    301: 
                    302: #  endif
1.6       bertrand  303: }
                    304: 
                    305: int
1.8       bertrand  306: sem_destroy_SysV(sem_t *semaphore)
1.6       bertrand  307: {
1.11      bertrand  308:    // Détruit un sémaphore anonmyme
1.9       bertrand  309: #  ifndef OS2
                    310: 
1.11      bertrand  311:    if ((*semaphore).path != NULL)
                    312:    {
                    313:        return(EINVAL);
                    314:    }
                    315: 
                    316:    if ((*semaphore).pid != getpid())
                    317:    {
                    318:        return(0);
                    319:    }
                    320: 
1.12      bertrand  321:    if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
1.6       bertrand  322:    {
                    323:        return(EINVAL);
                    324:    }
                    325: 
                    326:    return(0);
1.9       bertrand  327: 
                    328: #  else
                    329: 
                    330:    sem_t       *psem;
                    331: 
                    332:    psem = semaphore;
                    333: 
                    334:    if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    335:    {
                    336:        return(EINVAL);
                    337:    }
                    338: 
                    339:    if (DosCloseMutexSem((*psem).hmtx) != 0)
                    340:    {
                    341:        return(EINVAL);
                    342:    }
                    343: 
                    344:    while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
                    345:    {
                    346:        DosPostEventSem((*psem).hev);
                    347:    }
                    348: 
                    349:    (*(*psem).nopened)--;
                    350: 
                    351:    if ((*psem).shared == 0)
                    352:    {
                    353:        free((*psem).cnt);
                    354:        free((*psem).nopened);
                    355:    }
                    356:    else
                    357:    {
                    358:        if ((*(*psem).nopened) == 0)
                    359:        {
                    360:            DosFreeMem((*psem).cnt);
                    361:        }
                    362:    }
                    363: 
                    364:    if ((*psem).allocated != 0)
                    365:    {   
                    366:        free(psem);
                    367:    }
                    368: 
                    369:    return(0);
                    370: 
                    371: #  endif
1.6       bertrand  372: }
                    373: 
                    374: int
1.8       bertrand  375: sem_wait_SysV(sem_t *semaphore)
1.6       bertrand  376: {
1.9       bertrand  377: #  ifndef OS2
                    378: 
1.6       bertrand  379:    struct sembuf       commande;
                    380: 
                    381:    commande.sem_num = 0;
                    382:    commande.sem_op = -1;
                    383:    commande.sem_flg = 0;
                    384: 
1.11      bertrand  385:    while(semop((*semaphore).sem, &commande, 1) == -1)
1.6       bertrand  386:    {
1.11      bertrand  387:        if (errno != EINTR)
                    388:        {
                    389:            errno = EINVAL;
                    390:            return(-1);
                    391:        }
1.9       bertrand  392:    }
                    393: 
                    394:    return(0);
                    395: 
                    396: #  else
                    397: 
                    398:    sem_t       *psem;
                    399: 
                    400:    ULONG       cnt;
                    401: 
                    402:    psem = semaphore;
                    403: 
                    404:    if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
                    405:    {
                    406:        errno = EINVAL;
                    407:        return(-1);
                    408:    }
                    409: 
                    410:    if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    411:    {
                    412:        errno = EINVAL;
                    413:        return(-1);
                    414:    }
                    415: 
                    416:    if ((*(*psem).cnt) > 0)
                    417:    {
                    418:        (*(*psem).cnt)--;
                    419:    }
                    420: 
                    421:    if ((*(*psem).cnt) == 0)
                    422:    {
                    423:        DosResetEventSem((*psem).hev, &cnt);
1.6       bertrand  424:    }
                    425: 
1.9       bertrand  426:    DosReleaseMutexSem((*psem).hmtx);
1.6       bertrand  427:    return(0);
1.9       bertrand  428: 
                    429: #  endif
1.6       bertrand  430: }
                    431: 
                    432: int
1.8       bertrand  433: sem_trywait_SysV(sem_t *semaphore)
1.6       bertrand  434: {
1.9       bertrand  435: #  ifndef OS2
                    436: 
1.6       bertrand  437:    struct sembuf       commande;
                    438: 
                    439:    commande.sem_num = 0;
                    440:    commande.sem_op = -1;
                    441:    commande.sem_flg = IPC_NOWAIT;
                    442: 
1.11      bertrand  443:    while(semop((*semaphore).sem, &commande, 1) == -1)
1.6       bertrand  444:    {
1.11      bertrand  445:        if (errno != EINTR)
                    446:        {
                    447:            errno = EINVAL;
                    448:            return(-1);
                    449:        }
1.9       bertrand  450:    }
                    451: 
                    452:    return(0);
                    453: 
                    454: #  else
                    455: 
                    456:    int         ios;
                    457: 
                    458:    sem_t       *psem;
                    459: 
                    460:    ULONG       cnt;
                    461: 
                    462:    psem = semaphore;
                    463: 
                    464:    if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
                    465:    {
                    466:        errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
                    467:        return(-1);
                    468:    }
                    469: 
                    470:    if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    471:    {
                    472:        errno = EINVAL;
                    473:        return(-1);
                    474:    }
                    475: 
                    476:    if ((*(*psem).cnt) > 0)
                    477:    {
                    478:        (*(*psem).cnt)--;
                    479:    }
1.6       bertrand  480: 
1.9       bertrand  481:    if ((*(*psem).cnt) == 0)
                    482:    {
                    483:        DosResetEventSem((*psem).hev, &cnt);
1.6       bertrand  484:    }
                    485: 
1.9       bertrand  486:    DosReleaseMutexSem((*psem).hmtx);
1.6       bertrand  487:    return(0);
1.9       bertrand  488: 
                    489: #  endif
1.6       bertrand  490: }
                    491: 
                    492: int
1.8       bertrand  493: sem_post_SysV(sem_t *semaphore)
1.6       bertrand  494: {
1.9       bertrand  495: #  ifndef OS2
                    496: 
1.6       bertrand  497:    struct sembuf       commande;
                    498: 
                    499:    commande.sem_num = 0;
                    500:    commande.sem_op = 1;
                    501:    commande.sem_flg = 0;
                    502: 
1.11      bertrand  503:    while(semop((*semaphore).sem, &commande, 1) == -1)
1.6       bertrand  504:    {
1.11      bertrand  505:        if (errno != EINTR)
                    506:        {
                    507:            errno = EINVAL;
                    508:            return(-1);
                    509:        }
1.9       bertrand  510:    }
                    511: 
                    512:    return(0);
                    513: 
                    514: #  else
                    515: 
                    516:    sem_t               *psem;
                    517: 
                    518:    psem = semaphore;
                    519: 
                    520:    if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    521:    {
                    522:        errno = EINVAL;
                    523:        return(-1);
1.6       bertrand  524:    }
                    525: 
1.9       bertrand  526:    (*(*psem).cnt)++;
                    527:    DosPostEventSem((*psem).hev);
                    528:    DosReleaseMutexSem((*psem).hmtx);
                    529: 
1.6       bertrand  530:    return(0);
1.9       bertrand  531: 
                    532: #  endif
1.6       bertrand  533: }
                    534: 
                    535: int
1.8       bertrand  536: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
1.6       bertrand  537: {
1.9       bertrand  538: #  ifndef OS2
                    539: 
1.11      bertrand  540:    (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
1.6       bertrand  541: 
                    542:    if ((*valeur) < 0)
                    543:    {
                    544:        return(EINVAL);
                    545:    }
                    546: 
                    547:    return(0);
1.9       bertrand  548: 
                    549: #  else
                    550: 
                    551:    sem_t               *psem;
                    552: 
                    553:    psem = semaphore;
                    554: 
                    555:    if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    556:    {
                    557:        errno = EINVAL;
                    558:        return(-1);
                    559:    }
                    560: 
                    561:    (*valeur) = (*(*psem).cnt);
                    562:    DosReleaseMutexSem((*psem).hmtx);
                    563: 
                    564:    return(0);
                    565: 
                    566: #  endif
1.6       bertrand  567: }
                    568: 
                    569: sem_t
1.8       bertrand  570: *sem_open_SysV(const char *nom, int oflag, ...)
1.6       bertrand  571: //*sem_open(const char *nom, int oflag)
                    572: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
                    573: {
                    574:    mode_t              mode;
                    575: 
                    576:    sem_t               *semaphore;
                    577: 
1.9       bertrand  578: #  ifndef OS2
1.10      bertrand  579:    file                *desc;
                    580: 
                    581:    key_t               clef;
                    582: 
1.6       bertrand  583:    union semun         argument;
1.9       bertrand  584: #  endif
1.6       bertrand  585: 
                    586:    unsigned char       *nom_absolu;
                    587: 
                    588:    unsigned int        valeur;
                    589: 
                    590:    va_list             liste;
                    591: 
1.9       bertrand  592: #  ifdef OS2
                    593:    sem_t               *psem;
                    594: 
                    595:    PVOID               base;
                    596: 
                    597:    unsigned char       *ptr;
                    598:    unsigned char       *nom_segment;
                    599: #  endif
                    600: 
                    601: #  ifndef OS2
                    602: 
1.6       bertrand  603:    if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
                    604:            + 1) * sizeof(unsigned char))) == NULL)
                    605:    {
                    606:        return(SEM_FAILED);
                    607:    }
                    608: 
                    609:    sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
                    610: 
                    611:    if ((semaphore = malloc(sizeof(sem_t))) == NULL)
                    612:    {
                    613:        return(SEM_FAILED);
                    614:    }
                    615: 
1.9       bertrand  616: #  else
                    617: 
                    618:    if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)
                    619:            * sizeof(unsigned char))) == NULL)
                    620:    {
                    621:        return(SEM_FAILED);
                    622:    }   
                    623: 
                    624:    sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
                    625:    ptr = nom_segment;
                    626: 
                    627:    while((*ptr) != d_code_fin_chaine)
                    628:    {
                    629:        if ((*ptr) == '/')
                    630:        {
                    631:            (*ptr) = '\\';
                    632:        }
                    633: 
                    634:        ptr++;
                    635:    }
                    636: 
                    637:    if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom)
                    638:            + 2) * sizeof(unsigned char))) == NULL)
                    639:    {
                    640:        return(SEM_FAILED);
                    641:    }
                    642: 
                    643:    sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);
                    644:    ptr = nom_absolu;
                    645: 
                    646:    while((*ptr) != d_code_fin_chaine)
                    647:    {
                    648:        if ((*ptr) == '/')
                    649:        {
                    650:            (*ptr) = '\\';
                    651:        }
                    652: 
                    653:        ptr++;
                    654:    }
                    655: 
                    656:    (*(ptr + 1)) = d_code_fin_chaine;
                    657: 
                    658:    if ((psem = malloc(sizeof(sem_t))) == NULL)
                    659:    {
                    660:        return(SEM_FAILED);
                    661:    }
                    662: 
1.11      bertrand  663:    (*psem).allocated = 1;
                    664: 
1.9       bertrand  665: #  endif
                    666: 
1.6       bertrand  667:    if ((oflag & O_CREAT) == 0)
                    668:    {
                    669:        // 2 arguments
1.9       bertrand  670: 
                    671: #      ifndef OS2
                    672: 
1.11      bertrand  673:        clef = ftok(nom_absolu, 1);
                    674: 
                    675:        if (clef == -1)
                    676:        {
                    677:            return(SEM_FAILED);
                    678:        }
                    679: 
                    680:        (*semaphore).sem = semget(clef, 0, 0);
                    681:        (*semaphore).path = nom_absolu;
                    682:        (*semaphore).pid = getpid();
1.6       bertrand  683: 
1.11      bertrand  684:        if ((*semaphore).sem == -1)
1.6       bertrand  685:        {   
                    686:            free(semaphore);
                    687:            free(nom_absolu);
                    688: 
                    689:            return(SEM_FAILED);
                    690:        }
1.9       bertrand  691: 
                    692: #      else
                    693: 
                    694:        if ((psem = malloc(sizeof(sem_t))) == NULL)
                    695:        {
                    696:            free(nom_absolu);
                    697:            free(nom_segment);
                    698:            return(SEM_FAILED);
                    699:        }
                    700: 
                    701:        (*ptr) = 'M';
                    702: 
                    703:        if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
                    704:        {
                    705:            free(psem);
                    706:            free(nom_absolu);
                    707:            free(nom_segment);
                    708: 
                    709:            return(SEM_FAILED);
                    710:        }
                    711: 
                    712:        (*ptr) = 'S';
                    713: 
                    714:        if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
                    715:        {
                    716:            DosCloseMutexSem((*psem).hmtx);
                    717: 
                    718:            free(psem);
                    719:            free(nom_absolu);
                    720:            free(nom_segment);
                    721: 
                    722:            return(SEM_FAILED);
                    723:        }
                    724: 
                    725:        if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ) != 0)
                    726:        {
                    727:            DosCloseMutexSem((*psem).hmtx);
                    728: 
                    729:            free(nom_absolu);
                    730:            free(nom_segment);
                    731:            free(psem);
                    732: 
                    733:            return(SEM_FAILED);
                    734:        }
                    735: 
                    736:        free(nom_segment);
                    737: 
                    738:        (*psem).cnt = (ULONG *) base;
                    739:        (*psem).nopened = ((ULONG *) base) + 1;
                    740:        (*psem).shared = 1;
                    741: 
                    742:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    743:        {
                    744:            DosCloseMutexSem((*psem).hmtx);
                    745: 
                    746:            free(nom_absolu);
                    747:            free(nom_segment);
                    748:            free(psem);
                    749: 
                    750:            return(SEM_FAILED);
                    751:        }
                    752: 
                    753:        (*((*psem).nopened))++;
                    754: 
                    755:        DosReleaseMutexSem((*psem).hmtx);
                    756: 
                    757:        semaphore = psem;
                    758: 
                    759: #      endif
1.6       bertrand  760:    }
                    761:    else
                    762:    {
                    763:        // 4 arguments
                    764: 
                    765:        // O_CREAT O_EXCL
                    766:        // S_IRUSR S_IWUSR
                    767: 
                    768:        va_start(liste, oflag);
                    769:        mode = va_arg(liste, mode_t);
                    770:        valeur = va_arg(liste, unsigned int);
                    771:        va_end(liste);
                    772: 
1.9       bertrand  773: #      ifndef OS2
                    774: 
1.10      bertrand  775:        if ((desc = fopen(nom_absolu, "w")) == NULL)
                    776:        {
                    777:            free(semaphore);
                    778:            free(nom_absolu);
                    779: 
                    780:            return(SEM_FAILED);
                    781:        }
                    782: 
                    783:        fclose(desc);
                    784: 
                    785:        if ((clef = ftok(nom_absolu, 1)) == -1)
                    786:        {
                    787:            free(semaphore);
                    788:            free(nom_absolu);
                    789: 
                    790:            return(SEM_FAILED);
                    791:        }
                    792: 
1.11      bertrand  793:        (*semaphore).sem = semget(clef, 1,
                    794:                (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |
                    795:                (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |
                    796:                (int) mode);
                    797:        (*semaphore).path = nom_absolu;
                    798:        (*semaphore).pid = getpid();
1.6       bertrand  799: 
1.11      bertrand  800:        if ((*semaphore).sem == -1)
1.6       bertrand  801:        {   
                    802:            free(semaphore);
                    803:            free(nom_absolu);
                    804: 
                    805:            return(SEM_FAILED);
                    806:        }
                    807: 
                    808:        argument.val = valeur;
1.11      bertrand  809:        semctl((*semaphore).sem, 0, SETVAL, argument);
1.9       bertrand  810: 
                    811: #      else
                    812: 
                    813:        if ((psem = malloc(sizeof(sem_t))) == NULL)
                    814:        {
                    815:            free(nom_absolu);
                    816:            free(nom_segment);
                    817: 
                    818:            return(SEM_FAILED);
                    819:        }
                    820: 
                    821:        (*ptr) = 'M';
                    822: 
                    823:        if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
                    824:        {
                    825:            free(psem);
                    826:            free(nom_absolu);
                    827:            free(nom_segment);
                    828: 
                    829:            return(SEM_FAILED);
                    830:        }
                    831: 
                    832:        (*ptr) = 'S';
                    833: 
                    834:        if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
                    835:                (valeur != 0) ? 1 : 0) != 0)
                    836:        {
                    837:            DosCloseMutexSem((*psem).hmtx);
                    838: 
                    839:            free(nom_absolu);
                    840:            free(nom_segment);
                    841:            free(psem);
                    842: 
                    843:            return(SEM_FAILED);
                    844:        }
                    845: 
                    846:        if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
                    847:                PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
                    848:        {
                    849:            DosCloseMutexSem((*psem).hmtx);
                    850: 
                    851:            free(nom_absolu);
                    852:            free(nom_segment);
                    853:            free(psem);
                    854: 
                    855:            return(SEM_FAILED);
                    856:        }
                    857: 
                    858:        free(nom_segment);
                    859: 
                    860:        (*psem).cnt = (ULONG *) base;
                    861:        (*psem).nopened = ((ULONG *) base) + 1;
                    862:        (*(*psem).cnt) = valeur;
                    863:        (*(*psem).nopened) = 1;
                    864:        (*psem).shared = 1;
                    865:        semaphore = psem;
                    866: 
                    867: #      endif
1.6       bertrand  868:    }
                    869: 
1.8       bertrand  870:    return(semaphore);
1.6       bertrand  871: }
                    872: 
                    873: int
1.8       bertrand  874: sem_close_SysV(sem_t *semaphore)
1.6       bertrand  875: {
1.11      bertrand  876:    // Ferme un sémaphore nommé créé par sem_open_SysV()
1.9       bertrand  877: #  ifndef OS2
                    878: 
1.11      bertrand  879:    if ((*semaphore).path != NULL)
                    880:    {
                    881:        free((*semaphore).path);
                    882:    }
                    883: 
1.6       bertrand  884:    free(semaphore);
                    885:    return(0);
1.9       bertrand  886: 
                    887: #  else
                    888: 
                    889:    sem_t       *psem;
                    890: 
                    891:    psem = semaphore;
                    892: 
                    893:    if (DosCloseMutexSem((*psem).hmtx) != 0)
                    894:    {
                    895:        return(EINVAL);
                    896:    }
                    897: 
                    898:    while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
                    899:    {
                    900:        DosPostEventSem((*psem).hev);
                    901:    }
                    902: 
                    903:    (*(*psem).nopened)--;
                    904: 
                    905:    if ((*psem).shared == 0)
                    906:    {
                    907:        free((*psem).cnt);
                    908:        free((*psem).nopened);
                    909:    }
                    910:    else
                    911:    {
                    912:        if ((*(*psem).nopened) == 0)
                    913:        {
                    914:            DosFreeMem((*psem).cnt);
                    915:        }
                    916:    }
                    917: 
                    918:    if ((*psem).allocated != 0)
                    919:    {
                    920:        free(psem);
                    921:    }
                    922: 
                    923:    return(0);
                    924: 
                    925: #  endif
1.6       bertrand  926: }
                    927: 
                    928: int
1.8       bertrand  929: sem_unlink_SysV(const char *nom)
1.6       bertrand  930: {
1.11      bertrand  931:    // Détruit un sémaphore nommé créé par sem_open_SysV()
1.9       bertrand  932: #  ifndef OS2
                    933: 
1.6       bertrand  934:    unsigned char       *nom_absolu;
                    935: 
                    936:    if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
                    937:            + 1) * sizeof(unsigned char))) == NULL)
                    938:    {
                    939:        return(ENOMEM);
                    940:    }
                    941: 
                    942:    sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
1.12      bertrand  943:    semctl(semget(ftok(nom_absolu, 1), 0, 0), 0, IPC_RMID);
1.6       bertrand  944: 
                    945:    if (unlink(nom_absolu) == -1)
                    946:    {
                    947:        free(nom_absolu);
                    948:        return(EACCES);
                    949:    }
                    950: 
                    951:    free(nom_absolu);
                    952: 
                    953:    return(0);
1.9       bertrand  954: 
                    955: #  else
                    956: 
                    957:    return(0);
                    958: 
                    959: #  endif
1.6       bertrand  960: }
                    961: 
                    962: #endif
                    963: 
1.1       bertrand  964: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>