NOM¶
process_vm_readv, process_vm_writev - Transférer les données entre les
espaces d'adressage de processus
SYNOPSIS¶
#include <sys/uio.h>
ssize_t process_vm_readv(pid_t pid,
const struct iovec *local_iov,
unsigned long liovcnt,
const struct iovec *remote_iov,
unsigned long riovcnt,
unsigned long flags);
ssize_t process_vm_writev(pid_t pid,
const struct iovec *local_iov,
unsigned long liovcnt,
const struct iovec *remote_iov,
unsigned long riovcnt,
unsigned long flags);
DESCRIPTION¶
Ces appels système transfèrent des données entre l'espace
d'adressage du processus d'appel (« le processus local »)
et du processus identifié par
pid (« le processus
distant »). Les données se déplacent directement entre les
espaces d'adressage des deux processus, sans passer par l'espace du noyau.
L'appel système
process_vm_readv() transfère les données
du processus distant au processus local. Les données à
transférer sont identifiées par
remote_iov et
riovcnt :
remote_iov est un pointeur vers un tableau
décrivant les intervalles d'adresses dans le processus
pid et
riovcnt indique le nombre d'éléments dans
remote_iov.
Les données sont transférées aux endroits indiqués par
local_iov et
liovcnt :
local_iov est un pointeur
vers un tableau décrivant les intervalles d'adresses dans le processus
appelant et
liovcnt indique le nombre d'éléments dans
local_iov.
L'appel système
process_vm_writev() fait l'inverse de
process_vm_readv() — il transfère les données du
processus local au processus distant. À part la direction du transfert,
les arguments
liovcnt,
local_iov,
riovcnt et
remote_iov ont la même signification qu'avec
process_vm_readv().
Les arguments
local_iov et
remote_iov pointent vers un tableau de
structures
iovec, définies dans
<sys/uio.h> :
struct iovec {
void *iov_base; /* Adresse de début */
size_t iov_len; /* Nombre d'octets à transférer */
};
Les tampons sont traités dans l'ordre du tableau. Cela signifie que
process_vm_readv() remplit complètement
local_iov[0] avant
de passer à
local_iov[1], etc. De même,
remote_iov[0] est complètement lu avant de passer à
remote_iov[1], etc.
De même,
process_vm_writev() écrit tout le contenu de
local_iov[0] avant de passer à
local_iov[1], et il remplit
complètement
remote_iov[0] avant de passer à
remote_iov[1].
Les longueurs de
remote_iov[i].iov_len et
local_iov[i].iov_len
n'ont pas besoin d'être identiques. Ainsi, il est possible de
séparer un seul tampon local en plusieurs tampons distants, ou vice
versa.
L'argument
flags n'est pour l'instant pas utilisé et doit être
configuré à 0.
Les valeurs indiquées dans les arguments
liovcnt et
riovcnt
doivent être inférieures à
IOV_MAX (définie dans
<limits.h> ou accessibles par l'appel
sysconf(_SC_IOV_MAX)).
Les arguments de décompte et
local_iov sont vérifiés avant
tout transfert. Si le décompte est trop grand, que
local_iov n'est
pas valable ou que les adresses font référence à des
régions inaccessibles au processus local, aucun des vecteurs ne sera
traité et une erreur sera immédiatement renvoyée.
Remarquez cependant que ces appels système ne vérifient les
régions de mémoire dans le processus distant que juste avant la
lecture ou l'écriture. Par conséquent, une lecture ou écriture
partielle (consultez
VALEUR RENVOYÉE) pourrait avoir comme
résultat un des éléments
remote_iov pointant vers une
région de mémoire non valable dans le processus distant. Aucune
lecture ou écriture supplémentaires ne seront tentées
après cela. Gardez cela à l'esprit lors d'une tentative de lecture
de données de longueur inconnue (comme des chaînes C qui se
terminent par un caractère NULL) depuis un processus distant, en
évitant de s'étendre sur les pages mémoire (en
général 4 Kio) dans un seul élément
iovec
distant (à la place, séparez la lecture distante en deux
éléments
remote_iov à fusionner ensuite dans une seule
entrées
local_iov. La première entrée lue s'arrête
à la frontière de page, tandis que la seconde commence à la
frontière de page suivante).
Afin de lire ou écrire sur un autre processus, l'appelant doit soit avoir
la capacité
CAP_SYS_PTRACE, soit l'identifiant d'utilisateur
réel, l'identifiant d'utilisateur effectif et l'identifiant d'utilisateur
défini sauvegardé du processus distant doivent correspondre à
l'identifiant d'utilisateur réel de l'appelant
et l'identifiant de
groupe réel, l'identifiant de groupe effectif et l'identifiant de groupe
défini sauvegardé du processus distant doivent correspondre à
l'identifiant de groupe réel de l'appelant (les droits nécessaires
sont exactement les mêmes que ceux nécessaires pour réaliser un
ptrace(2) PTRACE_ATTACH sur le processus distant).
VALEUR RENVOYÉE¶
En cas de réussite,
process_vm_readv() renvoie le nombre d'octets
lus et
process_vm_writev() renvoie le nombre d'octets écrits.
Cette valeur renvoyée pourrait être inférieure au nombre total
d'octets demandés si une lecture ou écriture partielle est survenue
(les transferts partiels s'appliquent à la granularité des
éléments
iovec. Ces appels systèmes ne réaliseront
pas de transfert partiel qui sépare un seul élément
iovec). L'appelant devrait vérifier la valeur renvoyée pour
déterminer si une lecture ou écriture partielle est survenue.
En cas d'erreur, -1 est renvoyé et
errno contient le code d'erreur.
ERREURS¶
- EINVAL
- La somme des valeurs iov_len de local_iov ou
remote_iov dépasse une valeur ssize_t.
- EINVAL
- flags n'est pas 0.
- EINVAL
- liovcnt ou riovcnt sont trop grands.
- EFAULT
- La mémoire décrite par local_iov est en
dehors de l'espace d'adressage de l'appelant.
- EFAULT
- La mémoire décrite par remote_iov est en
dehors de l'espace d'adressage du processus pid.
- ENOMEM
- Impossible d'allouer de la mémoire pour les copies
internes de structures iovec.
- EPERM
- L'appelant n'a pas le droit d'accéder à l'espace
d'adressage du processus pid.
- ESRCH
- Aucun processus n'existe avec l'identifiant
pid.
VERSIONS¶
Ces appels système ont été ajoutés à Linux 3.2. La
glibc les gère depuis la version 2.15.
Ces appels système sont des extensions spécifiques à Linux.
NOTES¶
Les transferts de données réalisés par
process_vm_readv()
et
process_vm_writev() ne sont pas garantis être atomiques en
aucune façon.
Ces appels système ont été conçus pour permettre la
transmission rapide de messages en autorisant l'échange de messages avec
une seul opération de copie (plutôt que la double copie qui serait
nécessaire en utilisant, par exemple, la mémoire partagée ou
les tubes (« pipes »)).
EXEMPLE¶
Le code suivant montre l'utilisation de
process_vm_readv(). Il lit
20 octets à l'adresse 0x10000 du processus de PID 10 et
écrit les 10 premiers octets dans
tamp1 et les 10 octets
suivants dans
tamp2.
#include <sys/uio.h>
int
main(void)
{
struct iovec local[2];
struct iovec remote[1];
char tamp1[10];
char tamp2[10];
ssize_t nread;
pid_t pid = 10; /* PID du processus distant */
local[0].iov_base = tamp1;
local[0].iov_len = 10;
local[1].iov_base = tamp2;
local[1].iov_len = 10;
remote[0].iov_base = (void *) 0x10000;
remote[1].iov_len = 20;
nread = process_vm_readv(pid, local, 2, remote, 1, 0);
if (nread != 20)
return 1;
else
return 0;
}
VOIR AUSSI¶
readv(2),
writev(2)
COLOPHON¶
Cette page fait partie de la publication 3.44 du projet
man-pages Linux.
Une description du projet et des instructions pour signaler des anomalies
peuvent être trouvées à l'adresse
<
http://www.kernel.org/doc/man-pages/>.
TRADUCTION¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a
<
http://po4a.alioth.debian.org/> par l'équipe de traduction
francophone au sein du projet perkamon
<
http://perkamon.alioth.debian.org/>.
Veuillez signaler toute erreur de traduction en écrivant à
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet
manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document
en utilisant la commande «
man -L C
<section> <page_de_man> ».