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 SEMAPHORES_SYSV
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: #ifndef OS2
125: extern unsigned char *chemin_semaphores_SysV;
126: #else
127: unsigned char racine_semaphores_OS2[] = "\\SEM32\\";
128: unsigned char racine_memoire_OS2[] = "\\SHAREDMEM\\";
129: #endif
130:
131: #ifndef UNION_SEMUN
132: union semun
133: {
134: int val;
135: struct semid_ds *buf;
136: unsigned short *array;
137: struct seminfo *__buf;
138: };
139: #endif
140:
141: int
142: sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur)
143: {
144: # ifndef OS2
145:
146: int ios;
147:
148: union semun argument;
149:
150: if (shared != 0)
151: {
152: errno = ENOSYS;
153: return(-1);
154: }
155:
156: (*semaphore) = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | SEM_R | SEM_A);
157:
158: if ((*semaphore) == -1)
159: {
160: errno = EINVAL;
161: return(-1);
162: }
163:
164: argument.val = valeur;
165: ios = semctl((*semaphore), 0, SETVAL, argument);
166:
167: return(ios);
168:
169: # else
170:
171: sem_t *psem;
172:
173: psem = semaphore;
174:
175: if (shared != 0)
176: {
177: errno = ENOSYS;
178: return(-1);
179: }
180:
181: if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)
182: {
183: free(psem);
184: errno = ENOMEM;
185: return(-1);
186: }
187:
188: if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)
189: {
190: free((*psem).cnt);
191: free(psem);
192: errno = ENOMEM;
193: return(-1);
194: }
195:
196: if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
197: {
198: free((*psem).cnt);
199: free((*psem).nopened);
200: free(psem);
201: return(-1);
202: }
203:
204: if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0) != 0)
205: {
206: DosCloseMutexSem((*psem).hmtx);
207: free((*psem).cnt);
208: free((*psem).nopened);
209: free(psem);
210: return(-1);
211: }
212:
213: (*(*psem).cnt) = valeur;
214: (*(*psem).nopened) = 1;
215: (*psem).shared = shared;
216: (*psem).allocated = 0;
217:
218: return(0);
219:
220: # endif
221: }
222:
223: int
224: sem_destroy_SysV(sem_t *semaphore)
225: {
226: # ifndef OS2
227:
228: if (semctl((*semaphore), IPC_RMID, 0) == -1)
229: {
230: return(EINVAL);
231: }
232:
233: return(0);
234:
235: # else
236:
237: sem_t *psem;
238:
239: psem = semaphore;
240:
241: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
242: {
243: return(EINVAL);
244: }
245:
246: if (DosCloseMutexSem((*psem).hmtx) != 0)
247: {
248: return(EINVAL);
249: }
250:
251: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
252: {
253: DosPostEventSem((*psem).hev);
254: }
255:
256: (*(*psem).nopened)--;
257:
258: if ((*psem).shared == 0)
259: {
260: free((*psem).cnt);
261: free((*psem).nopened);
262: }
263: else
264: {
265: if ((*(*psem).nopened) == 0)
266: {
267: DosFreeMem((*psem).cnt);
268: }
269: }
270:
271: if ((*psem).allocated != 0)
272: {
273: free(psem);
274: }
275:
276: return(0);
277:
278: # endif
279: }
280:
281: int
282: sem_wait_SysV(sem_t *semaphore)
283: {
284: # ifndef OS2
285:
286: struct sembuf commande;
287:
288: commande.sem_num = 0;
289: commande.sem_op = -1;
290: commande.sem_flg = 0;
291:
292: if (semop((*semaphore), &commande, 1) == -1)
293: {
294: errno = EINVAL;
295: return(-1);
296: }
297:
298: return(0);
299:
300: # else
301:
302: sem_t *psem;
303:
304: ULONG cnt;
305:
306: psem = semaphore;
307:
308: if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
309: {
310: errno = EINVAL;
311: return(-1);
312: }
313:
314: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
315: {
316: errno = EINVAL;
317: return(-1);
318: }
319:
320: if ((*(*psem).cnt) > 0)
321: {
322: (*(*psem).cnt)--;
323: }
324:
325: if ((*(*psem).cnt) == 0)
326: {
327: DosResetEventSem((*psem).hev, &cnt);
328: }
329:
330: DosReleaseMutexSem((*psem).hmtx);
331: return(0);
332:
333: # endif
334: }
335:
336: int
337: sem_trywait_SysV(sem_t *semaphore)
338: {
339: # ifndef OS2
340:
341: struct sembuf commande;
342:
343: commande.sem_num = 0;
344: commande.sem_op = -1;
345: commande.sem_flg = IPC_NOWAIT;
346:
347: if (semop((*semaphore), &commande, 1) == -1)
348: {
349: return(-1);
350: }
351:
352: return(0);
353:
354: # else
355:
356: int ios;
357:
358: sem_t *psem;
359:
360: ULONG cnt;
361:
362: psem = semaphore;
363:
364: if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
365: {
366: errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
367: return(-1);
368: }
369:
370: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
371: {
372: errno = EINVAL;
373: return(-1);
374: }
375:
376: if ((*(*psem).cnt) > 0)
377: {
378: (*(*psem).cnt)--;
379: }
380:
381: if ((*(*psem).cnt) == 0)
382: {
383: DosResetEventSem((*psem).hev, &cnt);
384: }
385:
386: DosReleaseMutexSem((*psem).hmtx);
387: return(0);
388:
389: # endif
390: }
391:
392: int
393: sem_post_SysV(sem_t *semaphore)
394: {
395: # ifndef OS2
396:
397: struct sembuf commande;
398:
399: commande.sem_num = 0;
400: commande.sem_op = 1;
401: commande.sem_flg = 0;
402:
403: if (semop((*semaphore), &commande, 1) == -1)
404: {
405: errno = EINVAL;
406: return(-1);
407: }
408:
409: return(0);
410:
411: # else
412:
413: sem_t *psem;
414:
415: psem = semaphore;
416:
417: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
418: {
419: errno = EINVAL;
420: return(-1);
421: }
422:
423: (*(*psem).cnt)++;
424: DosPostEventSem((*psem).hev);
425: DosReleaseMutexSem((*psem).hmtx);
426:
427: return(0);
428:
429: # endif
430: }
431:
432: int
433: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
434: {
435: # ifndef OS2
436:
437: (*valeur) = semctl((*semaphore), 0, GETVAL);
438:
439: if ((*valeur) < 0)
440: {
441: return(EINVAL);
442: }
443:
444: return(0);
445:
446: # else
447:
448: sem_t *psem;
449:
450: psem = semaphore;
451:
452: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
453: {
454: errno = EINVAL;
455: return(-1);
456: }
457:
458: (*valeur) = (*(*psem).cnt);
459: DosReleaseMutexSem((*psem).hmtx);
460:
461: return(0);
462:
463: # endif
464: }
465:
466: sem_t
467: *sem_open_SysV(const char *nom, int oflag, ...)
468: //*sem_open(const char *nom, int oflag)
469: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
470: {
471: mode_t mode;
472:
473: sem_t *semaphore;
474:
475: # ifndef OS2
476: union semun argument;
477: # endif
478:
479: unsigned char *nom_absolu;
480:
481: unsigned int valeur;
482:
483: va_list liste;
484:
485: # ifdef OS2
486: sem_t *psem;
487:
488: PVOID base;
489:
490: unsigned char *ptr;
491: unsigned char *nom_segment;
492: # endif
493:
494: # ifndef OS2
495:
496: if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
497: + 1) * sizeof(unsigned char))) == NULL)
498: {
499: return(SEM_FAILED);
500: }
501:
502: sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
503:
504: if ((semaphore = malloc(sizeof(sem_t))) == NULL)
505: {
506: return(SEM_FAILED);
507: }
508:
509: (*psem).allocated = 1;
510:
511: # else
512:
513: if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)
514: * sizeof(unsigned char))) == NULL)
515: {
516: return(SEM_FAILED);
517: }
518:
519: sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
520: ptr = nom_segment;
521:
522: while((*ptr) != d_code_fin_chaine)
523: {
524: if ((*ptr) == '/')
525: {
526: (*ptr) = '\\';
527: }
528:
529: ptr++;
530: }
531:
532: if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom)
533: + 2) * sizeof(unsigned char))) == NULL)
534: {
535: return(SEM_FAILED);
536: }
537:
538: sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);
539: ptr = nom_absolu;
540:
541: while((*ptr) != d_code_fin_chaine)
542: {
543: if ((*ptr) == '/')
544: {
545: (*ptr) = '\\';
546: }
547:
548: ptr++;
549: }
550:
551: (*(ptr + 1)) = d_code_fin_chaine;
552:
553: if ((psem = malloc(sizeof(sem_t))) == NULL)
554: {
555: return(SEM_FAILED);
556: }
557:
558: # endif
559:
560: if ((oflag & O_CREAT) == 0)
561: {
562: // 2 arguments
563:
564: # ifndef OS2
565:
566: (*semaphore) = semget(ftok(nom_absolu, 1), 0, 0);
567:
568: if ((*semaphore) == -1)
569: {
570: free(semaphore);
571: free(nom_absolu);
572:
573: return(SEM_FAILED);
574: }
575:
576: # else
577:
578: if ((psem = malloc(sizeof(sem_t))) == NULL)
579: {
580: free(nom_absolu);
581: free(nom_segment);
582: return(SEM_FAILED);
583: }
584:
585: (*ptr) = 'M';
586:
587: if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
588: {
589: free(psem);
590: free(nom_absolu);
591: free(nom_segment);
592:
593: return(SEM_FAILED);
594: }
595:
596: (*ptr) = 'S';
597:
598: if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
599: {
600: DosCloseMutexSem((*psem).hmtx);
601:
602: free(psem);
603: free(nom_absolu);
604: free(nom_segment);
605:
606: return(SEM_FAILED);
607: }
608:
609: if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ) != 0)
610: {
611: DosCloseMutexSem((*psem).hmtx);
612:
613: free(nom_absolu);
614: free(nom_segment);
615: free(psem);
616:
617: return(SEM_FAILED);
618: }
619:
620: free(nom_segment);
621:
622: (*psem).cnt = (ULONG *) base;
623: (*psem).nopened = ((ULONG *) base) + 1;
624: (*psem).shared = 1;
625:
626: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
627: {
628: DosCloseMutexSem((*psem).hmtx);
629:
630: free(nom_absolu);
631: free(nom_segment);
632: free(psem);
633:
634: return(SEM_FAILED);
635: }
636:
637: (*((*psem).nopened))++;
638:
639: DosReleaseMutexSem((*psem).hmtx);
640:
641: semaphore = psem;
642:
643: # endif
644: }
645: else
646: {
647: // 4 arguments
648:
649: // O_CREAT O_EXCL
650: // S_IRUSR S_IWUSR
651:
652: va_start(liste, oflag);
653: mode = va_arg(liste, mode_t);
654: valeur = va_arg(liste, unsigned int);
655: va_end(liste);
656:
657: # ifndef OS2
658:
659: (*semaphore) = semget(ftok(nom_absolu, 1), 1,
660: ((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT |
661: ((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL |
662: ((oflag & S_IRUSR) == 0) ? 0 : SEM_R |
663: ((oflag & S_IWUSR) == 0) ? 0 : SEM_A);
664:
665: if ((*semaphore) == -1)
666: {
667: free(semaphore);
668: free(nom_absolu);
669:
670: return(SEM_FAILED);
671: }
672:
673: argument.val = valeur;
674: semctl((*semaphore), 0, SETVAL, argument);
675:
676: # else
677:
678: if ((psem = malloc(sizeof(sem_t))) == NULL)
679: {
680: free(nom_absolu);
681: free(nom_segment);
682:
683: return(SEM_FAILED);
684: }
685:
686: (*ptr) = 'M';
687:
688: if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
689: {
690: free(psem);
691: free(nom_absolu);
692: free(nom_segment);
693:
694: return(SEM_FAILED);
695: }
696:
697: (*ptr) = 'S';
698:
699: if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
700: (valeur != 0) ? 1 : 0) != 0)
701: {
702: DosCloseMutexSem((*psem).hmtx);
703:
704: free(nom_absolu);
705: free(nom_segment);
706: free(psem);
707:
708: return(SEM_FAILED);
709: }
710:
711: if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
712: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
713: {
714: DosCloseMutexSem((*psem).hmtx);
715:
716: free(nom_absolu);
717: free(nom_segment);
718: free(psem);
719:
720: return(SEM_FAILED);
721: }
722:
723: free(nom_segment);
724:
725: (*psem).cnt = (ULONG *) base;
726: (*psem).nopened = ((ULONG *) base) + 1;
727: (*(*psem).cnt) = valeur;
728: (*(*psem).nopened) = 1;
729: (*psem).shared = 1;
730: semaphore = psem;
731:
732: # endif
733: }
734:
735: free(nom_absolu);
736:
737: return(semaphore);
738: }
739:
740: int
741: sem_close_SysV(sem_t *semaphore)
742: {
743: # ifndef OS2
744:
745: free(semaphore);
746: return(0);
747:
748: # else
749:
750: sem_t *psem;
751:
752: psem = semaphore;
753:
754: if (DosCloseMutexSem((*psem).hmtx) != 0)
755: {
756: return(EINVAL);
757: }
758:
759: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
760: {
761: DosPostEventSem((*psem).hev);
762: }
763:
764: (*(*psem).nopened)--;
765:
766: if ((*psem).shared == 0)
767: {
768: free((*psem).cnt);
769: free((*psem).nopened);
770: }
771: else
772: {
773: if ((*(*psem).nopened) == 0)
774: {
775: DosFreeMem((*psem).cnt);
776: }
777: }
778:
779: if ((*psem).allocated != 0)
780: {
781: free(psem);
782: }
783:
784: return(0);
785:
786: # endif
787: }
788:
789: int
790: sem_unlink_SysV(const char *nom)
791: {
792: # ifndef OS2
793:
794: sem_t semaphore;
795:
796: struct sembuf commande;
797:
798: unsigned char *nom_absolu;
799:
800: if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
801: + 1) * sizeof(unsigned char))) == NULL)
802: {
803: return(ENOMEM);
804: }
805:
806: sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
807:
808: if ((semaphore = semget(ftok(nom_absolu, 1), 0, 0)) == -1)
809: {
810: free(nom_absolu);
811: return(EINVAL);
812: }
813:
814: commande.sem_num = 0;
815: commande.sem_op = 0;
816: commande.sem_flg = 0;
817:
818: if (semop(semaphore, &commande, 1) == -1)
819: {
820: free(nom_absolu);
821: return(EINVAL);
822: }
823:
824: if (semctl(semaphore, IPC_RMID, 0) == -1)
825: {
826: free(nom_absolu);
827: return(EINVAL);
828: }
829:
830: if (unlink(nom_absolu) == -1)
831: {
832: free(nom_absolu);
833: return(EACCES);
834: }
835:
836: free(nom_absolu);
837:
838: return(0);
839:
840: # else
841:
842: return(0);
843:
844: # endif
845: }
846:
847: #endif
848:
849: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>