sem.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #define _XOPEN_SOURCE
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <sys/stat.h> /* Constante option */
  5. #include <errno.h>
  6. #include "error.h"
  7. #include "sem.h"
  8. /* --- Extern --- */
  9. extern int errno;
  10. /* --- Fonctions privées --- */
  11. /**
  12. * Initialise les semaphores
  13. * @param semaphore* Le tableau de semaphore
  14. * @param int* Valeur à initialiser
  15. * @return boolean Reussite
  16. */
  17. boolean ini_sem(semaphore* sem, int* iniVal) {
  18. /* Initialisation des valeurs */
  19. if (semctl(sem->id, 0, SETALL, iniVal) == ERR) {
  20. addperror("Impossible d'initialiser le tableau de semaphore");
  21. return false;
  22. }
  23. /* Retour */
  24. return true;
  25. }
  26. /* --- Fonctions publiques --- */
  27. boolean create_sem(semaphore* sem, int code, int nb, int* iniVal) {
  28. int id;
  29. /* Création du tableau */
  30. key_t key = ftok(IPCKEYPATH, code);
  31. if(key == ERR){
  32. addperror("Impossible de générer la clef");
  33. return false;
  34. }
  35. id = semget(key, nb, S_IRUSR | S_IWUSR | IPC_CREAT | IPC_EXCL);
  36. if (id == ERR) {
  37. /* Si le tableau existe deja */
  38. if (errno == EEXIST) {
  39. adderror("Le tableau de sémaphore existe deja, tentaive de récupération");
  40. return get_sem(sem, code);
  41. }
  42. /* Sinon erreur */
  43. addperror("Impossible de créer le tableau de sémaphore");
  44. return false;
  45. }
  46. /* Paramétrage de la structure */
  47. sem->id = id;
  48. sem->key = key;
  49. sem->nb = nb;
  50. /* Initialise semaphore */
  51. return ini_sem(sem, iniVal);
  52. }
  53. boolean get_sem(semaphore* sem, int code) {
  54. int id;
  55. struct semid_ds sem_buf;
  56. /* Création du tableau */
  57. key_t key = ftok(IPCKEYPATH, code);
  58. if(key == ERR){
  59. addperror("Impossible de générer la clef");
  60. return false;
  61. }
  62. id = semget(key, 0, S_IRUSR | S_IWUSR);
  63. if (id == ERR) {
  64. /* Sinon erreur */
  65. addperror("Impossible de récupèrer le tableau de sémaphore");
  66. return false;
  67. }
  68. /* Récupération du nombre de semaphore */
  69. if (semctl(id, 0, IPC_STAT, &sem_buf) == ERR) {
  70. addperror("Impossible de récupèrer les informations du tableau de sémaphore");
  71. return false;
  72. }
  73. /* Paramétrage de la structure */
  74. sem->id = id;
  75. sem->key = key;
  76. sem->nb = sem_buf.sem_nsems;
  77. /* Retour */
  78. return true;
  79. }
  80. boolean P(semaphore* sem, int num) {
  81. struct sembuf action;
  82. /* Le num valide */
  83. if (num < 0 || num > (sem->nb - 1)) {
  84. adderror("Index tableau semaphore invalide");
  85. return false;
  86. }
  87. /* Parametre sembuf */
  88. action.sem_num = num;
  89. action.sem_op = -1;
  90. /* Puis je */
  91. if (semop(sem->id, &action, 1) == ERR) {
  92. addperror("Impossible d'effectuer P");
  93. return false;
  94. }
  95. return true;
  96. }
  97. boolean V(semaphore* sem, int num) {
  98. struct sembuf action;
  99. /* Le num valide */
  100. if (num < 0 || num > (sem->nb - 1)) {
  101. adderror("Index tableau semaphore invalide");
  102. return false;
  103. }
  104. /* Parametre sembuf */
  105. action.sem_num = num;
  106. action.sem_op = 1;
  107. /* Vas y */
  108. if (semop(sem->id, &action, 1) == ERR) {
  109. addperror("Impossible d'effectuer V");
  110. return false;
  111. }
  112. return true;
  113. }
  114. boolean delete_sem(semaphore* sem) {
  115. /* Suppr */
  116. if (semctl(sem->id, 0, IPC_RMID) == ERR) {
  117. addperror("Impossible de supprimer le tableau de semaphore");
  118. return false;
  119. }
  120. /* Reset struct */
  121. sem->id = 0;
  122. sem->key = 0;
  123. sem->nb = 0;
  124. return true;
  125. }