shmctl()
réalise l'opération de contrôle spécifiée par
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 manière 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()/shmdt() */
shmatt_t shm_nattch; /* Nombre d'attachements actuels */
...
};
La structure
ipc_perm
est définie dans
<sys/ipc.h>
de la manière suivante (les champs mis en
évidence sont configurable 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
SHM_LOCKED
unsigned short seq; /* Numéro de séquence */
};
Les valeurs valides 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 précédents le 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)).