1: /*
2: ================================================================================
3: RPL/2 (R) version 4.0.18
4: Copyright (C) 1989-2010 Dr. BERTRAND Joël
5:
6: This file is part of RPL/2.
7:
8: RPL/2 is free software; you can redistribute it and/or modify it
9: under the terms of the CeCILL V2 License as published by the french
10: CEA, CNRS and INRIA.
11:
12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
15: for more details.
16:
17: You should have received a copy of the CeCILL License
18: along with RPL/2. If not, write to info@cecill.info.
19: ================================================================================
20: */
21:
22:
23: #include "rpl-conv.h"
24:
25: #ifdef SEMAPHORES_NOMMES
26:
27: /*
28: ================================================================================
29: Fonctions d'émulation de sémaphores anonymes
30: ================================================================================
31: Entrées :
32: --------------------------------------------------------------------------------
33: Sorties :
34: --------------------------------------------------------------------------------
35: Effets de bord : néant
36: ================================================================================
37: */
38:
39: sem_t *
40: sem_init2(unsigned int valeur, enum t_semaphore semaphore)
41: {
42: snprintf(noms_semaphores[semaphore], LONGUEUR_NOM_SEMAPHORE,
43: "/RPLSEM-%d-%llu-%d", (int) getpid(),
44: (unsigned long long) pthread_self(),
45: (int) semaphore);
46: return(sem_open(noms_semaphores[semaphore], O_CREAT,
47: (S_IRUSR | S_IWUSR), valeur));
48: }
49:
50: int
51: sem_destroy2(sem_t *semaphore_p, enum t_semaphore semaphore)
52: {
53: sem_close(semaphore_p);
54: return(sem_unlink(noms_semaphores[semaphore]));
55: }
56:
57: #undef sem_post
58: #undef sem_wait
59: #undef sem_trywait
60:
61: int
62: sem_getvalue2(sem_t *semaphore, int *valeur)
63: {
64: int i;
65:
66: logical1 drapeau_fin;
67:
68: pthread_mutex_lock(&mutex_sem);
69:
70: (*valeur) = 0;
71: drapeau_fin = d_faux;
72:
73: do
74: {
75: if (sem_trywait(semaphore) == -1)
76: {
77: if (errno == EAGAIN)
78: {
79: // Le sémaphore avait une valeur nulle
80: drapeau_fin = d_vrai;
81: }
82: else
83: {
84: // Autre erreur
85: pthread_mutex_unlock(&mutex_sem);
86: return(-1);
87: }
88: }
89: else
90: {
91: (*valeur)++;
92: }
93: } while(drapeau_fin == d_faux);
94:
95: for(i = 0; i < (*valeur); i++)
96: {
97: if (sem_post(semaphore) != 0)
98: {
99: pthread_mutex_unlock(&mutex_sem);
100: return(-1);
101: }
102: }
103:
104: pthread_mutex_unlock(&mutex_sem);
105: return(0);
106: }
107:
108: #endif
109:
110: #ifdef OS2
111:
112: /*
113: ================================================================================
114: Fonctions d'émulation de sémaphores POSIX en fonction des sémaphores SysV
115: ================================================================================
116: Entrées :
117: --------------------------------------------------------------------------------
118: Sorties :
119: --------------------------------------------------------------------------------
120: Effets de bord : néant
121: ================================================================================
122: */
123:
124: extern unsigned char *chemin_semaphores_SysV;
125:
126: int
127: sem_init(sem_t *semaphore, int shared, unsigned int valeur)
128: {
129: union semun argument;
130:
131: if (shared != 0)
132: {
133: return(ENOSYS);
134: }
135:
136: (*semaphore) = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | SEM_R | SEM_A);
137:
138: if ((*semaphore) == -1)
139: {
140: return(EINVAL);
141: }
142:
143: argument.val = valeur;
144: semctl((*semaphore), 0, SETVAL, argument);
145:
146: return(0);
147: }
148:
149: int
150: sem_destroy(sem_t *semaphore)
151: {
152: if (semctl((*semaphore), IPC_RMID, 0) == -1)
153: {
154: return(EINVAL);
155: }
156:
157: return(0);
158: }
159:
160: int
161: sem_wait(sem_t *semaphore)
162: {
163: struct sembuf commande;
164:
165: commande.sem_num = 0;
166: commande.sem_op = -1;
167: commande.sem_flg = 0;
168:
169: if (semop((*semaphore), &commande, 1) == -1)
170: {
171: return(EINVAL);
172: }
173:
174: return(0);
175: }
176:
177: int
178: sem_trywait(sem_t *semaphore)
179: {
180: struct sembuf commande;
181:
182: commande.sem_num = 0;
183: commande.sem_op = -1;
184: commande.sem_flg = IPC_NOWAIT;
185:
186: if (semop((*semaphore), &commande, 1) == -1)
187: {
188: if (errno == EAGAIN)
189: {
190: return(EAGAIN);
191: }
192:
193: return(EINVAL);
194: }
195:
196: return(0);
197: }
198:
199: int
200: sem_post(sem_t *semaphore)
201: {
202: struct sembuf commande;
203:
204: commande.sem_num = 0;
205: commande.sem_op = 1;
206: commande.sem_flg = 0;
207:
208: if (semop((*semaphore), &commande, 1) == -1)
209: {
210: return(EINVAL);
211: }
212:
213: return(0);
214: }
215:
216: int
217: sem_getvalue(sem_t *semaphore, int *valeur)
218: {
219: (*valeur) = semctl((*semaphore), 0, GETVAL);
220:
221: if ((*valeur) < 0)
222: {
223: return(EINVAL);
224: }
225:
226: return(0);
227: }
228:
229: sem_t
230: *sem_open(const char *nom, int oflag, ...)
231: //*sem_open(const char *nom, int oflag)
232: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
233: {
234: mode_t mode;
235:
236: sem_t *semaphore;
237:
238: union semun argument;
239:
240: unsigned char *nom_absolu;
241:
242: unsigned int valeur;
243:
244: va_list liste;
245:
246: if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
247: + 1) * sizeof(unsigned char))) == NULL)
248: {
249: return(SEM_FAILED);
250: }
251:
252: sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
253:
254: if ((semaphore = malloc(sizeof(sem_t))) == NULL)
255: {
256: return(SEM_FAILED);
257: }
258:
259: if ((oflag & O_CREAT) == 0)
260: {
261: // 2 arguments
262: (*semaphore) = semget(ftok(nom_absolu, 1), 0, 0);
263:
264: if ((*semaphore) == -1)
265: {
266: free(semaphore);
267: free(nom_absolu);
268:
269: return(SEM_FAILED);
270: }
271: }
272: else
273: {
274: // 4 arguments
275:
276: // O_CREAT O_EXCL
277: // S_IRUSR S_IWUSR
278:
279: va_start(liste, oflag);
280: mode = va_arg(liste, mode_t);
281: valeur = va_arg(liste, unsigned int);
282: va_end(liste);
283:
284: (*semaphore) = semget(ftok(nom_absolu, 1), 1,
285: ((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT |
286: ((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL |
287: ((oflag & S_IRUSR) == 0) ? 0 : SEM_R |
288: ((oflag & S_IWUSR) == 0) ? 0 : SEM_A);
289:
290: if ((*semaphore) == -1)
291: {
292: free(semaphore);
293: free(nom_absolu);
294:
295: return(SEM_FAILED);
296: }
297:
298: argument.val = valeur;
299: semctl((*semaphore), 0, SETVAL, argument);
300: }
301:
302: free(nom_absolu);
303:
304: return(SEM_FAILED);
305: }
306:
307: int
308: sem_close(sem_t *semaphore)
309: {
310: free(semaphore);
311: return(0);
312: }
313:
314: int
315: sem_unlink(const char *nom)
316: {
317: sem_t semaphore;
318:
319: struct sembuf commande;
320:
321: unsigned char *nom_absolu;
322:
323: if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
324: + 1) * sizeof(unsigned char))) == NULL)
325: {
326: return(ENOMEM);
327: }
328:
329: sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
330:
331: if ((semaphore = semget(ftok(nom_absolu, 1), 0, 0)) == -1)
332: {
333: free(nom_absolu);
334: return(EINVAL);
335: }
336:
337: commande.sem_num = 0;
338: commande.sem_op = 0;
339: commande.sem_flg = 0;
340:
341: if (semop(semaphore, &commande, 1) == -1)
342: {
343: free(nom_absolu);
344: return(EINVAL);
345: }
346:
347: if (semctl(semaphore, IPC_RMID, 0) == -1)
348: {
349: free(nom_absolu);
350: return(EINVAL);
351: }
352:
353: if (unlink(nom_absolu) == -1)
354: {
355: free(nom_absolu);
356: return(EACCES);
357: }
358:
359: free(nom_absolu);
360:
361: return(0);
362: }
363:
364: #endif
365:
366: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>