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