123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- /*
- * 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 utilisent 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;
- }
|