1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.10
4: Copyright (C) 1989-2012 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:
26: #ifdef SEMAPHORES_NOMMES
27:
28: // Les fonctions suivantes ne sont utilisées que dans le cas d'un
29: // système POSIX qui ne possède pas de sémaphores anonymes. MacOS X
30: // est dans ce cas.
31:
32: static unsigned char *
33: nom_segment_semaphore(pid_t pid, int ordre)
34: {
35: unsigned char *fichier;
36:
37: if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
38: {
39: return(NULL);
40: }
41:
42: sprintf(fichier, "/RPL-%d-%d", (int) pid, ordre);
43: return(fichier);
44: }
45:
46:
47: static unsigned char *
48: nom_segment_semaphore_thread(pid_t pid, pthread_t tid, int ordre)
49: {
50: unsigned char *fichier;
51:
52: if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
53: {
54: return(NULL);
55: }
56:
57: sprintf(fichier, "/RPL-%d-%llX-%d", (int) pid,
58: (unsigned long long) tid, ordre);
59: return(fichier);
60: }
61:
62:
63: /*
64: ================================================================================
65: Fonctions d'émulation de sémaphores anonymes
66: ================================================================================
67: Entrées :
68: --------------------------------------------------------------------------------
69: Sorties :
70: --------------------------------------------------------------------------------
71: Effets de bord : néant
72: ================================================================================
73: */
74:
75: sem_t *
76: sem_init2(unsigned int valeur, pid_t pid, int ordre)
77: {
78: sem_t *semaphore;
79:
80: unsigned char *chemin;
81:
82: if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
83: {
84: return(SEM_FAILED);
85: }
86:
87: semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR,
88: valeur);
89: free(chemin);
90:
91: return(semaphore);
92: }
93:
94:
95: sem_t *
96: sem_init3(unsigned int valeur, pid_t pid, pthread_t tid, int ordre)
97: {
98: sem_t *semaphore;
99:
100: unsigned char *chemin;
101:
102: if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL)
103: {
104: return(SEM_FAILED);
105: }
106:
107: semaphore = sem_open(chemin, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR,
108: valeur);
109: free(chemin);
110:
111: return(semaphore);
112: }
113:
114:
115: sem_t *
116: sem_open2(pid_t pid, int ordre)
117: {
118: unsigned char *chemin;
119:
120: sem_t *semaphore;
121:
122: if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
123: {
124: return(SEM_FAILED);
125: }
126:
127: semaphore = sem_open(chemin, O_RDWR);
128: free(chemin);
129:
130: return(semaphore);
131: }
132:
133:
134: int
135: sem_destroy2(sem_t *semaphore, pid_t pid, int ordre)
136: {
137: int erreur;
138:
139: unsigned char *chemin;
140:
141: sem_close(semaphore);
142:
143: if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
144: {
145: return(1);
146: }
147:
148: erreur = sem_unlink(chemin);
149: free(chemin);
150:
151: return(erreur);
152: }
153:
154:
155: int
156: sem_destroy3(sem_t *semaphore, pid_t pid, pthread_t tid, int ordre)
157: {
158: int erreur;
159:
160: unsigned char *chemin;
161:
162: sem_close(semaphore);
163:
164: if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL)
165: {
166: return(1);
167: }
168:
169: erreur = sem_unlink(chemin);
170: free(chemin);
171:
172: return(erreur);
173: }
174:
175:
176: #undef sem_post
177: #undef sem_wait
178: #undef sem_trywait
179:
180: int
181: sem_getvalue2(sem_t *semaphore, int *valeur)
182: {
183: int i;
184: int j;
185:
186: logical1 drapeau_fin;
187:
188: struct timespec attente;
189:
190: attente.tv_sec = 0;
191: attente.tv_nsec = GRANULARITE_us * 1000;
192:
193: for(j = 0; j < 100; j++)
194: {
195: if (pthread_mutex_trylock(&mutex_sem) == 0)
196: {
197: (*valeur) = 0;
198: drapeau_fin = d_faux;
199:
200: do
201: {
202: if (sem_trywait(semaphore) == -1)
203: {
204: if (errno == EAGAIN)
205: {
206: // Le sémaphore avait une valeur nulle
207: drapeau_fin = d_vrai;
208: }
209: else
210: {
211: // Autre erreur
212: pthread_mutex_unlock(&mutex_sem);
213: return(-1);
214: }
215: }
216: else
217: {
218: (*valeur)++;
219: }
220: } while(drapeau_fin == d_faux);
221:
222: for(i = 0; i < (*valeur); i++)
223: {
224: if (sem_post(semaphore) != 0)
225: {
226: pthread_mutex_unlock(&mutex_sem);
227: return(-1);
228: }
229: }
230:
231: pthread_mutex_unlock(&mutex_sem);
232: return(0);
233: }
234:
235: INCR_GRANULARITE(attente.tv_nsec);
236: }
237:
238: // Le mutex n'a pas pu être verrouillé. On peut raisonnablement penser
239: // que le sémaphore est bloqué dans un sem_wait() protégé par ce mutex.
240:
241: (*valeur) = 0;
242: return(0);
243: }
244:
245: #endif
246:
247: #ifdef IPCS_SYSV
248:
249: /*
250: ================================================================================
251: Fonctions d'émulation de sémaphores POSIX en fonction des sémaphores SysV
252: ================================================================================
253: Entrées :
254: --------------------------------------------------------------------------------
255: Sorties :
256: --------------------------------------------------------------------------------
257: Effets de bord : néant
258: ================================================================================
259: */
260:
261: #ifndef OS2 // IPCS_SYSV
262: extern unsigned char *racine_segment;
263: #else // OS/2
264: unsigned char racine_semaphores_OS2[] = "\\SEM32\\";
265: unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\";
266: #endif
267:
268: int
269: sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur)
270: {
271: // Création d'un sémaphore anonyme qui devra être supprimé par
272: // sem_destroy_SysV
273:
274: # ifndef OS2 // IPCS_SYSV
275: int desc;
276: int ios;
277:
278: key_t clef;
279:
280: union semun argument;
281:
282: if (shared == 0)
283: {
284: // Sémaphore privé
285: (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL |
286: S_IRUSR | S_IWUSR);
287: (*semaphore).path = NULL;
288: (*semaphore).pid = getpid();
289: (*semaphore).tid = pthread_self();
290: (*semaphore).alloue = 0;
291: }
292: else
293: {
294: // Sémaphore partagé entre plusieurs processus
295: if (((*semaphore).path = malloc((strlen(racine_segment)
296: + 2 + 256 + 1) * sizeof(unsigned char))) == NULL)
297: {
298: return(-1);
299: }
300:
301: sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%llX",
302: racine_segment, (int) getpid(),
303: (long long unsigned) pthread_self(),
304: (long long unsigned) semaphore);
305:
306: if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL,
307: S_IRUSR | S_IWUSR)) == -1)
308: {
309: free((*semaphore).path);
310: return(-1);
311: }
312:
313: (*semaphore).pid = getpid();
314: (*semaphore).tid = pthread_self();
315: clef = ftok((*semaphore).path, 1);
316: close(desc);
317:
318: if (clef == -1)
319: {
320: free((*semaphore).path);
321: return(-1);
322: }
323:
324: (*semaphore).alloue = 0;
325: (*semaphore).sem = semget(clef, 1, IPC_CREAT | IPC_EXCL |
326: S_IRUSR | S_IWUSR);
327: }
328:
329: if ((*semaphore).sem == -1)
330: {
331: errno = EINVAL;
332: return(-1);
333: }
334:
335: argument.val = valeur;
336: ios = semctl((*semaphore).sem, 0, SETVAL, argument);
337:
338: return(ios);
339: # else // OS/2
340: sem_t *psem;
341:
342: psem = semaphore;
343:
344: if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)
345: {
346: free(psem);
347: errno = ENOMEM;
348: return(-1);
349: }
350:
351: if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)
352: {
353: free((*psem).cnt);
354: free(psem);
355: errno = ENOMEM;
356: return(-1);
357: }
358:
359: if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
360: {
361: free((*psem).cnt);
362: free((*psem).nopened);
363: free(psem);
364: return(-1);
365: }
366:
367: if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0)
368: != 0)
369: {
370: DosCloseMutexSem((*psem).hmtx);
371: free((*psem).cnt);
372: free((*psem).nopened);
373: free(psem);
374: return(-1);
375: }
376:
377: (*(*psem).cnt) = valeur;
378: (*(*psem).nopened) = 1;
379: (*psem).shared = shared;
380: (*psem).allocated = 0;
381:
382: return(0);
383: # endif
384: }
385:
386: int
387: sem_destroy_SysV(sem_t *semaphore)
388: {
389: // Détruit un sémaphore anonmyme
390:
391: # ifndef OS2 // IPCS_SYSV
392: if ((*semaphore).path != NULL)
393: {
394: return(EINVAL);
395: }
396:
397: if ((*semaphore).pid != getpid())
398: {
399: return(0);
400: }
401:
402: if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
403: {
404: return(EINVAL);
405: }
406:
407: return(0);
408: # else // OS/2
409: sem_t *psem;
410:
411: psem = semaphore;
412:
413: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
414: {
415: return(EINVAL);
416: }
417:
418: if (DosCloseMutexSem((*psem).hmtx) != 0)
419: {
420: return(EINVAL);
421: }
422:
423: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
424: {
425: DosPostEventSem((*psem).hev);
426: }
427:
428: (*(*psem).nopened)--;
429:
430: if ((*psem).shared == 0)
431: {
432: free((*psem).cnt);
433: free((*psem).nopened);
434: }
435: else
436: {
437: if ((*(*psem).nopened) == 0)
438: {
439: DosFreeMem((*psem).cnt);
440: }
441: }
442:
443: if ((*psem).allocated != 0)
444: {
445: free(psem);
446: }
447:
448: return(0);
449: # endif
450: }
451:
452: int
453: sem_wait_SysV(sem_t *semaphore)
454: {
455: # ifndef OS2 // IPCS_SYSV
456: struct sembuf commande;
457:
458: commande.sem_num = 0;
459: commande.sem_op = -1;
460: commande.sem_flg = 0;
461:
462: while(semop((*semaphore).sem, &commande, 1) == -1)
463: {
464: if (errno != EINTR)
465: {
466: errno = EINVAL;
467: return(-1);
468: }
469: }
470:
471: return(0);
472: # else // OS/2
473: sem_t *psem;
474:
475: ULONG cnt;
476:
477: psem = semaphore;
478:
479: if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
480: {
481: errno = EINVAL;
482: return(-1);
483: }
484:
485: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
486: {
487: errno = EINVAL;
488: return(-1);
489: }
490:
491: if ((*(*psem).cnt) > 0)
492: {
493: (*(*psem).cnt)--;
494: }
495:
496: if ((*(*psem).cnt) == 0)
497: {
498: DosResetEventSem((*psem).hev, &cnt);
499: }
500:
501: DosReleaseMutexSem((*psem).hmtx);
502: return(0);
503: # endif
504: }
505:
506: int
507: sem_trywait_SysV(sem_t *semaphore)
508: {
509: # ifndef OS2 // IPCS_SYSV
510: struct sembuf commande;
511:
512: commande.sem_num = 0;
513: commande.sem_op = -1;
514: commande.sem_flg = IPC_NOWAIT;
515:
516: while(semop((*semaphore).sem, &commande, 1) == -1)
517: {
518: if (errno != EINTR)
519: {
520: errno = EINVAL;
521: return(-1);
522: }
523: }
524:
525: return(0);
526: # else // OS/2
527: int ios;
528:
529: sem_t *psem;
530:
531: ULONG cnt;
532:
533: psem = semaphore;
534:
535: if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
536: {
537: errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
538: return(-1);
539: }
540:
541: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
542: {
543: errno = EINVAL;
544: return(-1);
545: }
546:
547: if ((*(*psem).cnt) > 0)
548: {
549: (*(*psem).cnt)--;
550: }
551:
552: if ((*(*psem).cnt) == 0)
553: {
554: DosResetEventSem((*psem).hev, &cnt);
555: }
556:
557: DosReleaseMutexSem((*psem).hmtx);
558: return(0);
559: # endif
560: }
561:
562: #ifndef timespeccmp
563: # define timespeccmp(tsp, usp, cmp) \
564: (((tsp)->tv_sec == (usp)->tv_sec) ? \
565: ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
566: ((tsp)->tv_sec cmp (usp)->tv_sec))
567: # define timespecadd(tsp, usp, vsp) \
568: do { \
569: (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
570: (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
571: if ((vsp)->tv_nsec >= 1000000000L) { \
572: (vsp)->tv_sec++; \
573: (vsp)->tv_nsec -= 1000000000L; \
574: } \
575: } while(0)
576: # define timespecsub(tsp, usp, vsp) \
577: do { \
578: (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
579: (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
580: if ((vsp)->tv_nsec < 0) { \
581: (vsp)->tv_sec--; \
582: (vsp)->tv_nsec += 1000000000L; \
583: } \
584: } while(0)
585: #endif
586:
587: int
588: sem_timedwait_SysV(sem_t *sem, struct timespec *ts)
589: {
590: struct timespec onems = { 0, 1000000 };
591: struct timespec total = { 0, 0 };
592: struct timespec unslept;
593: struct timespec elapsed;
594: struct timespec tmp;
595:
596: while(timespeccmp(ts, &total, >))
597: {
598: if (sem_trywait_SysV(sem) == 0)
599: {
600: return(0);
601: }
602:
603: if (errno != EAGAIN)
604: {
605: return(-1);
606: }
607:
608: nanosleep(&onems, &unslept);
609:
610: timespecsub(&onems, &unslept, &elapsed);
611: timespecadd(&total, &elapsed, &tmp);
612: total.tv_sec = tmp.tv_sec;
613: total.tv_nsec = tmp.tv_nsec;
614: }
615:
616: errno = ETIMEDOUT;
617: return(-1);
618: }
619:
620: int
621: sem_post_SysV(sem_t *semaphore)
622: {
623: # ifndef OS2 // IPCS_SYSV
624: struct sembuf commande;
625:
626: commande.sem_num = 0;
627: commande.sem_op = 1;
628: commande.sem_flg = 0;
629:
630: while(semop((*semaphore).sem, &commande, 1) == -1)
631: {
632: if (errno != EINTR)
633: {
634: errno = EINVAL;
635: return(-1);
636: }
637: }
638:
639: return(0);
640: # else // OS/2
641: sem_t *psem;
642:
643: psem = semaphore;
644:
645: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
646: {
647: errno = EINVAL;
648: return(-1);
649: }
650:
651: (*(*psem).cnt)++;
652: DosPostEventSem((*psem).hev);
653: DosReleaseMutexSem((*psem).hmtx);
654:
655: return(0);
656: # endif
657: }
658:
659: int
660: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
661: {
662: # ifndef OS2 // IPCS_SYSV
663: (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
664:
665: if ((*valeur) < 0)
666: {
667: return(EINVAL);
668: }
669:
670: return(0);
671: # else
672: sem_t *psem;
673:
674: psem = semaphore;
675:
676: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
677: {
678: errno = EINVAL;
679: return(-1);
680: }
681:
682: (*valeur) = (*(*psem).cnt);
683: DosReleaseMutexSem((*psem).hmtx);
684:
685: return(0);
686: # endif
687: }
688:
689: sem_t
690: *sem_open_SysV(const char *nom, int oflag, ...)
691: //*sem_open(const char *nom, int oflag)
692: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
693: {
694: mode_t mode;
695:
696: sem_t *semaphore;
697:
698: # ifndef OS2
699: int desc;
700:
701: key_t clef;
702:
703: union semun argument;
704: # endif
705:
706: unsigned char *nom_absolu;
707:
708: unsigned int valeur;
709:
710: va_list liste;
711:
712: # ifdef OS2
713: sem_t *psem;
714:
715: PVOID base;
716:
717: unsigned char *ptr;
718: unsigned char *nom_segment;
719: # endif
720:
721: # ifndef OS2 // IPCS_SYSV
722: if ((nom_absolu = malloc((strlen(racine_segment) + strlen(nom)
723: + 2) * sizeof(unsigned char))) == NULL)
724: {
725: return(SEM_FAILED);
726: }
727:
728: sprintf(nom_absolu, "%s/%s", racine_segment, nom);
729:
730: if ((semaphore = malloc(sizeof(sem_t))) == NULL)
731: {
732: return(SEM_FAILED);
733: }
734:
735: (*semaphore).alloue = -1;
736: (*semaphore).pid = getpid();
737: (*semaphore).tid = pthread_self();
738: # else
739: if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)
740: * sizeof(unsigned char))) == NULL)
741: {
742: return(SEM_FAILED);
743: }
744:
745: sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
746: ptr = nom_segment;
747:
748: while((*ptr) != d_code_fin_chaine)
749: {
750: if ((*ptr) == '/')
751: {
752: (*ptr) = '\\';
753: }
754:
755: ptr++;
756: }
757:
758: if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom)
759: + 2) * sizeof(unsigned char))) == NULL)
760: {
761: return(SEM_FAILED);
762: }
763:
764: sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);
765: ptr = nom_absolu;
766:
767: while((*ptr) != d_code_fin_chaine)
768: {
769: if ((*ptr) == '/')
770: {
771: (*ptr) = '\\';
772: }
773:
774: ptr++;
775: }
776:
777: (*(ptr + 1)) = d_code_fin_chaine;
778:
779: if ((psem = malloc(sizeof(sem_t))) == NULL)
780: {
781: return(SEM_FAILED);
782: }
783:
784: (*psem).allocated = 1;
785: # endif
786:
787: if ((oflag & O_CREAT) == 0)
788: {
789: // 2 arguments
790:
791: # ifndef OS2 // IPCS_SYSV
792: clef = ftok(nom_absolu, 1);
793:
794: if (clef == -1)
795: {
796: return(SEM_FAILED);
797: }
798:
799: (*semaphore).sem = semget(clef, 0, 0);
800: (*semaphore).path = nom_absolu;
801: (*semaphore).pid = getpid();
802:
803: if ((*semaphore).sem == -1)
804: {
805: free(semaphore);
806: free(nom_absolu);
807:
808: return(SEM_FAILED);
809: }
810: # else // OS/2
811: if ((psem = malloc(sizeof(sem_t))) == NULL)
812: {
813: free(nom_absolu);
814: free(nom_segment);
815: return(SEM_FAILED);
816: }
817:
818: (*ptr) = 'M';
819:
820: if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
821: {
822: free(psem);
823: free(nom_absolu);
824: free(nom_segment);
825:
826: return(SEM_FAILED);
827: }
828:
829: (*ptr) = 'S';
830:
831: if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
832: {
833: DosCloseMutexSem((*psem).hmtx);
834:
835: free(psem);
836: free(nom_absolu);
837: free(nom_segment);
838:
839: return(SEM_FAILED);
840: }
841:
842: if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ)
843: != 0)
844: {
845: DosCloseMutexSem((*psem).hmtx);
846:
847: free(nom_absolu);
848: free(nom_segment);
849: free(psem);
850:
851: return(SEM_FAILED);
852: }
853:
854: free(nom_segment);
855:
856: (*psem).cnt = (ULONG *) base;
857: (*psem).nopened = ((ULONG *) base) + 1;
858: (*psem).shared = 1;
859:
860: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
861: {
862: DosCloseMutexSem((*psem).hmtx);
863:
864: free(nom_absolu);
865: free(nom_segment);
866: free(psem);
867:
868: return(SEM_FAILED);
869: }
870:
871: (*((*psem).nopened))++;
872:
873: DosReleaseMutexSem((*psem).hmtx);
874:
875: semaphore = psem;
876: # endif
877: }
878: else
879: {
880: // 4 arguments
881:
882: // O_CREAT O_EXCL
883: // S_IRUSR S_IWUSR
884:
885: va_start(liste, oflag);
886: mode = va_arg(liste, mode_t);
887: valeur = va_arg(liste, unsigned int);
888: va_end(liste);
889:
890: # ifndef OS2 // IPCS_SYSV
891: if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR,
892: S_IRUSR | S_IWUSR)) == -1)
893: {
894: free(semaphore);
895: free(nom_absolu);
896:
897: return(SEM_FAILED);
898: }
899:
900: if ((clef = ftok(nom_absolu, 1)) == -1)
901: {
902: close(desc);
903: free(semaphore);
904: free(nom_absolu);
905:
906: return(SEM_FAILED);
907: }
908:
909: close(desc);
910:
911: (*semaphore).sem = semget(clef, 1,
912: (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |
913: (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |
914: (int) mode);
915: (*semaphore).path = nom_absolu;
916: (*semaphore).pid = getpid();
917:
918: if ((*semaphore).sem == -1)
919: {
920: free(semaphore);
921: free(nom_absolu);
922:
923: return(SEM_FAILED);
924: }
925:
926: argument.val = valeur;
927: semctl((*semaphore).sem, 0, SETVAL, argument);
928: # else // OS/2
929: if ((psem = malloc(sizeof(sem_t))) == NULL)
930: {
931: free(nom_absolu);
932: free(nom_segment);
933:
934: return(SEM_FAILED);
935: }
936:
937: (*ptr) = 'M';
938:
939: if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
940: {
941: free(psem);
942: free(nom_absolu);
943: free(nom_segment);
944:
945: return(SEM_FAILED);
946: }
947:
948: (*ptr) = 'S';
949:
950: if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
951: (valeur != 0) ? 1 : 0) != 0)
952: {
953: DosCloseMutexSem((*psem).hmtx);
954:
955: free(nom_absolu);
956: free(nom_segment);
957: free(psem);
958:
959: return(SEM_FAILED);
960: }
961:
962: if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
963: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
964: {
965: DosCloseMutexSem((*psem).hmtx);
966:
967: free(nom_absolu);
968: free(nom_segment);
969: free(psem);
970:
971: return(SEM_FAILED);
972: }
973:
974: free(nom_segment);
975:
976: (*psem).cnt = (ULONG *) base;
977: (*psem).nopened = ((ULONG *) base) + 1;
978: (*(*psem).cnt) = valeur;
979: (*(*psem).nopened) = 1;
980: (*psem).shared = 1;
981: semaphore = psem;
982: # endif
983: }
984:
985: return(semaphore);
986: }
987:
988: int
989: sem_close_SysV(sem_t *semaphore)
990: {
991: // Ferme un sémaphore nommé créé par sem_open_SysV()
992: # ifndef OS2 // IPCS_SYSV
993: if ((*semaphore).path != NULL)
994: {
995: free((*semaphore).path);
996: }
997:
998: if ((*semaphore).alloue == -1)
999: {
1000: free(semaphore);
1001: }
1002:
1003: return(0);
1004: # else
1005: sem_t *psem;
1006:
1007: psem = semaphore;
1008:
1009: if (DosCloseMutexSem((*psem).hmtx) != 0)
1010: {
1011: return(EINVAL);
1012: }
1013:
1014: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
1015: {
1016: DosPostEventSem((*psem).hev);
1017: }
1018:
1019: (*(*psem).nopened)--;
1020:
1021: if ((*psem).shared == 0)
1022: {
1023: free((*psem).cnt);
1024: free((*psem).nopened);
1025: }
1026: else
1027: {
1028: if ((*(*psem).nopened) == 0)
1029: {
1030: DosFreeMem((*psem).cnt);
1031: }
1032: }
1033:
1034: if ((*psem).allocated != 0)
1035: {
1036: free(psem);
1037: }
1038:
1039: return(0);
1040: # endif
1041: }
1042:
1043: int
1044: sem_unlink_SysV(char *nom)
1045: {
1046: // Détruit un sémaphore nommé créé par sem_open_SysV()
1047: # ifndef OS2 // IPCS_SYSV
1048: semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID);
1049:
1050: if (unlink(nom) == -1)
1051: {
1052: return(EACCES);
1053: }
1054:
1055: free(nom);
1056: return(0);
1057: # else
1058: return(0);
1059: # endif
1060: }
1061:
1062: #endif
1063:
1064: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>