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

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

CVSweb interface <joel.bertrand@systella.fr>