--- rpl/src/semaphores.c 2010/04/17 18:57:36 1.1 +++ rpl/src/semaphores.c 2010/08/09 13:51:48 1.8 @@ -1,6 +1,6 @@ /* ================================================================================ - RPL/2 (R) version 4.0.14 + RPL/2 (R) version 4.0.18 Copyright (C) 1989-2010 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,9 +20,9 @@ */ -#ifdef SEMAPHORES_NOMMES -#include "rpl.conv.h" +#include "rpl-conv.h" +#ifdef SEMAPHORES_NOMMES /* ================================================================================ @@ -105,6 +105,274 @@ sem_getvalue2(sem_t *semaphore, int *val return(0); } +#endif + +#ifdef SEMAPHORES_SYSV + +/* +================================================================================ + Fonctions d'émulation de sémaphores POSIX en fonction des sémaphores SysV +================================================================================ + Entrées : +-------------------------------------------------------------------------------- + Sorties : +-------------------------------------------------------------------------------- + Effets de bord : néant +================================================================================ +*/ + +extern unsigned char *chemin_semaphores_SysV; + +#ifndef UNION_SEMUN +union semun +{ + int val; + struct semid_ds *buf; + unsigned short *array; + struct seminfo *__buf; +}; +#endif + +int +sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur) +{ + int ios; + + union semun argument; + + if (shared != 0) + { + return(ENOSYS); + } + + (*semaphore) = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | SEM_R | SEM_A); + + if ((*semaphore) == -1) + { + return(EINVAL); + } + + argument.val = valeur; + ios = semctl((*semaphore), 0, SETVAL, argument); + + return(ios); +} + +int +sem_destroy_SysV(sem_t *semaphore) +{ + if (semctl((*semaphore), IPC_RMID, 0) == -1) + { + return(EINVAL); + } + + return(0); +} + +int +sem_wait_SysV(sem_t *semaphore) +{ + struct sembuf commande; + + commande.sem_num = 0; + commande.sem_op = -1; + commande.sem_flg = 0; + + if (semop((*semaphore), &commande, 1) == -1) + { + return(EINVAL); + } + + return(0); +} + +int +sem_trywait_SysV(sem_t *semaphore) +{ + struct sembuf commande; + + commande.sem_num = 0; + commande.sem_op = -1; + commande.sem_flg = IPC_NOWAIT; + + if (semop((*semaphore), &commande, 1) == -1) + { + if (errno == EAGAIN) + { + return(EAGAIN); + } + + return(EINVAL); + } + + return(0); +} + +int +sem_post_SysV(sem_t *semaphore) +{ + struct sembuf commande; + + commande.sem_num = 0; + commande.sem_op = 1; + commande.sem_flg = 0; + + if (semop((*semaphore), &commande, 1) == -1) + { + return(EINVAL); + } + + return(0); +} + +int +sem_getvalue_SysV(sem_t *semaphore, int *valeur) +{ + (*valeur) = semctl((*semaphore), 0, GETVAL); + + if ((*valeur) < 0) + { + return(EINVAL); + } + + return(0); +} + +sem_t +*sem_open_SysV(const char *nom, int oflag, ...) +//*sem_open(const char *nom, int oflag) +//*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value) +{ + mode_t mode; + + sem_t *semaphore; + + union semun argument; + + unsigned char *nom_absolu; + + unsigned int valeur; + + va_list liste; + + if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom) + + 1) * sizeof(unsigned char))) == NULL) + { + return(SEM_FAILED); + } + + sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom); + + if ((semaphore = malloc(sizeof(sem_t))) == NULL) + { + return(SEM_FAILED); + } + + if ((oflag & O_CREAT) == 0) + { + // 2 arguments + (*semaphore) = semget(ftok(nom_absolu, 1), 0, 0); + + if ((*semaphore) == -1) + { + free(semaphore); + free(nom_absolu); + + return(SEM_FAILED); + } + } + else + { + // 4 arguments + + // O_CREAT O_EXCL + // S_IRUSR S_IWUSR + + va_start(liste, oflag); + mode = va_arg(liste, mode_t); + valeur = va_arg(liste, unsigned int); + va_end(liste); + + (*semaphore) = semget(ftok(nom_absolu, 1), 1, + ((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT | + ((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL | + ((oflag & S_IRUSR) == 0) ? 0 : SEM_R | + ((oflag & S_IWUSR) == 0) ? 0 : SEM_A); + + if ((*semaphore) == -1) + { + free(semaphore); + free(nom_absolu); + + return(SEM_FAILED); + } + + argument.val = valeur; + semctl((*semaphore), 0, SETVAL, argument); + } + + free(nom_absolu); + + return(semaphore); +} + +int +sem_close_SysV(sem_t *semaphore) +{ + free(semaphore); + return(0); +} + +int +sem_unlink_SysV(const char *nom) +{ + sem_t semaphore; + + struct sembuf commande; + + unsigned char *nom_absolu; + + if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom) + + 1) * sizeof(unsigned char))) == NULL) + { + return(ENOMEM); + } + + sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom); + + if ((semaphore = semget(ftok(nom_absolu, 1), 0, 0)) == -1) + { + free(nom_absolu); + return(EINVAL); + } + + commande.sem_num = 0; + commande.sem_op = 0; + commande.sem_flg = 0; + + if (semop(semaphore, &commande, 1) == -1) + { + free(nom_absolu); + return(EINVAL); + } + + if (semctl(semaphore, IPC_RMID, 0) == -1) + { + free(nom_absolu); + return(EINVAL); + } + + if (unlink(nom_absolu) == -1) + { + free(nom_absolu); + return(EACCES); + } + + free(nom_absolu); + + return(0); +} + #endif // vim: ts=4