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

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

CVSweb interface <joel.bertrand@systella.fr>