/* ================================================================================ RPL/2 (R) version 4.0.18 Copyright (C) 1989-2010 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" #ifdef SEMAPHORES_NOMMES /* ================================================================================ Fonctions d'émulation de sémaphores anonymes ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ sem_t * sem_init2(unsigned int valeur, enum t_semaphore semaphore) { snprintf(noms_semaphores[semaphore], LONGUEUR_NOM_SEMAPHORE, "/RPLSEM-%d-%llu-%d", (int) getpid(), (unsigned long long) pthread_self(), (int) semaphore); return(sem_open(noms_semaphores[semaphore], O_CREAT, (S_IRUSR | S_IWUSR), valeur)); } int sem_destroy2(sem_t *semaphore_p, enum t_semaphore semaphore) { sem_close(semaphore_p); return(sem_unlink(noms_semaphores[semaphore])); } #undef sem_post #undef sem_wait #undef sem_trywait int sem_getvalue2(sem_t *semaphore, int *valeur) { int i; logical1 drapeau_fin; pthread_mutex_lock(&mutex_sem); (*valeur) = 0; drapeau_fin = d_faux; do { if (sem_trywait(semaphore) == -1) { if (errno == EAGAIN) { // Le sémaphore avait une valeur nulle drapeau_fin = d_vrai; } else { // Autre erreur pthread_mutex_unlock(&mutex_sem); return(-1); } } else { (*valeur)++; } } while(drapeau_fin == d_faux); for(i = 0; i < (*valeur); i++) { if (sem_post(semaphore) != 0) { pthread_mutex_unlock(&mutex_sem); return(-1); } } pthread_mutex_unlock(&mutex_sem); return(0); } #endif #ifdef OS2 /* ================================================================================ 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; int sem_init(sem_t *semaphore, int shared, unsigned int valeur) { 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; semctl((*semaphore), 0, SETVAL, argument); return(0); } int sem_destroy(sem_t *semaphore) { if (semctl((*semaphore), IPC_RMID, 0) == -1) { return(EINVAL); } return(0); } int sem_wait(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(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(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(sem_t *semaphore, int *valeur) { (*valeur) = semctl((*semaphore), 0, GETVAL); if ((*valeur) < 0) { return(EINVAL); } return(0); } sem_t *sem_open(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(SEM_FAILED); } int sem_close(sem_t *semaphore) { free(semaphore); return(0); } int sem_unlink(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