SEMCTL(2)

NOM
semctl - Opérations de contrôle sur les sémaphores System V

SYNOPSIS
#include <sys/sem.h>

int semctl(int semid, int semnum, int cmd, ...);

DESCRIPTION
Cette fonction effectue l'opération de contrôle indiquée par cmd sur l'ensemble de sémaphores System V (ou sur le semnum-ième sémaphore de l'ensemble) identifié par semid. (Les sémaphores sont numérotés à partir de zéro.)

La fonction a trois ou quatre arguments, selon la valeur de cmd. Quand il y en a quatre, le quatrième est de type union semun. Le programme appelant doit définir cette union de la façon suivante :

    union semun {
        int              val;    /* Valeur pour SETVAL */
        struct semid_ds *buf;    /* Tampon pour IPC_STAT, IPC_SET */
        unsigned short  *array;  /* Tableau pour GETALL, SETALL */
        struct seminfo  *__buf;  /* Tampon pour IPC_INFO
                                    (spécifique à Linux) */
    };

La structure semid_ds est définie dans <sys/sem.h> comme suit :

    struct semid_ds {
        struct ipc_perm sem_perm;   /* Permissions d'accès */
        time_t          sem_otime;  /* Heure dernier semop() */
        time_t          sem_ctime;  /* Heure de création/heure du */
                                       dernier changement avec semctl() */
        unsigned long   sem_nsems;  /* Nombre de sémaphores dans l'ensemble */
    };

Les champs de la structure semid_ds sont les suivants :

sem_perm
    Il s'agit d'une structure ipc_perm (voir plus bas) qui spécifie les d'accès sur le jeu de sémaphores.

sem_otime
    Heure du dernier appel système semop(2).

sem_ctime
    Heure de création du jeu de sémaphores ou heure de la dernière opération IPCSET, SETVAL ou SETALL de semctl().

sem_nsems
    Nombre de sémaphores dans l'ensemble. Chaque sémaphore est référencé par un entier positif ou nul, compris dans l'intervalle 0 à sem_nsems-1.

La structure ipc_perm est définie de la façon suivante (les champs en gras peuvent être modifiés en utilisant IPC_SET) :

    struct ipc_perm {
        key_t          __key; /* Clé fournie à semget(2) */
        uid_t          uid;   /* UID effectif du propriétaire */
        gid_t          gid;   /* GID effectif du propriétaire */
        uid_t          cuid;  /* UID effectif du créateur */
        gid_t          cgid;  /* GID effectif du créateur */
        unsigned short mode;  /* Permissions */
        unsigned short __seq; /* Numéro de séquence */
    };

Les 9 bits de poids faible du champ mode de la structure ipc_perm définissent les permissions d'accès sur le segment de mémoire partagée. Les bits de permission sont les suivants :
0400 | Lisible par l'utilisateur
0200 | Droit d'écriture pour l'utilisateur
0040 | Lisible par le groupe
0020 | Autorisation d'écriture pour le groupe
0004 | Lisible par les autres
0002 | Écrit par d'autres

En réalité, « écrire » signifie « modifier » pour un jeu de sémaphores. Les bits 0100, 0010 et 0001 (les bits d'exécution) ne sont pas utilisés par le système.

Les valeurs autorisées pour cmd sont :

IPC_STAT
    Copier dans la structure semid_ds pointée par arg.buf la structure de données du noyau concernant l'ensemble de sémaphores. L'argument semnum est alors ignoré. Le processus appelant doit avoir des privilèges de lecture sur le jeu de sémaphores.

IPC_SET
    Écrire la valeur de certains membres de la structure semid_ds pointés par arg.buf dans la structure de données du noyau associée à ce jeu de sémaphores, en mettant aussi à jour son membre sem_ctime.

    Les membres suivants de la structure sont mis à jour : sem_perm.uid, sem_perm.gid et (les 9 bits de poids faible de) sem_perm.mode.

    L'UID effectif du processus appelant doit correspondre au propriétaire (sem_perm.uid) ou au créateur (sem_perm.cuid) du jeu de sémaphores ou l'appelant doit être privilégié. L'argument semnum est ignoré.

IPC_RMID
    Supprimer immédiatement l'ensemble de sémaphores en réveillant tous les processus en attente dans semop(2). Ils obtiendront un code d'erreur, et errno aura la valeur EIDRM. L'UID effectif du processus appelant doit être soit celui du créateur ou du propriétaire du jeu de sémaphores, ou l'appelant doit être privilégié. L'argument semnum est ignoré.

IPC_INFO (spécifique à Linux)
    Renvoyer des informations sur les limites et paramètres du système concernant les sémaphores dans la structure pointée par arg.__buf. Cette structure est de type seminfo, défini dans <sys/sem.h> si la macro _GNU_SOURCE est définie :

        struct  seminfo {
            int semmap;  /* Nombre d'entrées dans la table de sémaphores ;
                            pas utilisé par le noyau */
            int semmni;  /* Nombre maximal d'ensembles de sémaphores */
            int semmns;  /* Nombre maximal de sémaphores dans tous les
                            ensembles de sémaphores */
            int semmnu;  /* Nombre maximal de structures « undo »
                            sur le système ; pas utilisé par le noyau */
            int semmsl;  /* Nombre maximal de sémaphores dans un ensemble */
            int semopm;  /* Nombre maximal d'opérations pour semop(2) */
            int semume;  /* Nombre maximal d'entrées « undo » par
                            processus ; pas utilisé par le noyau */
            int semusz;  /* Taille de struct sem_undo */
            int semvmx;  /* Valeur maximale d'un sémaphore */
            int semaem;  /* Valeur maximale pouvant être enregistrée pour
                            la mise à jour d'un sémaphore (SEM_UNDO) */
        };

    Les paramètres semmsl, semmns, semopm et semmni peuvent être modifiés via /proc/sys/kernel/sem ; consultez proc(5) pour plus de détails.

SEM_INFO (spécifique à Linux)
    Renvoyer une structure seminfo contenant les mêmes informations que pour IPC_INFO, sauf les champs suivants qui sont remplis avec des informations sur les ressources système actuellement utilisées par les sémaphores : le champ semusz renvoie le nombre d'ensembles de sémaphores existants sur le système, et le champ semaem renvoie le nombre total de sémaphores dans tous les ensembles de sémaphores du système.

SEM_STAT (spécifique à Linux)
    Renvoyer une structure semid_ds comme pour IPC_STAT. Cependant, l'argument semid n'est pas un identifiant de sémaphore, mais un index dans la table interne du noyau qui contient des informations sur tous les ensembles de sémaphores du système.

SEM_STAT_ANY (spécifique à Linux depuis Linux 4.17)
    Renvoyer une structure semid_ds comme pour SEM_STAT. Néanmoins, l'accès en lecture pour semid n'est pas vérifié dans sem_perm.mode ce qui signifie que tous les utilisateurs peuvent utiliser cette opération (de la même manière qu'ils peuvent lire /proc/sysvipc/sem pour obtenir la même information).

GETALL
    Renvoyer la valeur semval de chaque sémaphore de l'ensemble dans le tableau arg.array. L'argument semnum est ignoré. Le processus appelant doit avoir des privilèges de lecture sur le jeu de sémaphores.

GETNCNT
    Renvoyer la valeur du champ semzcnt du semnum-ième sémaphore de l'ensemble (c'est-à-dire le nombre de processus attendant que la valeur du sémaphore augmente). Le processus appelant doit avoir des privilèges de lecture sur le jeu de sémaphores.

GETPID
    Renvoyer la valeur de sempid pour le semnum-ième sémaphore de l'ensemble. Il s'agit du PID du processus ayant exécuté la dernière opération sur ce sémaphore (voir les NOTES). Le processus appelant doit avoir des privilèges de lecture sur le jeu de sémaphores.

GETVAL
    Renvoyer semval (c'est-à-dire la valeur du sémaphore) pour le semnum-ième sémaphore de l'ensemble. Le processus appelant doit avoir des privilèges de lecture sur le jeu de sémaphores.

GETZCNT
    Renvoyer la valeur du champ semzcnt du semnum-ième sémaphore de l'ensemble (c'est-à-dire le nombre de processus attendant que la valeur du sémaphore revienne à 0). Le processus appelant doit avoir des privilèges de lecture sur le jeu de sémaphores.

SETALL
    Positionner la valeur du champ semval de tous les sémaphores de l'ensemble en utilisant le tableau arg.array et en mettant à jour le champ sem_ctime de la structure semid_ds de contrôle du jeu de sémaphores. Les entrées « undo » (consultez semop(2)) sont effacées de tous les processus pour les sémaphores modifiés. Si la nouvelle valeur du sémaphore permet à des appels semop(2) bloqués dans d'autres processus de se poursuivre, ces processus sont réveillés. L'argument semnum est ignoré. Le processus appelant doit avoir des privilèges d'écriture sur le jeu de sémaphores.

SETVAL
    Positionner la valeur du sémaphore (semval) à arg.val pour le semnum-ième sémaphore de l'ensemble en mettant aussi à jour le champ sem_ctime dans la structure semid_ds associée au jeu de sémaphores. Les entrées « undo » sont effacées de tous les processus pour les sémaphores modifiés. Si la nouvelle valeur du sémaphore permet à des appels semop(2) bloqués dans d'autres processus de se poursuivre, ces processus sont réveillés. Le processus appelant doit avoir des privilèges d'écriture sur le jeu de sémaphores.

VALEUR RENVOYÉE
En cas de réussite, semctl() renvoie une valeur non négative dépendant de l'argument cmd :

GETNCNT
    La valeur de semncnt.

GETPID
    La valeur sempid.

GETVAL
    La valeur semval.

GETZCNT
    La valeur semzcnt.

IPC_INFO
    Le plus grand indice d'une entrée utilisée dans la table interne du noyau contenant des informations sur tous les ensembles de sémaphores. Cette information peut ensuite être utilisée pour des opérations SEM_STAT ou SEM_STAT_ANY répétées afin d'obtenir des informations sur tous les ensembles de sémaphores du système.

SEM_INFO
    Comme pour IPC_INFO.

SEM_STAT
    L'identifiant de l'ensemble de sémaphores dont l'indice était donné dans semid.

SEM_STAT_ANY
    comme pour SEM_STAT

Toutes les autres commandes cmd renvoient zéro en cas de réussite.

semctl() renvoie -1 s'il échoue auquel cas errno contient le code d'erreur.

ERREURS

EACCES
    L'argument cmd a l'une des valeurs suivantes GETALL, GETPID, GETVAL, GETNCNT, GETZCNT, IPC_STAT, SEM_STAT, SEM_STAT_ANY, SETALL ou SETVAL, et le processus appelant n'a pas les permissions nécessaires sur le jeu de sémaphores et n'a pas la capacité CAP_IPC_OWNER dans l'espace de noms utilisateur qui régit son espace de noms IPC.

EFAULT
    arg.buf ou arg.array pointent en dehors de l'espace d'adressage accessible.

EIDRM
    Le jeu de sémaphores a été supprimé.

EINVAL
    Valeur de cmd ou semid non valable. Ou bien, pour une opération SEM_STAT, l'indice indiqué dans semid référence une entrée actuellement inutilisée de la table.

EPERM
    L'argument cmd réclame les commandes IPC_SET ou IPC_RMID mais l'UID effectif du processus appelant n'est pas le créateur (comme dans sem_perm.cuid) ou le propriétaire (comme dans sem_perm.uid) du jeu de sémaphores, et le processus n'a pas la capacité CAP_SYS_ADMIN.

ERANGE
    L'argument cmd réclame les commandes SETALL ou SETVAL et la valeur de semval (pour l'ensemble ou pour certains sémaphores) est inférieure à 0 ou supérieure à la valeur SEMVMX.

CONFORMITÉ
POSIX.1-2001, POSIX.1-2008, SVr4.

POSIX.1 spécifie le champ sem_nsems de la structure semid_ds comme de type unsigned short, ce qui est suivi par de nombreux systèmes. Ce champ était défini ainsi dans Linux 2.2 et dans les versions précédentes. Depuis Linux 2.4, ce champ est de type unsigned long.

NOTES
Les appels système IPC_INFO, SEM_STAT et SEM_INFO sont utilisés par le programme ipcs(1) pour fournir des informations sur les ressources allouées. Cela peut changer dans le futur, en utilisant l'interface d'un système de fichiers /proc.

Divers champs de la struct semid_ds étaient de type short sous Linux 2.2 et sont devenus de type long sous Linux 2.4. Pour en tirer parti, une recompilation sous la glibc 2.1.91 ou ultérieure doit suffire. (Le noyau distingue les anciens et nouveaux appels par un drapeau IPC_64 dans cmd.)

Dans certaines versions antérieures de la glibc, l'union semun était définie dans <sys/sem.h>, mais POSIX.1 documente que l'appelant doit définir cette union. Dans les versions de la glibc où cette union n'est pas définie, la macro _SEM_SEMUN_UNDEFINED est définie dans <sys/sem.h>.

La limite suivante du système sur les jeux de sémaphore affecte l'appel système semctl() :

SEMVMX
    Valeur maximale pour semval dépendant de l'implémentation (généralement 32767).

Pour améliorer la portabilité, il vaut mieux invoquer toujours semctl() avec quatre arguments.

  La valeur sempid
POSIX.1 définit sempid comme l'« ID du processus de la dernière opération » sur un sémaphore, et note explicitement que cette valeur est réglée par un appel semop réussi, avec l'implication qu'aucune autre interface n'affecte la valeur sempid.

Bien que certaines implémentations respectent le comportement défini dans POSIX.1, d'autres ne le font pas (le tort revient ici probablement à POSIX.1 qui n'a pas réussi à englober tous les comportements implémentés existants). Diverses autres implémentations mettent également à jour sempid pour d'autres opérations qui mettent à jour la valeur d'un sémaphore : les opérations SETVAL et SETALL, ainsi que les ajustements de sémaphores exécutés en fin de processus du fait de l'utilisation de l'option SEM_UNDO (voir semop(2)).

Linux modifie également sempid pour les opérations SETVAL et les ajustements de sémaphores. Cependant, de façon plutôt incohérente, le noyau ne mettait pas à jour sempid pour les opérations SETALL jusqu'à la version 4.5 de Linux incluse. Cela a été corrigé avec la version 4.6.

EXEMPLES
Consultez shmop(2).

VOIR AUSSI
ipc(2), semget(2), semop(2), capabilities(7), sem_overview(7), sysvipc(7)

COLOPHON
Cette page fait partie de la publication 5.13 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>, Thomas Vincent <tvincent@debian.org> et Jean-Pierre Giraud <jean-pierregiraud@neuf.fr> Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE. Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.