sem.c 3.4 KB

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