|
@@ -0,0 +1,115 @@
|
|
|
+#define _XOPEN_SOURCE
|
|
|
+
|
|
|
+#include <stdlib.h>
|
|
|
+#include <stdio.h>
|
|
|
+#include <sys/stat.h> /* Constante option */
|
|
|
+#include <errno.h>
|
|
|
+#include "error.h"
|
|
|
+#include "sem.h"
|
|
|
+
|
|
|
+boolean create_sem(semaphore* sem, int code, int nb) {
|
|
|
+ int id;
|
|
|
+ extern int errno;
|
|
|
+ /* Création du tableau */
|
|
|
+ key_t key = ftok(SEMKEYPATH, code);
|
|
|
+ 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;
|
|
|
+ /* Retour */
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+boolean get_sem(semaphore* sem, int code) {
|
|
|
+ int id;
|
|
|
+ struct semid_ds sem_buf;
|
|
|
+ /* Création du tableau */
|
|
|
+ key_t key = ftok(SEMKEYPATH, code);
|
|
|
+ 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 ini_sem(semaphore* sem, int* iniVal) {
|
|
|
+ /* Initialisation des valeurs */
|
|
|
+ if (semctl(sem->id, 0, SETALL, iniVal) == ERR) {
|
|
|
+ addperror("Impossible d'initialiser le tableau de semaphore");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ /* 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;
|
|
|
+}
|