SHMCTL(2)

NOM
shmctl - Contrôler la mémoire partagée

SYNOPSIS
#include <sys/ipc.h>
#include <sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

DESCRIPTION
shmctl() effectue l'opération de contrôle indiquée dans cmd sur le segment de mémoire partagée dont l'identifiant est fourni dans shmid. L'argument buf est un pointeur sur une structure shmid_ds définie dans <sys/shm.h> de la façon suivante :

struct shmid_ds {
    struct ipc_perm shm_perm;    /* Appartenace et permissions       */
    size_t          shm_segsz;   /* Taille segment en octets         */
    time_t          shm_atime;   /* Heure dernier attachement        */
    time_t          shm_dtime;   /* Heure dernier détachement        */
    time_t          shm_ctime;   /* Heure dernière modification      */
    pid_t           shm_cpid;    /* PID du créateur                  */
    pid_t           shm_lpid;    /* PID du dernier shmat(2)/shmdt(2) */
    shmatt_t        shm_nattch;  /* Nombre d'attachements actuels    */
    ...
};

La structure ipc_perm est définie dans <sys/ipc.h> de la façon suivante (les champs en gras sont configurables avec IPC_SET) :

struct ipc_perm
{
  key_t  key;           /* Clé fournie à shmget() */
  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 + attributs SHM_DEST
                           et SHM_LOCKED */
  unsigned short seq;   /* Numéro de séquence */
};

Les valeurs autorisées pour cmd sont :

IPC_STAT
    Copier les informations de la structure de données noyau associée à shmid dans la structure shmid_ds pointée par buf. L'appelant doit avoir la permission de lecture sur le segment de mémoire partagée.

IPC_SET
    Écrire les valeurs de certains membres de la structure shmid_ds pointée par buf dans la structure de données noyau associée à ce segment de mémoire partagée, mettant également à jour son membre shm_ctime. Les champs suivants peuvent être modifiés : shm_perm.uid, shm_perm.gid et (les 9 bits de poids faibles de) shm_perm.mode. L'UID effectif du processus appelant doit correspondre à celui du propriétaire (shm_perm.uid) ou celui du créateur (shm_perm.cuid) du segment de mémoire partagée, ou bien l'appelant doit être privilégié.

IPC_RMID
    Marquer le segment pour être détruit. Il ne sera détruit effectivement qu'après le dernier détachement (c'est-à-dire quand le membre shm_nattch de la structure shmid_ds associée vaudra zéro.) L'appelant doit être le créateur du segment, son propriétaire, ou être privilégié. Si un segment est marqué pour destruction, alors l'attribut (non standard) SHM_DEST du champ shm_perm.mode de la structure de donnée récupérée avec IPC_STAT sera positionné.

L'appelant doit s'assurer qu'un segment a été détruit ; autrement, les pages qui ont provoquées des fautes resteront en mémoire ou dans l'espace swap.

IPC_INFO (Spécifique à Linux)
    Renvoie les informations sur les paramètres et limites de mémoire partagée à l'échelle du système dans une structure pointée par buf. Cette structure est du type shminfo (aussi, un transtypage est nécessaire), définie dans <sys/shm.h> si la macro de test de fonctionnalités _GNU_SOURCE est définie :
    struct  shminfo {
        unsigned long shmmax; /* Taille maximum de segment */
        unsigned long shmmin; /* Taille minimum de segment ; toujours 1 */
        unsigned long shmmni; /* Nombre maximum de segments */
        unsigned long shmseg; /* Nombre maximum de segments qu'un
                                 processus puisse attacher ;
                                 inutilisé dans le noyau */
        unsigned long shmall; /* Nombre maximum de pages de mémoire
                                 partagée, à l'échelle du système */
    };
    Les réglages shmmni, shmmax et shmall peuvent être modifiés via les fichiers /proc de même nom ; voir proc(5) pour les détails.

SHM_INFO (Spécifique à Linux)
    Renvoie une structure shm_info dont les champs contiennent des informations sur les ressources système consommées par la mémoire partagée. Cette structure est définie dans <sys/shm.h> si la macro de test de fonctionnalité _GNU_SOURCE est définie :
    struct shm_info {
        int used_ids;           /* Nombre de segments
                                   actuellement existants */
        unsigned long shm_tot;  /* Nombre total de pages
                                   de mémoire partagée */
        unsigned long shm_rss;  /* Nombre de pages de mémoire
                                   partagée résidentes */
        unsigned long shm_swp;  /* Nombre de pages de mémoire
                                   partagée swappées */
        unsigned long swap_attempts;  /* Inutilisé depuis Linux 2.4 */
        unsigned long swap_successes; /* Inutilisé depuis Linux 2.4 */
    };

SHM_STAT (Spécifique à Linux)
    Renvoie une structure shmid_ds comme pour IPC_STAT. Toutefois, l'argument shmid n'est pas un identifiant de segment, mais plutôt un index dans un tableau interne du noyau qui contient les informations sur tous les segments de mémoire partagée du système.

Un appelant privilégié peut autoriser ou interdire le swapping d'un segment avec les valeurs de cmd suivantes :

SHM_LOCK (Spécifique à Linux)
    Empêcher le swapping d'un segment de mémoire partagée. L'appelant doit consulter chaque page concernée après avoir effectué le verrouillage pour s'assurer qu'elle est bien présente en mémoire. Si un segment a été verrouillé, l'attribut (non standard) SHM_LOCKED du champ shm_perm.mode de la structure de données récupérée avec IPC_STAT sera positionné.

SHM_UNLOCK (Spécifique à Linux)
    Déverrouiller le segment, autorisant son swapping.

Dans les noyaux antérieurs au 2.6.10, seul un processus privilégié pouvait utiliser SHM_LOCK et SHM_UNLOCK. Depuis le noyau 2.6.10, un processus non privilégié peut utiliser ces opérations si son UID effectif correspond à l'UID du propriétaire ou du créateur du segment, et (pour SHM_LOCK) si la quantité de mémoire à verrouiller ne dépasse pas la limite de ressource RLIMIT_MEMLOCK (voir setrlimit(2)).

VALEUR RENVOYÉE
Une opération IPC_INFO ou SHM_INFO réussie renvoie l'index de la plus grande entrée utilisée dans le tableau interne du noyau contenant l'information sue tous les segments de mémoire partagée. (Cette information peut être utilisée avec des opérations SHM_STAT répétées pour obtenir les informations sur tous les segments de mémoire partagée du système.) Une opération SHM_STAT réussie renvoie l'identifiant du segment de mémoire partagée dont l'index a été fourni à shmid. Les autres opérations renvoient 0 si elles réussissent. shmctl() renvoie -1 s'il échoue, auquel cas errno contient le code d'erreur.

ERREURS

EACCES
    on demande IPC_STAT ou SHM_STAT mais shm_perm.mode ne permet pas la lecture du segment shmid, et le processus appelant n'a pas la capacité CAP_IPC_OWNER.

EFAULT
    cmd à la valeur IPC_SET ou IPC_STAT mais buf pointe en-dehors de l'espace d'adressage accessible.

EIDRM
    shmid pointe sur un segment détruit.

EINVAL
    shmid n'est pas un identificateur de segment valide, ou cmd n'est pas une commande reconnue. Ou, pour l'opération SHM_STAT, la valeur d'index spécifiée dans shmid fait référence à un emplacement du tableau qui n'est pas actuellement utilisé.

ENOMEM
    (Depuis le noyau 2.6.9), SHM_LOCK a été spécifié et la taille du segment à verrouiller signifie que le nombre total d'octets dans les segments de mémoire partagée verrouillés excède la limite pour l'UID réel du processus appelant. Cette limite est définie par la limite de ressources souple RLIMIT_MEMLOCK (voir setrlimit(2)).

EOVERFLOW
    on demande IPC_STAT mais la valeur de GID ou d'UID est trop grande pour être stockée dans la structure pointée par buf.

EPERM
    On réclame IPC_SET ou IPC_RMID mais l'appelant n'est ni le créateur du segment (trouvé dans shm_perm.cuid), ni le propriétaire (trouvé dans shm_perm.uid) et le processus n'est pas privilégié (n'a pas la capacité CAP_SYS_ADMIN. Ou bien (dans les noyaux depuix 2.6.9) soit SHM_LOCK soit SHM_UNLOCK a été spécifié, mais le processus n'est pas privilégié (sous Linux : n'a pas la capacité CAP_IPC_LOCK. (Depuis Linux 2.6.9, cette erreur peut survenir si RLIMIT_MEMLOCK vaut 0 et si l'appelant n'est pas privilégié.)

CONFORMITÉ
SVr4, POSIX.1-2001.

NOTES
les opérations IPC_INFO, SHM_STAT et SHM_INFO sont utilisées par le programme operations are used by the ipcs(8) pour fournir des informations sur les ressources allouées. Dans le futur, celles-ci seront modifiées ou déplacées vers un interface du système de fichier /proc. Linux permet à un processus d'attacher (shmat(2)) un segment de mémoire partagée qui a déjà été marqué pour effacement en utilisant shmctl(IPC_RMID). Ce comportement n'est pas disponible sur d'autres implémntations Unix ; les applications conçues pour être portables devraient éviter de compter dessus. Divers champs de la struct shmid_ds étaient des short sous Linux 2.2 et sont devenus des long sous Linux 2.4. Pour en tirer parti, une recompilation sous glibc 2.1.91 ou ultérieure doit suffire. (Le noyau distingue les anciens et nouveaux appels par un drapeau IPC_64 dans cmd.)

VOIR AUSSI
mlock(2), setrlimit(2), shmget(2), shmop(2), capabilities(7), svipc(7)

TRADUCTION

Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 16 octobre 1996 et révisée le 24 juin 2008.

L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 2 shmctl ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.