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