#define _XOPEN_SOURCE #include #include #include /* Constante option */ #include #include "error.h" #include "sem.h" /* --- Extern --- */ extern int errno; /* --- Fonctions privées --- */ /** * Initialise les semaphores * @param semaphore* Le tableau de semaphore * @param int La taille du tableau * @param int* Valeur à initialiser * @return boolean Reussite */ boolean ini_sem(semaphore* sem, int size, int* iniVal) { /* Initialisation des valeurs */ for(int i = 0; i < size; i++){ if(semctl(sem->id, i, SETVAL, iniVal[i]) == ERR){ addperror("Impossible d'initialiser le tableau de semaphore"); return false; } } /* Retour */ return true; } /* --- Fonctions publiques --- */ boolean create_sem(semaphore* sem, int code, int nb, int* iniVal) { int id; /* Création du tableau */ key_t key = ftok(IPCKEYPATH, code); if(key == ERR){ addperror("Impossible de générer la clef"); return false; } id = semget(key, nb, S_IRUSR | S_IWUSR | IPC_CREAT | IPC_EXCL); if (id == ERR) { /* Si le tableau existe deja */ if (errno == EEXIST) { adderror("Le tableau de sémaphore existe deja, tentaive de récupération"); return get_sem(sem, code); } /* Sinon erreur */ addperror("Impossible de créer le tableau de sémaphore"); return false; } /* Paramétrage de la structure */ sem->id = id; sem->key = key; sem->nb = nb; /* Initialise semaphore */ return ini_sem(sem, nb, iniVal); } boolean get_sem(semaphore* sem, int code) { int id; struct semid_ds sem_buf; /* Création du tableau */ key_t key = ftok(IPCKEYPATH, code); if(key == ERR){ addperror("Impossible de générer la clef"); return false; } id = semget(key, 0, S_IRUSR | S_IWUSR); if (id == ERR) { /* Sinon erreur */ addperror("Impossible de récupèrer le tableau de sémaphore"); return false; } /* Récupération du nombre de semaphore */ if (semctl(id, 0, IPC_STAT, &sem_buf) == ERR) { addperror("Impossible de récupèrer les informations du tableau de sémaphore"); return false; } /* Paramétrage de la structure */ sem->id = id; sem->key = key; sem->nb = sem_buf.sem_nsems; /* Retour */ return true; } boolean P(semaphore* sem, int num) { struct sembuf action; /* Le num valide */ if (num < 0 || num > (sem->nb - 1)) { adderror("Index tableau semaphore invalide"); return false; } /* Parametre sembuf */ action.sem_num = num; action.sem_op = -1; /* Puis je */ if (semop(sem->id, &action, 1) == ERR) { addperror("Impossible d'effectuer P"); return false; } return true; } boolean V(semaphore* sem, int num) { struct sembuf action; /* Le num valide */ if (num < 0 || num > (sem->nb - 1)) { adderror("Index tableau semaphore invalide"); return false; } /* Parametre sembuf */ action.sem_num = num; action.sem_op = 1; /* Vas y */ if (semop(sem->id, &action, 1) == ERR) { addperror("Impossible d'effectuer V"); return false; } return true; } boolean delete_sem(semaphore* sem) { /* Suppr */ if (semctl(sem->id, 0, IPC_RMID) == ERR) { addperror("Impossible de supprimer le tableau de semaphore"); return false; } /* Reset struct */ sem->id = 0; sem->key = 0; sem->nb = 0; return true; } int get_sem_value(semaphore* sem, int num){ return semctl(sem->id, num, GETVAL); }