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.65 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> ».