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