1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.36
4: Copyright (C) 1989-2025 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: nanosleep(&attente, NULL);
288: INCR_GRANULARITE(attente.tv_nsec);
289: }
290:
291: // Le mutex n'a pas pu être verrouillé. On peut raisonnablement penser
292: // que le sémaphore est bloqué dans un sem_wait() protégé par ce mutex.
293:
294: (*valeur) = 0;
295: return(0);
296: }
297:
298:
299: #undef sem_post
300: #undef sem_wait
301: #undef sem_trywait
302:
303:
304: #ifdef IPCS_SYSV
305:
306: /*
307: ================================================================================
308: Fonctions d'émulation de sémaphores POSIX en fonction des sémaphores SysV
309: ================================================================================
310: Entrées :
311: --------------------------------------------------------------------------------
312: Sorties :
313: --------------------------------------------------------------------------------
314: Effets de bord : néant
315: ================================================================================
316: */
317:
318: #ifndef OS2 // IPCS_SYSV
319: extern unsigned char *racine_segment;
320: #else // OS/2
321: unsigned char racine_semaphores_OS2[] = "\\SEM32\\";
322: unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\";
323: #endif
324:
325: int
326: sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur)
327: {
328: // Création d'un sémaphore anonyme qui devra être supprimé par
329: // sem_destroy_SysV
330:
331: # ifndef OS2 // IPCS_SYSV
332: int desc;
333: int ios;
334:
335: key_t clef;
336:
337: union semun argument;
338:
339: unsigned char *langue;
340:
341: if (shared == 0)
342: {
343: // Sémaphore privé
344: (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL |
345: S_IRUSR | S_IWUSR);
346: (*semaphore).path = NULL;
347: (*semaphore).pid = getpid();
348: (*semaphore).tid = pthread_self();
349: (*semaphore).alloue = 0;
350: }
351: else
352: {
353: // Sémaphore partagé entre plusieurs processus
354: if (((*semaphore).path = sys_malloc((strlen(racine_segment)
355: + 2 + 256 + 1) * sizeof(unsigned char))) == NULL)
356: {
357: return(-1);
358: }
359:
360: sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%llX",
361: racine_segment, (int) getpid(),
362: (long long unsigned) pthread_self(),
363: (long long unsigned) semaphore);
364:
365: if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL,
366: S_IRUSR | S_IWUSR)) == -1)
367: {
368: if (errno != EEXIST)
369: {
370: sys_free((*semaphore).path);
371: return(-1);
372: }
373:
374: if ((langue = getenv("LANG")) != NULL)
375: {
376: if (strncmp(langue, "fr", 2) == 0)
377: {
378: uprintf("+++Attention : Le sémaphore %s préexiste !\n",
379: (*semaphore).path);
380: }
381: else
382: {
383: uprintf("+++Warning: %s semaphore preexists!\n",
384: (*semaphore).path);
385: }
386: }
387: else
388: {
389: uprintf("+++Warning: %s semaphore preexists!\n",
390: (*semaphore).path);
391: }
392:
393: if ((desc = open((*semaphore).path, O_RDWR | O_CREAT,
394: S_IRUSR | S_IWUSR)) == -1)
395: {
396: sys_free((*semaphore).path);
397: return(-1);
398: }
399: }
400:
401: (*semaphore).pid = getpid();
402: (*semaphore).tid = pthread_self();
403: clef = ftok((*semaphore).path, 1);
404: close(desc);
405:
406: if (clef == -1)
407: {
408: sys_free((*semaphore).path);
409: return(-1);
410: }
411:
412: (*semaphore).alloue = 0;
413: (*semaphore).sem = semget(clef, 1, IPC_CREAT | IPC_EXCL |
414: S_IRUSR | S_IWUSR);
415: }
416:
417: if ((*semaphore).sem == -1)
418: {
419: errno = EINVAL;
420: return(-1);
421: }
422:
423: argument.val = (int) valeur;
424: ios = semctl((*semaphore).sem, 0, SETVAL, argument);
425:
426: return(ios);
427: # else // OS/2
428: sem_t *psem;
429:
430: psem = semaphore;
431:
432: if (((*psem).cnt = sys_malloc(sizeof(ULONG))) == NULL)
433: {
434: sys_free(psem);
435: errno = ENOMEM;
436: return(-1);
437: }
438:
439: if (((*psem).nopened = sys_malloc(sizeof(ULONG))) == NULL)
440: {
441: sys_free((*psem).cnt);
442: sys_free(psem);
443: errno = ENOMEM;
444: return(-1);
445: }
446:
447: if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
448: {
449: sys_free((*psem).cnt);
450: sys_free((*psem).nopened);
451: sys_free(psem);
452: return(-1);
453: }
454:
455: if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0)
456: != 0)
457: {
458: DosCloseMutexSem((*psem).hmtx);
459: sys_free((*psem).cnt);
460: sys_free((*psem).nopened);
461: sys_free(psem);
462: return(-1);
463: }
464:
465: (*(*psem).cnt) = valeur;
466: (*(*psem).nopened) = 1;
467: (*psem).shared = shared;
468: (*psem).allocated = 0;
469:
470: return(0);
471: # endif
472: }
473:
474: int
475: sem_destroy_SysV(sem_t *semaphore)
476: {
477: // Détruit un sémaphore anonmyme
478:
479: # ifndef OS2 // IPCS_SYSV
480: if ((*semaphore).path != NULL)
481: {
482: return(EINVAL);
483: }
484:
485: if ((*semaphore).pid != getpid())
486: {
487: return(0);
488: }
489:
490: if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
491: {
492: return(EINVAL);
493: }
494:
495: return(0);
496: # else // OS/2
497: sem_t *psem;
498:
499: psem = semaphore;
500:
501: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
502: {
503: return(EINVAL);
504: }
505:
506: if (DosCloseMutexSem((*psem).hmtx) != 0)
507: {
508: return(EINVAL);
509: }
510:
511: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
512: {
513: DosPostEventSem((*psem).hev);
514: }
515:
516: (*(*psem).nopened)--;
517:
518: if ((*psem).shared == 0)
519: {
520: sys_free((*psem).cnt);
521: sys_free((*psem).nopened);
522: }
523: else
524: {
525: if ((*(*psem).nopened) == 0)
526: {
527: DosFreeMem((*psem).cnt);
528: }
529: }
530:
531: if ((*psem).allocated != 0)
532: {
533: sys_free(psem);
534: }
535:
536: return(0);
537: # endif
538: }
539:
540: int
541: sem_wait_SysV(sem_t *semaphore)
542: {
543: # ifndef OS2 // IPCS_SYSV
544: struct sembuf commande;
545:
546: // semop() ne renvoie pas EINTR sur un signal !
547:
548: commande.sem_num = 0;
549: commande.sem_op = -1;
550: commande.sem_flg = 0;
551:
552: if (semop((*semaphore).sem, &commande, 1) == -1)
553: {
554: if (errno != EAGAIN)
555: {
556: errno = EINVAL;
557: return(-1);
558: }
559: else
560: {
561: return(-1);
562: }
563: }
564:
565: return(0);
566: # else // OS/2
567: sem_t *psem;
568:
569: ULONG cnt;
570:
571: psem = semaphore;
572:
573: if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
574: {
575: errno = EINVAL;
576: return(-1);
577: }
578:
579: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
580: {
581: errno = EINVAL;
582: return(-1);
583: }
584:
585: if ((*(*psem).cnt) > 0)
586: {
587: (*(*psem).cnt)--;
588: }
589:
590: if ((*(*psem).cnt) == 0)
591: {
592: DosResetEventSem((*psem).hev, &cnt);
593: }
594:
595: DosReleaseMutexSem((*psem).hmtx);
596: return(0);
597: # endif
598: }
599:
600: int
601: sem_trywait_SysV(sem_t *semaphore)
602: {
603: # ifndef OS2 // IPCS_SYSV
604: struct sembuf commande;
605:
606: commande.sem_num = 0;
607: commande.sem_op = -1;
608: commande.sem_flg = IPC_NOWAIT;
609:
610: if (semop((*semaphore).sem, &commande, 1) == -1)
611: {
612: return(-1);
613: }
614:
615: return(0);
616: # else // OS/2
617: int ios;
618:
619: sem_t *psem;
620:
621: ULONG cnt;
622:
623: psem = semaphore;
624:
625: if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
626: {
627: errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
628: return(-1);
629: }
630:
631: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
632: {
633: errno = EINVAL;
634: return(-1);
635: }
636:
637: if ((*(*psem).cnt) > 0)
638: {
639: (*(*psem).cnt)--;
640: }
641:
642: if ((*(*psem).cnt) == 0)
643: {
644: DosResetEventSem((*psem).hev, &cnt);
645: }
646:
647: DosReleaseMutexSem((*psem).hmtx);
648: return(0);
649: # endif
650: }
651:
652: #ifndef timespeccmp
653: # define timespeccmp(tsp, usp, cmp) \
654: (((tsp)->tv_sec == (usp)->tv_sec) ? \
655: ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
656: ((tsp)->tv_sec cmp (usp)->tv_sec))
657: # define timespecadd(tsp, usp, vsp) \
658: do { \
659: (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
660: (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
661: if ((vsp)->tv_nsec >= 1000000000L) { \
662: (vsp)->tv_sec++; \
663: (vsp)->tv_nsec -= 1000000000L; \
664: } \
665: } while(0)
666: # define timespecsub(tsp, usp, vsp) \
667: do { \
668: (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
669: (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
670: if ((vsp)->tv_nsec < 0) { \
671: (vsp)->tv_sec--; \
672: (vsp)->tv_nsec += 1000000000L; \
673: } \
674: } while(0)
675: #endif
676:
677: int
678: sem_timedwait_SysV(sem_t *sem, struct timespec *ts)
679: {
680: struct timespec onems = { 0, 1000000 };
681: struct timespec total = { 0, 0 };
682: struct timespec unslept;
683: struct timespec elapsed;
684: struct timespec tmp;
685:
686: while(timespeccmp(ts, &total, >))
687: {
688: if (sem_trywait_SysV(sem) == 0)
689: {
690: return(0);
691: }
692:
693: if (errno != EAGAIN)
694: {
695: return(-1);
696: }
697:
698: nanosleep(&onems, &unslept);
699:
700: timespecsub(&onems, &unslept, &elapsed);
701: timespecadd(&total, &elapsed, &tmp);
702: total.tv_sec = tmp.tv_sec;
703: total.tv_nsec = tmp.tv_nsec;
704: }
705:
706: errno = ETIMEDOUT;
707: return(-1);
708: }
709:
710: int
711: sem_post_SysV(sem_t *semaphore)
712: {
713: # ifndef OS2 // IPCS_SYSV
714: struct sembuf commande;
715:
716: commande.sem_num = 0;
717: commande.sem_op = 1;
718: commande.sem_flg = 0;
719:
720: while(semop((*semaphore).sem, &commande, 1) == -1)
721: {
722: if (errno != EINTR)
723: {
724: errno = EINVAL;
725: return(-1);
726: }
727: }
728:
729: return(0);
730: # else // OS/2
731: sem_t *psem;
732:
733: psem = semaphore;
734:
735: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
736: {
737: errno = EINVAL;
738: return(-1);
739: }
740:
741: (*(*psem).cnt)++;
742: DosPostEventSem((*psem).hev);
743: DosReleaseMutexSem((*psem).hmtx);
744:
745: return(0);
746: # endif
747: }
748:
749: int
750: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
751: {
752: # ifndef OS2 // IPCS_SYSV
753: (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
754:
755: if ((*valeur) < 0)
756: {
757: return(EINVAL);
758: }
759:
760: return(0);
761: # else
762: sem_t *psem;
763:
764: psem = semaphore;
765:
766: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
767: {
768: errno = EINVAL;
769: return(-1);
770: }
771:
772: (*valeur) = (*(*psem).cnt);
773: DosReleaseMutexSem((*psem).hmtx);
774:
775: return(0);
776: # endif
777: }
778:
779: sem_t
780: *sem_open_SysV(const char *nom, int oflag, ...)
781: //*sem_open(const char *nom, int oflag)
782: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
783: {
784: mode_t mode;
785:
786: sem_t *semaphore;
787:
788: # ifndef OS2
789: int desc;
790:
791: key_t clef;
792:
793: union semun argument;
794:
795: unsigned char *langue;
796: # endif
797:
798: unsigned char *nom_absolu;
799:
800: unsigned int valeur;
801:
802: va_list liste;
803:
804: # ifdef OS2
805: sem_t *psem;
806:
807: PVOID base;
808:
809: unsigned char *ptr;
810: unsigned char *nom_segment;
811: # endif
812:
813: # ifndef OS2 // IPCS_SYSV
814: if ((nom_absolu = sys_malloc((strlen(racine_segment) + strlen(nom)
815: + 2) * sizeof(unsigned char))) == NULL)
816: {
817: return(SEM_FAILED);
818: }
819:
820: sprintf(nom_absolu, "%s/%s", racine_segment, nom);
821:
822: if ((semaphore = sys_malloc(sizeof(sem_t))) == NULL)
823: {
824: return(SEM_FAILED);
825: }
826:
827: (*semaphore).alloue = -1;
828: (*semaphore).pid = getpid();
829: (*semaphore).tid = pthread_self();
830: # else
831: if ((nom_segment = sys_malloc((strlen(racine_memoire_OS2) + strlen(nom)
832: + 1) * sizeof(unsigned char))) == NULL)
833: {
834: return(SEM_FAILED);
835: }
836:
837: sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
838: ptr = nom_segment;
839:
840: while((*ptr) != d_code_fin_chaine)
841: {
842: if ((*ptr) == '/')
843: {
844: (*ptr) = '\\';
845: }
846:
847: ptr++;
848: }
849:
850: if ((nom_absolu = sys_malloc((strlen(racine_semaphores_OS2) +
851: strlen(nom) + 2) * sizeof(unsigned char))) == NULL)
852: {
853: return(SEM_FAILED);
854: }
855:
856: sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);
857: ptr = nom_absolu;
858:
859: while((*ptr) != d_code_fin_chaine)
860: {
861: if ((*ptr) == '/')
862: {
863: (*ptr) = '\\';
864: }
865:
866: ptr++;
867: }
868:
869: (*(ptr + 1)) = d_code_fin_chaine;
870:
871: if ((psem = sys_malloc(sizeof(sem_t))) == NULL)
872: {
873: return(SEM_FAILED);
874: }
875:
876: (*psem).allocated = 1;
877: # endif
878:
879: if ((oflag & O_CREAT) == 0)
880: {
881: // 2 arguments
882:
883: # ifndef OS2 // IPCS_SYSV
884: clef = ftok(nom_absolu, 1);
885:
886: if (clef == -1)
887: {
888: return(SEM_FAILED);
889: }
890:
891: (*semaphore).sem = semget(clef, 0, 0);
892: (*semaphore).path = nom_absolu;
893: (*semaphore).pid = getpid();
894:
895: if ((*semaphore).sem == -1)
896: {
897: sys_free(semaphore);
898: sys_free(nom_absolu);
899:
900: return(SEM_FAILED);
901: }
902: # else // OS/2
903: if ((psem = sys_malloc(sizeof(sem_t))) == NULL)
904: {
905: sys_free(nom_absolu);
906: sys_free(nom_segment);
907: return(SEM_FAILED);
908: }
909:
910: (*ptr) = 'M';
911:
912: if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
913: {
914: sys_free(psem);
915: sys_free(nom_absolu);
916: sys_free(nom_segment);
917:
918: return(SEM_FAILED);
919: }
920:
921: (*ptr) = 'S';
922:
923: if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
924: {
925: DosCloseMutexSem((*psem).hmtx);
926:
927: sys_free(psem);
928: sys_free(nom_absolu);
929: sys_free(nom_segment);
930:
931: return(SEM_FAILED);
932: }
933:
934: if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ)
935: != 0)
936: {
937: DosCloseMutexSem((*psem).hmtx);
938:
939: sys_free(nom_absolu);
940: sys_free(nom_segment);
941: sys_free(psem);
942:
943: return(SEM_FAILED);
944: }
945:
946: sys_free(nom_segment);
947:
948: (*psem).cnt = (ULONG *) base;
949: (*psem).nopened = ((ULONG *) base) + 1;
950: (*psem).shared = 1;
951:
952: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
953: {
954: DosCloseMutexSem((*psem).hmtx);
955:
956: sys_free(nom_absolu);
957: sys_free(nom_segment);
958: sys_free(psem);
959:
960: return(SEM_FAILED);
961: }
962:
963: (*((*psem).nopened))++;
964:
965: DosReleaseMutexSem((*psem).hmtx);
966:
967: semaphore = psem;
968: # endif
969: }
970: else
971: {
972: // 4 arguments
973:
974: // O_CREAT O_EXCL
975: // S_IRUSR S_IWUSR
976:
977: va_start(liste, oflag);
978: mode = va_arg(liste, mode_t);
979: valeur = va_arg(liste, unsigned int);
980: va_end(liste);
981:
982: # ifndef OS2 // IPCS_SYSV
983: if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR,
984: S_IRUSR | S_IWUSR)) == -1)
985: {
986: if (errno != EEXIST)
987: {
988: sys_free(semaphore);
989: sys_free(nom_absolu);
990: return(SEM_FAILED);
991: }
992:
993: if ((langue = getenv("LANG")) != NULL)
994: {
995: if (strncmp(langue, "fr", 2) == 0)
996: {
997: uprintf("+++Attention : Le sémaphore %s préexiste !\n",
998: nom_absolu);
999: }
1000: else
1001: {
1002: uprintf("+++Warning: %s semaphore preexists!\n",
1003: nom_absolu);
1004: }
1005: }
1006: else
1007: {
1008: uprintf("+++Warning: %s semaphore preexists!\n",
1009: nom_absolu);
1010: }
1011:
1012: if ((desc = open(nom_absolu, O_CREAT | O_RDWR,
1013: S_IRUSR | S_IWUSR)) == -1)
1014: {
1015: sys_free(semaphore);
1016: sys_free(nom_absolu);
1017: return(SEM_FAILED);
1018: }
1019: }
1020:
1021: if ((clef = ftok(nom_absolu, 1)) == -1)
1022: {
1023: close(desc);
1024: sys_free(semaphore);
1025: sys_free(nom_absolu);
1026:
1027: return(SEM_FAILED);
1028: }
1029:
1030: close(desc);
1031:
1032: (*semaphore).sem = semget(clef, 1,
1033: (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |
1034: (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |
1035: (int) mode);
1036: (*semaphore).path = nom_absolu;
1037: (*semaphore).pid = getpid();
1038:
1039: if ((*semaphore).sem == -1)
1040: {
1041: sys_free(semaphore);
1042: sys_free(nom_absolu);
1043:
1044: return(SEM_FAILED);
1045: }
1046:
1047: argument.val = (int) valeur;
1048: semctl((*semaphore).sem, 0, SETVAL, argument);
1049: # else // OS/2
1050: if ((psem = sys_malloc(sizeof(sem_t))) == NULL)
1051: {
1052: sys_free(nom_absolu);
1053: sys_free(nom_segment);
1054:
1055: return(SEM_FAILED);
1056: }
1057:
1058: (*ptr) = 'M';
1059:
1060: if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
1061: {
1062: sys_free(psem);
1063: sys_free(nom_absolu);
1064: sys_free(nom_segment);
1065:
1066: return(SEM_FAILED);
1067: }
1068:
1069: (*ptr) = 'S';
1070:
1071: if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
1072: (valeur != 0) ? 1 : 0) != 0)
1073: {
1074: DosCloseMutexSem((*psem).hmtx);
1075:
1076: sys_free(nom_absolu);
1077: sys_free(nom_segment);
1078: sys_free(psem);
1079:
1080: return(SEM_FAILED);
1081: }
1082:
1083: if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
1084: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
1085: {
1086: DosCloseMutexSem((*psem).hmtx);
1087:
1088: sys_free(nom_absolu);
1089: sys_free(nom_segment);
1090: sys_free(psem);
1091:
1092: return(SEM_FAILED);
1093: }
1094:
1095: sys_free(nom_segment);
1096:
1097: (*psem).cnt = (ULONG *) base;
1098: (*psem).nopened = ((ULONG *) base) + 1;
1099: (*(*psem).cnt) = valeur;
1100: (*(*psem).nopened) = 1;
1101: (*psem).shared = 1;
1102: semaphore = psem;
1103: # endif
1104: }
1105:
1106: return(semaphore);
1107: }
1108:
1109: int
1110: sem_close_SysV(sem_t *semaphore)
1111: {
1112: // Ferme un sémaphore nommé créé par sem_open_SysV()
1113: # ifndef OS2 // IPCS_SYSV
1114: if ((*semaphore).path != NULL)
1115: {
1116: sys_free((*semaphore).path);
1117: }
1118:
1119: if ((*semaphore).alloue == -1)
1120: {
1121: sys_free(semaphore);
1122: }
1123:
1124: return(0);
1125: # else
1126: sem_t *psem;
1127:
1128: psem = semaphore;
1129:
1130: if (DosCloseMutexSem((*psem).hmtx) != 0)
1131: {
1132: return(EINVAL);
1133: }
1134:
1135: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
1136: {
1137: DosPostEventSem((*psem).hev);
1138: }
1139:
1140: (*(*psem).nopened)--;
1141:
1142: if ((*psem).shared == 0)
1143: {
1144: sys_free((*psem).cnt);
1145: sys_free((*psem).nopened);
1146: }
1147: else
1148: {
1149: if ((*(*psem).nopened) == 0)
1150: {
1151: DosFreeMem((*psem).cnt);
1152: }
1153: }
1154:
1155: if ((*psem).allocated != 0)
1156: {
1157: sys_free(psem);
1158: }
1159:
1160: return(0);
1161: # endif
1162: }
1163:
1164: int
1165: sem_unlink_SysV(char *nom)
1166: {
1167: // Détruit un sémaphore nommé créé par sem_open_SysV()
1168: # ifndef OS2 // IPCS_SYSV
1169: semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID);
1170:
1171: if (unlink(nom) == -1)
1172: {
1173: return(EACCES);
1174: }
1175:
1176: sys_free(nom);
1177: return(0);
1178: # else
1179: return(0);
1180: # endif
1181: }
1182:
1183: #endif
1184:
1185: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>