|
@@ -0,0 +1,126 @@
|
|
|
+/*
|
|
|
+ * File: shm.c
|
|
|
+ * Author: Arthur Brandao
|
|
|
+ *
|
|
|
+ * Created on 21 décembre 2018
|
|
|
+ */
|
|
|
+
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <sys/stat.h> /* Constante option */
|
|
|
+#include <errno.h>
|
|
|
+#include "error.h"
|
|
|
+#include "shm.h"
|
|
|
+
|
|
|
+/* --- Extern --- */
|
|
|
+extern int errno;
|
|
|
+
|
|
|
+/* --- Fonctions prviées --- */
|
|
|
+
|
|
|
+/**
|
|
|
+ * Indique si il reste des processus utilsant le segment
|
|
|
+ * @param shared_mem* La mémoire partagée
|
|
|
+ * @return Peut ont supprimer ou non
|
|
|
+ */
|
|
|
+boolean can_delete_shm(shared_mem* shm){
|
|
|
+ struct shmid_ds buf;
|
|
|
+ /* Recup les infos de la mémoire */
|
|
|
+ if (shmctl(shm->id, IPC_STAT, &buf) == ERR) {
|
|
|
+ addperror("Impossible de récupérer les données du segment");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ /* Verifie qu'il n'y a plus d'utilisateur actif */
|
|
|
+ return buf.shm_nattch == 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* --- Fonctions publiques --- */
|
|
|
+boolean create_shm(shared_mem* shm, int code, int size) {
|
|
|
+ int id;
|
|
|
+ void* adr;
|
|
|
+ /* Création de la shm */
|
|
|
+ key_t key = ftok(IPCKEYPATH, code);
|
|
|
+ if (key == ERR) {
|
|
|
+ addperror("Impossible de générer la clef");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ id = shmget(key, size, S_IRUSR | S_IWUSR | IPC_CREAT | IPC_EXCL);
|
|
|
+ if (id == ERR) {
|
|
|
+ /* Si erreur existe deja appel get_shm */
|
|
|
+ if (errno == EEXIST) {
|
|
|
+ adderror("Le segment existe deja, tentative de récupération");
|
|
|
+ return get_shm(shm, code, size);
|
|
|
+ } else {
|
|
|
+ addperror("Impossible de créer la mémoire partagée");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* On attache */
|
|
|
+ adr = shmat(id, NULL, 0);
|
|
|
+ if (adr == (void*) ERR) {
|
|
|
+ addperror("Impossible d'attacher le segment");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ /* Initialisation de la structure */
|
|
|
+ shm->id = id;
|
|
|
+ shm->key = key;
|
|
|
+ shm->size = size;
|
|
|
+ shm->adr = adr;
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+boolean get_shm(shared_mem* shm, int code, int size) {
|
|
|
+ int id;
|
|
|
+ void* adr;
|
|
|
+ /* Création de la shm */
|
|
|
+ key_t key = ftok(IPCKEYPATH, code);
|
|
|
+ if (key == ERR) {
|
|
|
+ addperror("Impossible de générer la clef");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ id = shmget(key, size, S_IRUSR | S_IWUSR);
|
|
|
+ if (id == ERR) {
|
|
|
+ addperror("Impossible de récupérer la mémoire partagée");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ /* On attache */
|
|
|
+ adr = shmat(id, NULL, 0);
|
|
|
+ if (adr == (void*) ERR) {
|
|
|
+ addperror("Impossible d'attacher le segment");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ /* Initialisation de la structure */
|
|
|
+ shm->id = id;
|
|
|
+ shm->key = key;
|
|
|
+ shm->size = size;
|
|
|
+ shm->adr = adr;
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+boolean unset_shm(shared_mem* shm){
|
|
|
+ /* On détache la shm */
|
|
|
+ if(shmdt(shm->adr) == ERR){
|
|
|
+ perror("Erreur lors du détachement de la mémoire ");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ shm->adr = NULL;
|
|
|
+ shm->size = 0;
|
|
|
+ /* Retour */
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+boolean delete_shm(shared_mem* shm) {
|
|
|
+ /* Regarde si on peut supprimer */
|
|
|
+ if(!can_delete_shm(shm)){
|
|
|
+ adderror("Des processus utilise encore le segment");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ /* Supprime */
|
|
|
+ if (shmctl(shm->id, IPC_RMID, 0) == ERR) {
|
|
|
+ addperror("Impossible de supprimer le segment");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ /* Reset la structure */
|
|
|
+ shm->id = 0;
|
|
|
+ shm->key = 0;
|
|
|
+ return true;
|
|
|
+}
|