--- rpl/src/semaphores.c 2011/06/21 15:26:35 1.22 +++ rpl/src/semaphores.c 2020/01/10 11:15:51 1.89 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.0.prerelease.2 - Copyright (C) 1989-2011 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.32 + Copyright (C) 1989-2020 Dr. BERTRAND Joël This file is part of RPL/2. @@ -22,7 +22,41 @@ #include "rpl-conv.h" -#ifdef SEMAPHORES_NOMMES + +// Les fonctions suivantes ne sont utilisées que dans le cas d'un +// système POSIX qui ne possède pas de sémaphores anonymes. MacOS X +// est dans ce cas. + +static unsigned char * +nom_segment_semaphore(pid_t pid, int ordre) +{ + unsigned char *fichier; + + if ((fichier = sys_malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL) + { + return(NULL); + } + + sprintf(fichier, "/RPL-%llu-%d", (unsigned long long) pid, ordre); + return(fichier); +} + + +static unsigned char * +nom_segment_semaphore_thread(pid_t pid, pthread_t tid, int ordre) +{ + unsigned char *fichier; + + if ((fichier = sys_malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL) + { + return(NULL); + } + + sprintf(fichier, "/RPL-%llu-%llu-%d", (unsigned long long) pid, + (unsigned long long) tid, ordre); + return(fichier); +} + /* ================================================================================ @@ -37,75 +71,235 @@ */ sem_t * -sem_init2(unsigned int valeur, enum t_semaphore semaphore) +sem_init2(unsigned int valeur, pid_t pid, int ordre) +{ + sem_t *semaphore; + + unsigned char *chemin; + unsigned char *langue; + + if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL) + { + return(SEM_FAILED); + } + + if ((semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR, valeur)) == SEM_FAILED) + { + if (errno == EEXIST) + { + if ((langue = getenv("LANG")) != NULL) + { + if (strncmp(langue, "fr", 2) == 0) + { + uprintf("+++Attention : Le sémaphore %s préexiste !\n", + chemin); + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", chemin); + } + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", chemin); + } + + if (sem_unlink(chemin) != 0) + { + sys_free(chemin); + return(SEM_FAILED); + } + + semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR, valeur); + } + } + + sys_free(chemin); + + return(semaphore); +} + + +sem_t * +sem_init3(unsigned int valeur, pid_t pid, pthread_t tid, int ordre) +{ + sem_t *semaphore; + + unsigned char *chemin; + unsigned char *langue; + + if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL) + { + return(SEM_FAILED); + } + + if ((semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR, valeur)) == SEM_FAILED) + { + if (errno == EEXIST) + { + if ((langue = getenv("LANG")) != NULL) + { + if (strncmp(langue, "fr", 2) == 0) + { + uprintf("+++Attention : Le sémaphore %s préexiste !\n", + chemin); + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", chemin); + } + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", chemin); + } + + semaphore = sem_open(chemin, O_RDWR | O_CREAT, + S_IRUSR | S_IWUSR, valeur); + } + } + + sys_free(chemin); + + return(semaphore); +} + + +sem_t * +sem_open2(pid_t pid, int ordre) +{ + unsigned char *chemin; + + sem_t *semaphore; + + if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL) + { + return(SEM_FAILED); + } + + semaphore = sem_open(chemin, O_RDWR); + sys_free(chemin); + + return(semaphore); +} + + +int +sem_destroy2(sem_t *semaphore, pid_t pid, int ordre) { - snprintf(noms_semaphores[semaphore], LONGUEUR_NOM_SEMAPHORE, - "/RPL-SEM-%d-%llu-%d", (int) getpid(), - (unsigned long long) pthread_self(), - (int) semaphore); - return(sem_open(noms_semaphores[semaphore], O_CREAT, - (S_IRUSR | S_IWUSR), valeur)); + int erreur; + + unsigned char *chemin; + + sem_close(semaphore); + + if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL) + { + return(1); + } + + erreur = sem_unlink(chemin); + sys_free(chemin); + + return(erreur); } + int -sem_destroy2(sem_t *semaphore_p, enum t_semaphore semaphore) +sem_destroy3(sem_t *semaphore, pid_t pid, pthread_t tid, int ordre) { - sem_close(semaphore_p); - return(sem_unlink(noms_semaphores[semaphore])); + int erreur; + + unsigned char *chemin; + + sem_close(semaphore); + + if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL) + { + return(1); + } + + erreur = sem_unlink(chemin); + sys_free(chemin); + + return(erreur); } -#undef sem_post -#undef sem_wait -#undef sem_trywait int sem_getvalue2(sem_t *semaphore, int *valeur) { int i; + int j; logical1 drapeau_fin; - pthread_mutex_lock(&mutex_sem); + struct timespec attente; - (*valeur) = 0; - drapeau_fin = d_faux; + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; - do + for(j = 0; j < 100; j++) { - if (sem_trywait(semaphore) == -1) + if (pthread_mutex_trylock(&mutex_sem) == 0) { - if (errno == EAGAIN) + (*valeur) = 0; + drapeau_fin = d_faux; + + do { - // Le sémaphore avait une valeur nulle - drapeau_fin = d_vrai; - } - else + if (sem_trywait(semaphore) == -1) + { + if (errno == EAGAIN) + { + // Le sémaphore avait une valeur nulle + drapeau_fin = d_vrai; + } + else + { + // Autre erreur + pthread_mutex_unlock(&mutex_sem); + return(-1); + } + } + else + { + (*valeur)++; + } + } while(drapeau_fin == d_faux); + + for(i = 0; i < (*valeur); i++) { - // Autre erreur - pthread_mutex_unlock(&mutex_sem); - return(-1); + if (sem_post(semaphore) != 0) + { + pthread_mutex_unlock(&mutex_sem); + return(-1); + } } - } - else - { - (*valeur)++; - } - } while(drapeau_fin == d_faux); - for(i = 0; i < (*valeur); i++) - { - if (sem_post(semaphore) != 0) - { pthread_mutex_unlock(&mutex_sem); - return(-1); + return(0); } + + nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); } - pthread_mutex_unlock(&mutex_sem); + // Le mutex n'a pas pu être verrouillé. On peut raisonnablement penser + // que le sémaphore est bloqué dans un sem_wait() protégé par ce mutex. + + (*valeur) = 0; return(0); } -#endif + +#undef sem_post +#undef sem_wait +#undef sem_trywait + #ifdef IPCS_SYSV @@ -121,9 +315,9 @@ sem_getvalue2(sem_t *semaphore, int *val ================================================================================ */ -#ifndef OS2 - extern unsigned char *chemin_semaphores_SysV; -#else +#ifndef OS2 // IPCS_SYSV + extern unsigned char *racine_segment; +#else // OS/2 unsigned char racine_semaphores_OS2[] = "\\SEM32\\"; unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\"; #endif @@ -133,85 +327,147 @@ sem_init_SysV(sem_t *semaphore, int shar { // Création d'un sémaphore anonyme qui devra être supprimé par // sem_destroy_SysV -# ifndef OS2 - int ios; +# ifndef OS2 // IPCS_SYSV + int desc; + int ios; - union semun argument; + key_t clef; - if (shared != 0) - { - errno = ENOSYS; - return(-1); - } + union semun argument; - (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | - S_IRUSR | S_IWUSR); - (*semaphore).path = NULL; - (*semaphore).pid = getpid(); + unsigned char *langue; - if ((*semaphore).sem == -1) - { - errno = EINVAL; - return(-1); - } + if (shared == 0) + { + // Sémaphore privé + (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | + S_IRUSR | S_IWUSR); + (*semaphore).path = NULL; + (*semaphore).pid = getpid(); + (*semaphore).tid = pthread_self(); + (*semaphore).alloue = 0; + } + else + { + // Sémaphore partagé entre plusieurs processus + if (((*semaphore).path = sys_malloc((strlen(racine_segment) + + 2 + 256 + 1) * sizeof(unsigned char))) == NULL) + { + return(-1); + } - argument.val = valeur; - ios = semctl((*semaphore).sem, 0, SETVAL, argument); + sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%llX", + racine_segment, (int) getpid(), + (long long unsigned) pthread_self(), + (long long unsigned) semaphore); - return(ios); + if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR)) == -1) + { + if (errno != EEXIST) + { + sys_free((*semaphore).path); + return(-1); + } + + if ((langue = getenv("LANG")) != NULL) + { + if (strncmp(langue, "fr", 2) == 0) + { + uprintf("+++Attention : Le sémaphore %s préexiste !\n", + (*semaphore).path); + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", + (*semaphore).path); + } + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", + (*semaphore).path); + } + + if ((desc = open((*semaphore).path, O_RDWR | O_CREAT, + S_IRUSR | S_IWUSR)) == -1) + { + sys_free((*semaphore).path); + return(-1); + } + } -# else + (*semaphore).pid = getpid(); + (*semaphore).tid = pthread_self(); + clef = ftok((*semaphore).path, 1); + close(desc); - sem_t *psem; + if (clef == -1) + { + sys_free((*semaphore).path); + return(-1); + } - psem = semaphore; + (*semaphore).alloue = 0; + (*semaphore).sem = semget(clef, 1, IPC_CREAT | IPC_EXCL | + S_IRUSR | S_IWUSR); + } - if (shared != 0) - { - errno = ENOSYS; - return(-1); - } + if ((*semaphore).sem == -1) + { + errno = EINVAL; + return(-1); + } - if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL) - { - free(psem); - errno = ENOMEM; - return(-1); - } + argument.val = (int) valeur; + ios = semctl((*semaphore).sem, 0, SETVAL, argument); - if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL) - { - free((*psem).cnt); - free(psem); - errno = ENOMEM; - return(-1); - } + return(ios); +# else // OS/2 + sem_t *psem; - if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0) - { - free((*psem).cnt); - free((*psem).nopened); - free(psem); - return(-1); - } + psem = semaphore; - if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0) != 0) - { - DosCloseMutexSem((*psem).hmtx); - free((*psem).cnt); - free((*psem).nopened); - free(psem); - return(-1); - } + if (((*psem).cnt = sys_malloc(sizeof(ULONG))) == NULL) + { + sys_free(psem); + errno = ENOMEM; + return(-1); + } - (*(*psem).cnt) = valeur; - (*(*psem).nopened) = 1; - (*psem).shared = shared; - (*psem).allocated = 0; + if (((*psem).nopened = sys_malloc(sizeof(ULONG))) == NULL) + { + sys_free((*psem).cnt); + sys_free(psem); + errno = ENOMEM; + return(-1); + } - return(0); + if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0) + { + sys_free((*psem).cnt); + sys_free((*psem).nopened); + sys_free(psem); + return(-1); + } + + if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0) + != 0) + { + DosCloseMutexSem((*psem).hmtx); + sys_free((*psem).cnt); + sys_free((*psem).nopened); + sys_free(psem); + return(-1); + } + + (*(*psem).cnt) = valeur; + (*(*psem).nopened) = 1; + (*psem).shared = shared; + (*psem).allocated = 0; + return(0); # endif } @@ -219,263 +475,304 @@ int sem_destroy_SysV(sem_t *semaphore) { // Détruit un sémaphore anonmyme -# ifndef OS2 - - if ((*semaphore).path != NULL) - { - return(EINVAL); - } - - if ((*semaphore).pid != getpid()) - { - return(0); - } - if (semctl((*semaphore).sem, 0, IPC_RMID) == -1) - { - return(EINVAL); - } +# ifndef OS2 // IPCS_SYSV + if ((*semaphore).path != NULL) + { + return(EINVAL); + } - return(0); + if ((*semaphore).pid != getpid()) + { + return(0); + } -# else + if (semctl((*semaphore).sem, 0, IPC_RMID) == -1) + { + return(EINVAL); + } - sem_t *psem; + return(0); +# else // OS/2 + sem_t *psem; - psem = semaphore; + psem = semaphore; - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - return(EINVAL); - } + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + return(EINVAL); + } - if (DosCloseMutexSem((*psem).hmtx) != 0) - { - return(EINVAL); - } + if (DosCloseMutexSem((*psem).hmtx) != 0) + { + return(EINVAL); + } - while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY) - { - DosPostEventSem((*psem).hev); - } + while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY) + { + DosPostEventSem((*psem).hev); + } - (*(*psem).nopened)--; + (*(*psem).nopened)--; - if ((*psem).shared == 0) - { - free((*psem).cnt); - free((*psem).nopened); - } - else - { - if ((*(*psem).nopened) == 0) + if ((*psem).shared == 0) { - DosFreeMem((*psem).cnt); + sys_free((*psem).cnt); + sys_free((*psem).nopened); + } + else + { + if ((*(*psem).nopened) == 0) + { + DosFreeMem((*psem).cnt); + } } - } - - if ((*psem).allocated != 0) - { - free(psem); - } - return(0); + if ((*psem).allocated != 0) + { + sys_free(psem); + } + return(0); # endif } int sem_wait_SysV(sem_t *semaphore) { -# ifndef OS2 +# ifndef OS2 // IPCS_SYSV + struct sembuf commande; - struct sembuf commande; + // semop() ne renvoie pas EINTR sur un signal ! - commande.sem_num = 0; - commande.sem_op = -1; - commande.sem_flg = 0; + commande.sem_num = 0; + commande.sem_op = -1; + commande.sem_flg = 0; - while(semop((*semaphore).sem, &commande, 1) == -1) - { - if (errno != EINTR) + if (semop((*semaphore).sem, &commande, 1) == -1) { - errno = EINVAL; - return(-1); + if (errno != EAGAIN) + { + errno = EINVAL; + return(-1); + } + else + { + return(-1); + } } - } - - return(0); -# else - - sem_t *psem; - - ULONG cnt; + return(0); +# else // OS/2 + sem_t *psem; - psem = semaphore; + ULONG cnt; - if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0) - { - errno = EINVAL; - return(-1); - } + psem = semaphore; - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - errno = EINVAL; - return(-1); - } + if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0) + { + errno = EINVAL; + return(-1); + } - if ((*(*psem).cnt) > 0) - { - (*(*psem).cnt)--; - } + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + errno = EINVAL; + return(-1); + } - if ((*(*psem).cnt) == 0) - { - DosResetEventSem((*psem).hev, &cnt); - } + if ((*(*psem).cnt) > 0) + { + (*(*psem).cnt)--; + } - DosReleaseMutexSem((*psem).hmtx); - return(0); + if ((*(*psem).cnt) == 0) + { + DosResetEventSem((*psem).hev, &cnt); + } + DosReleaseMutexSem((*psem).hmtx); + return(0); # endif } int sem_trywait_SysV(sem_t *semaphore) { -# ifndef OS2 - - struct sembuf commande; +# ifndef OS2 // IPCS_SYSV + struct sembuf commande; - commande.sem_num = 0; - commande.sem_op = -1; - commande.sem_flg = IPC_NOWAIT; + commande.sem_num = 0; + commande.sem_op = -1; + commande.sem_flg = IPC_NOWAIT; - while(semop((*semaphore).sem, &commande, 1) == -1) - { - if (errno != EINTR) + if (semop((*semaphore).sem, &commande, 1) == -1) { - errno = EINVAL; return(-1); } - } - - return(0); - -# else - - int ios; - sem_t *psem; + return(0); +# else // OS/2 + int ios; - ULONG cnt; + sem_t *psem; - psem = semaphore; + ULONG cnt; - if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0) - { - errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL; - return(-1); - } + psem = semaphore; - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - errno = EINVAL; - return(-1); - } + if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0) + { + errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL; + return(-1); + } - if ((*(*psem).cnt) > 0) - { - (*(*psem).cnt)--; - } + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + errno = EINVAL; + return(-1); + } - if ((*(*psem).cnt) == 0) - { - DosResetEventSem((*psem).hev, &cnt); - } + if ((*(*psem).cnt) > 0) + { + (*(*psem).cnt)--; + } - DosReleaseMutexSem((*psem).hmtx); - return(0); + if ((*(*psem).cnt) == 0) + { + DosResetEventSem((*psem).hev, &cnt); + } + DosReleaseMutexSem((*psem).hmtx); + return(0); # endif } +#ifndef timespeccmp +# define timespeccmp(tsp, usp, cmp) \ + (((tsp)->tv_sec == (usp)->tv_sec) ? \ + ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ + ((tsp)->tv_sec cmp (usp)->tv_sec)) +# define timespecadd(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \ + if ((vsp)->tv_nsec >= 1000000000L) { \ + (vsp)->tv_sec++; \ + (vsp)->tv_nsec -= 1000000000L; \ + } \ + } while(0) +# define timespecsub(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \ + if ((vsp)->tv_nsec < 0) { \ + (vsp)->tv_sec--; \ + (vsp)->tv_nsec += 1000000000L; \ + } \ + } while(0) +#endif + int -sem_post_SysV(sem_t *semaphore) +sem_timedwait_SysV(sem_t *sem, struct timespec *ts) { -# ifndef OS2 - - struct sembuf commande; + struct timespec onems = { 0, 1000000 }; + struct timespec total = { 0, 0 }; + struct timespec unslept; + struct timespec elapsed; + struct timespec tmp; - commande.sem_num = 0; - commande.sem_op = 1; - commande.sem_flg = 0; - - while(semop((*semaphore).sem, &commande, 1) == -1) + while(timespeccmp(ts, &total, >)) { - if (errno != EINTR) + if (sem_trywait_SysV(sem) == 0) + { + return(0); + } + + if (errno != EAGAIN) { - errno = EINVAL; return(-1); } + + nanosleep(&onems, &unslept); + + timespecsub(&onems, &unslept, &elapsed); + timespecadd(&total, &elapsed, &tmp); + total.tv_sec = tmp.tv_sec; + total.tv_nsec = tmp.tv_nsec; } - return(0); + errno = ETIMEDOUT; + return(-1); +} -# else +int +sem_post_SysV(sem_t *semaphore) +{ +# ifndef OS2 // IPCS_SYSV + struct sembuf commande; - sem_t *psem; + commande.sem_num = 0; + commande.sem_op = 1; + commande.sem_flg = 0; - psem = semaphore; + while(semop((*semaphore).sem, &commande, 1) == -1) + { + if (errno != EINTR) + { + errno = EINVAL; + return(-1); + } + } - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - errno = EINVAL; - return(-1); - } + return(0); +# else // OS/2 + sem_t *psem; - (*(*psem).cnt)++; - DosPostEventSem((*psem).hev); - DosReleaseMutexSem((*psem).hmtx); + psem = semaphore; - return(0); + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + errno = EINVAL; + return(-1); + } + (*(*psem).cnt)++; + DosPostEventSem((*psem).hev); + DosReleaseMutexSem((*psem).hmtx); + + return(0); # endif } int sem_getvalue_SysV(sem_t *semaphore, int *valeur) { -# ifndef OS2 +# ifndef OS2 // IPCS_SYSV + (*valeur) = semctl((*semaphore).sem, 0, GETVAL); - (*valeur) = semctl((*semaphore).sem, 0, GETVAL); - - if ((*valeur) < 0) - { - return(EINVAL); - } - - return(0); + if ((*valeur) < 0) + { + return(EINVAL); + } + return(0); # else + sem_t *psem; - sem_t *psem; + psem = semaphore; - psem = semaphore; - - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - errno = EINVAL; - return(-1); - } - - (*valeur) = (*(*psem).cnt); - DosReleaseMutexSem((*psem).hmtx); + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + errno = EINVAL; + return(-1); + } - return(0); + (*valeur) = (*(*psem).cnt); + DosReleaseMutexSem((*psem).hmtx); + return(0); # endif } @@ -489,11 +786,13 @@ sem_t sem_t *semaphore; # ifndef OS2 - file *desc; + int desc; - key_t clef; + key_t clef; - union semun argument; + union semun argument; + + unsigned char *langue; # endif unsigned char *nom_absolu; @@ -503,172 +802,169 @@ sem_t va_list liste; # ifdef OS2 - sem_t *psem; + sem_t *psem; - PVOID base; + PVOID base; - unsigned char *ptr; - unsigned char *nom_segment; + unsigned char *ptr; + unsigned char *nom_segment; # endif -# ifndef OS2 - - if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom) - + 1) * sizeof(unsigned char))) == NULL) - { - return(SEM_FAILED); - } +# ifndef OS2 // IPCS_SYSV + if ((nom_absolu = sys_malloc((strlen(racine_segment) + strlen(nom) + + 2) * sizeof(unsigned char))) == NULL) + { + return(SEM_FAILED); + } - sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom); + sprintf(nom_absolu, "%s/%s", racine_segment, nom); - if ((semaphore = malloc(sizeof(sem_t))) == NULL) - { - return(SEM_FAILED); - } + if ((semaphore = sys_malloc(sizeof(sem_t))) == NULL) + { + return(SEM_FAILED); + } + (*semaphore).alloue = -1; + (*semaphore).pid = getpid(); + (*semaphore).tid = pthread_self(); # else - - if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1) - * sizeof(unsigned char))) == NULL) - { - return(SEM_FAILED); - } - - sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom); - ptr = nom_segment; - - while((*ptr) != d_code_fin_chaine) - { - if ((*ptr) == '/') + if ((nom_segment = sys_malloc((strlen(racine_memoire_OS2) + strlen(nom) + + 1) * sizeof(unsigned char))) == NULL) { - (*ptr) = '\\'; - } + return(SEM_FAILED); + } - ptr++; - } + sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom); + ptr = nom_segment; - if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom) - + 2) * sizeof(unsigned char))) == NULL) - { - return(SEM_FAILED); - } + while((*ptr) != d_code_fin_chaine) + { + if ((*ptr) == '/') + { + (*ptr) = '\\'; + } - sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom); - ptr = nom_absolu; + ptr++; + } - while((*ptr) != d_code_fin_chaine) - { - if ((*ptr) == '/') + if ((nom_absolu = sys_malloc((strlen(racine_semaphores_OS2) + + strlen(nom) + 2) * sizeof(unsigned char))) == NULL) { - (*ptr) = '\\'; + return(SEM_FAILED); } - ptr++; - } + sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom); + ptr = nom_absolu; - (*(ptr + 1)) = d_code_fin_chaine; + while((*ptr) != d_code_fin_chaine) + { + if ((*ptr) == '/') + { + (*ptr) = '\\'; + } - if ((psem = malloc(sizeof(sem_t))) == NULL) - { - return(SEM_FAILED); - } + ptr++; + } - (*psem).allocated = 1; + (*(ptr + 1)) = d_code_fin_chaine; + if ((psem = sys_malloc(sizeof(sem_t))) == NULL) + { + return(SEM_FAILED); + } + + (*psem).allocated = 1; # endif if ((oflag & O_CREAT) == 0) { // 2 arguments -# ifndef OS2 - - clef = ftok(nom_absolu, 1); +# ifndef OS2 // IPCS_SYSV + clef = ftok(nom_absolu, 1); - if (clef == -1) - { - return(SEM_FAILED); - } - - (*semaphore).sem = semget(clef, 0, 0); - (*semaphore).path = nom_absolu; - (*semaphore).pid = getpid(); - - if ((*semaphore).sem == -1) - { - free(semaphore); - free(nom_absolu); - - return(SEM_FAILED); - } + if (clef == -1) + { + return(SEM_FAILED); + } -# else + (*semaphore).sem = semget(clef, 0, 0); + (*semaphore).path = nom_absolu; + (*semaphore).pid = getpid(); + + if ((*semaphore).sem == -1) + { + sys_free(semaphore); + sys_free(nom_absolu); - if ((psem = malloc(sizeof(sem_t))) == NULL) - { - free(nom_absolu); - free(nom_segment); - return(SEM_FAILED); - } + return(SEM_FAILED); + } +# else // OS/2 + if ((psem = sys_malloc(sizeof(sem_t))) == NULL) + { + sys_free(nom_absolu); + sys_free(nom_segment); + return(SEM_FAILED); + } - (*ptr) = 'M'; + (*ptr) = 'M'; - if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0) - { - free(psem); - free(nom_absolu); - free(nom_segment); + if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0) + { + sys_free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); - return(SEM_FAILED); - } + return(SEM_FAILED); + } - (*ptr) = 'S'; + (*ptr) = 'S'; - if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0) - { - DosCloseMutexSem((*psem).hmtx); + if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0) + { + DosCloseMutexSem((*psem).hmtx); - free(psem); - free(nom_absolu); - free(nom_segment); + sys_free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); - return(SEM_FAILED); - } + return(SEM_FAILED); + } - if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ) != 0) - { - DosCloseMutexSem((*psem).hmtx); + if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ) + != 0) + { + DosCloseMutexSem((*psem).hmtx); - free(nom_absolu); - free(nom_segment); - free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); + sys_free(psem); - return(SEM_FAILED); - } + return(SEM_FAILED); + } - free(nom_segment); + sys_free(nom_segment); - (*psem).cnt = (ULONG *) base; - (*psem).nopened = ((ULONG *) base) + 1; - (*psem).shared = 1; + (*psem).cnt = (ULONG *) base; + (*psem).nopened = ((ULONG *) base) + 1; + (*psem).shared = 1; - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - DosCloseMutexSem((*psem).hmtx); - - free(nom_absolu); - free(nom_segment); - free(psem); + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + DosCloseMutexSem((*psem).hmtx); - return(SEM_FAILED); - } + sys_free(nom_absolu); + sys_free(nom_segment); + sys_free(psem); - (*((*psem).nopened))++; + return(SEM_FAILED); + } - DosReleaseMutexSem((*psem).hmtx); + (*((*psem).nopened))++; - semaphore = psem; + DosReleaseMutexSem((*psem).hmtx); + semaphore = psem; # endif } else @@ -683,100 +979,127 @@ sem_t valeur = va_arg(liste, unsigned int); va_end(liste); -# ifndef OS2 - - if ((desc = fopen(nom_absolu, "w")) == NULL) - { - free(semaphore); - free(nom_absolu); - - return(SEM_FAILED); - } - - fclose(desc); - - if ((clef = ftok(nom_absolu, 1)) == -1) - { - free(semaphore); - free(nom_absolu); - - return(SEM_FAILED); - } - - (*semaphore).sem = semget(clef, 1, - (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) | - (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) | - (int) mode); - (*semaphore).path = nom_absolu; - (*semaphore).pid = getpid(); +# ifndef OS2 // IPCS_SYSV + if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR, + S_IRUSR | S_IWUSR)) == -1) + { + if (errno != EEXIST) + { + sys_free(semaphore); + sys_free(nom_absolu); + return(SEM_FAILED); + } + + if ((langue = getenv("LANG")) != NULL) + { + if (strncmp(langue, "fr", 2) == 0) + { + uprintf("+++Attention : Le sémaphore %s préexiste !\n", + nom_absolu); + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", + nom_absolu); + } + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", + nom_absolu); + } + + if ((desc = open(nom_absolu, O_CREAT | O_RDWR, + S_IRUSR | S_IWUSR)) == -1) + { + sys_free(semaphore); + sys_free(nom_absolu); + return(SEM_FAILED); + } + } - if ((*semaphore).sem == -1) - { - free(semaphore); - free(nom_absolu); + if ((clef = ftok(nom_absolu, 1)) == -1) + { + close(desc); + sys_free(semaphore); + sys_free(nom_absolu); - return(SEM_FAILED); - } + return(SEM_FAILED); + } - argument.val = valeur; - semctl((*semaphore).sem, 0, SETVAL, argument); + close(desc); -# else + (*semaphore).sem = semget(clef, 1, + (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) | + (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) | + (int) mode); + (*semaphore).path = nom_absolu; + (*semaphore).pid = getpid(); + + if ((*semaphore).sem == -1) + { + sys_free(semaphore); + sys_free(nom_absolu); - if ((psem = malloc(sizeof(sem_t))) == NULL) - { - free(nom_absolu); - free(nom_segment); + return(SEM_FAILED); + } - return(SEM_FAILED); - } + argument.val = (int) valeur; + semctl((*semaphore).sem, 0, SETVAL, argument); +# else // OS/2 + if ((psem = sys_malloc(sizeof(sem_t))) == NULL) + { + sys_free(nom_absolu); + sys_free(nom_segment); - (*ptr) = 'M'; + return(SEM_FAILED); + } - if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0) - { - free(psem); - free(nom_absolu); - free(nom_segment); + (*ptr) = 'M'; - return(SEM_FAILED); - } + if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0) + { + sys_free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); - (*ptr) = 'S'; + return(SEM_FAILED); + } - if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0, - (valeur != 0) ? 1 : 0) != 0) - { - DosCloseMutexSem((*psem).hmtx); + (*ptr) = 'S'; - free(nom_absolu); - free(nom_segment); - free(psem); + if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0, + (valeur != 0) ? 1 : 0) != 0) + { + DosCloseMutexSem((*psem).hmtx); - return(SEM_FAILED); - } + sys_free(nom_absolu); + sys_free(nom_segment); + sys_free(psem); - if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG), - PAG_WRITE | PAG_READ | PAG_COMMIT) != 0) - { - DosCloseMutexSem((*psem).hmtx); + return(SEM_FAILED); + } - free(nom_absolu); - free(nom_segment); - free(psem); + if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG), + PAG_WRITE | PAG_READ | PAG_COMMIT) != 0) + { + DosCloseMutexSem((*psem).hmtx); - return(SEM_FAILED); - } + sys_free(nom_absolu); + sys_free(nom_segment); + sys_free(psem); - free(nom_segment); + return(SEM_FAILED); + } - (*psem).cnt = (ULONG *) base; - (*psem).nopened = ((ULONG *) base) + 1; - (*(*psem).cnt) = valeur; - (*(*psem).nopened) = 1; - (*psem).shared = 1; - semaphore = psem; + sys_free(nom_segment); + (*psem).cnt = (ULONG *) base; + (*psem).nopened = ((ULONG *) base) + 1; + (*(*psem).cnt) = valeur; + (*(*psem).nopened) = 1; + (*psem).shared = 1; + semaphore = psem; # endif } @@ -787,88 +1110,73 @@ int sem_close_SysV(sem_t *semaphore) { // Ferme un sémaphore nommé créé par sem_open_SysV() -# ifndef OS2 - - if ((*semaphore).path != NULL) - { - free((*semaphore).path); - } +# ifndef OS2 // IPCS_SYSV + if ((*semaphore).path != NULL) + { + sys_free((*semaphore).path); + } - free(semaphore); - return(0); + if ((*semaphore).alloue == -1) + { + sys_free(semaphore); + } + return(0); # else + sem_t *psem; - sem_t *psem; + psem = semaphore; - psem = semaphore; - - if (DosCloseMutexSem((*psem).hmtx) != 0) - { - return(EINVAL); - } + if (DosCloseMutexSem((*psem).hmtx) != 0) + { + return(EINVAL); + } - while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY) - { - DosPostEventSem((*psem).hev); - } + while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY) + { + DosPostEventSem((*psem).hev); + } - (*(*psem).nopened)--; + (*(*psem).nopened)--; - if ((*psem).shared == 0) - { - free((*psem).cnt); - free((*psem).nopened); - } - else - { - if ((*(*psem).nopened) == 0) + if ((*psem).shared == 0) { - DosFreeMem((*psem).cnt); + sys_free((*psem).cnt); + sys_free((*psem).nopened); + } + else + { + if ((*(*psem).nopened) == 0) + { + DosFreeMem((*psem).cnt); + } } - } - - if ((*psem).allocated != 0) - { - free(psem); - } - return(0); + if ((*psem).allocated != 0) + { + sys_free(psem); + } + return(0); # endif } int -sem_unlink_SysV(const char *nom) +sem_unlink_SysV(char *nom) { // Détruit un sémaphore nommé créé par sem_open_SysV() -# ifndef OS2 - - unsigned char *nom_absolu; - - if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom) - + 1) * sizeof(unsigned char))) == NULL) - { - return(ENOMEM); - } - - sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom); - semctl(semget(ftok(nom_absolu, 1), 0, 0), 0, IPC_RMID); - - if (unlink(nom_absolu) == -1) - { - free(nom_absolu); - return(EACCES); - } - - free(nom_absolu); +# ifndef OS2 // IPCS_SYSV + semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID); - return(0); + if (unlink(nom) == -1) + { + return(EACCES); + } + sys_free(nom); + return(0); # else - - return(0); - + return(0); # endif }