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