shm.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * File: shm.c
  3. * Author: Arthur Brandao
  4. *
  5. * Created on 21 décembre 2018
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <sys/stat.h> /* Constante option */
  10. #include <errno.h>
  11. #include "error.h"
  12. #include "shm.h"
  13. /* --- Extern --- */
  14. extern int errno;
  15. /* --- Fonctions prviées --- */
  16. /**
  17. * Indique si il reste des processus utilsant le segment
  18. * @param shared_mem* La mémoire partagée
  19. * @return Peut ont supprimer ou non
  20. */
  21. boolean can_delete_shm(shared_mem* shm){
  22. struct shmid_ds buf;
  23. /* Recup les infos de la mémoire */
  24. if (shmctl(shm->id, IPC_STAT, &buf) == ERR) {
  25. addperror("Impossible de récupérer les données du segment");
  26. return false;
  27. }
  28. /* Verifie qu'il n'y a plus d'utilisateur actif */
  29. return buf.shm_nattch == 0;
  30. }
  31. /* --- Fonctions publiques --- */
  32. boolean create_shm(shared_mem* shm, int code, int size) {
  33. int id;
  34. void* adr;
  35. /* Création de la shm */
  36. key_t key = ftok(IPCKEYPATH, code);
  37. if (key == ERR) {
  38. addperror("Impossible de générer la clef");
  39. return false;
  40. }
  41. id = shmget(key, size, S_IRUSR | S_IWUSR | IPC_CREAT | IPC_EXCL);
  42. if (id == ERR) {
  43. /* Si erreur existe deja appel get_shm */
  44. if (errno == EEXIST) {
  45. adderror("Le segment existe deja, tentative de récupération");
  46. return get_shm(shm, code, size);
  47. } else {
  48. addperror("Impossible de créer la mémoire partagée");
  49. return false;
  50. }
  51. }
  52. /* On attache */
  53. adr = shmat(id, NULL, 0);
  54. if (adr == (void*) ERR) {
  55. addperror("Impossible d'attacher le segment");
  56. return false;
  57. }
  58. /* Initialisation de la structure */
  59. shm->id = id;
  60. shm->key = key;
  61. shm->size = size;
  62. shm->adr = adr;
  63. return true;
  64. }
  65. boolean get_shm(shared_mem* shm, int code, int size) {
  66. int id;
  67. void* adr;
  68. /* Création de la shm */
  69. key_t key = ftok(IPCKEYPATH, code);
  70. if (key == ERR) {
  71. addperror("Impossible de générer la clef");
  72. return false;
  73. }
  74. id = shmget(key, size, S_IRUSR | S_IWUSR);
  75. if (id == ERR) {
  76. addperror("Impossible de récupérer la mémoire partagée");
  77. return false;
  78. }
  79. /* On attache */
  80. adr = shmat(id, NULL, 0);
  81. if (adr == (void*) ERR) {
  82. addperror("Impossible d'attacher le segment");
  83. return false;
  84. }
  85. /* Initialisation de la structure */
  86. shm->id = id;
  87. shm->key = key;
  88. shm->size = size;
  89. shm->adr = adr;
  90. return true;
  91. }
  92. boolean unset_shm(shared_mem* shm){
  93. /* On détache la shm */
  94. if(shmdt(shm->adr) == ERR){
  95. perror("Erreur lors du détachement de la mémoire ");
  96. return false;
  97. }
  98. shm->adr = NULL;
  99. shm->size = 0;
  100. /* Retour */
  101. return true;
  102. }
  103. boolean delete_shm(shared_mem* shm) {
  104. /* Regarde si on peut supprimer */
  105. if(!can_delete_shm(shm)){
  106. adderror("Des processus utilisent encore le segment");
  107. return false;
  108. }
  109. /* Supprime */
  110. if (shmctl(shm->id, IPC_RMID, 0) == ERR) {
  111. addperror("Impossible de supprimer le segment");
  112. return false;
  113. }
  114. /* Reset la structure */
  115. shm->id = 0;
  116. shm->key = 0;
  117. return true;
  118. }