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