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

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

CVSweb interface <joel.bertrand@systella.fr>