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