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