NOM¶
clone, __clone2 - Créer un processus fils (child)
SYNOPSIS¶
#define _GNU_SOURCE /* Consultez feature_test_macros(7) */
#include <sched.h>
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
DESCRIPTION¶
clone() crée un nouveau processus, exactement comme le fait
fork(2).
clone() est en fait une fonction de bibliothèque
s'appuyant sur l'appel système
clone() sous‐jacent,
mentionné comme
sys_clone ci‐dessous. Une description de
sys_clone se trouve plus bas sur cette page.
Contrairement à
fork(2), cette routine permet le partage d'une
partie du contexte d'exécution entre le processus fils et le processus
appelant. Le partage peut s'appliquer sur l'espace mémoire, sur la table
des descripteurs de fichiers ou la table des gestionnaires de signaux. (Notez
que sur cette page de manuel, le « processus appelant »
correspond normalement au « processus père », mais
voyez quand même la description de
CLONE_PARENT plus bas).
L'appel système
clone() est principalement utilisé pour
permettre l'implémentation des threads : un programme est
scindé en plusieurs lignes de contrôle, s'exécutant
simultanément dans un espace mémoire partagée.
Quand le processus fils est créé, avec
clone(), il exécute
la fonction
fn(
arg) de l'application. Ceci est différent de
fork(2) avec lequel l'exécution continue dans le fils au point de
l'appel
fork(2). L'argument
fn est un pointeur sur la fonction
appelée par le processus fils lors de son démarrage. L'argument
arg est transmis à la fonction
fn lors de son invocation.
Quand la fonction
fn(
arg) revient, le processus fils se termine.
La valeur entière renvoyée par
fn est utilisée comme
code de retour du processus fils. Ce dernier peut également se terminer
de manière explicite en invoquant la fonction
exit(2) ou
après la réception d'un signal fatal.
L'argument
child_stack indique l'emplacement de la pile utilisée par
le processus fils. Comme les processus fils et appelant peuvent partager de la
mémoire, il n'est généralement pas possible pour le fils
d'utiliser la même pile que son père. Le processus appelant doit
donc préparer un espace mémoire pour stocker la pile de son fils, et
transmettre à
clone un pointeur sur cet emplacement. Les piles
croissent vers le bas sur tous les processeurs implémentant Linux (sauf
le HP PA), donc
child_stack doit pointer sur la plus haute adresse de
l'espace mémoire prévu pour la pile du processus fils.
L'octet de poids faible de
flags contient le numéro du signal qui
sera envoyé au père lorsque le processus fils se terminera. Si ce
signal est différent de
SIGCHLD, le processus parent doit
également spécifier les options
__WALL ou
__WCLONE
lorsqu'il attend la fin du fils avec
wait(2). Si aucun signal n'est
indiqué, le processus parent ne sera pas notifié de la terminaison
du fils.
flags permet également de préciser ce qui sera partagé
entre le père et le fils, en effectuant un OU binaire entre une ou
plusieurs des constantes suivantes :
- CLONE_CHILD_CLEARTID (depuis Linux 2.5.49)
- Effacer l'ID du thread enfant à ctid dans la
mémoire du fils lorsqu'il se termine, et réveiller le futex
à cette adresse. L'adresse concernée peut être
modifiée par l'appel système set_tid_address(2). Cela est
utilisé dans les bibliothèques de gestion de threads.
- CLONE_CHILD_SETTID (depuis Linux 2.5.49)
- Enregistrer l'ID du thread enfant à ctid dans
la mémoire du fils.
- CLONE_FILES
- Si l'attribut CLONE_FILES est positionné, le
processus appelant et le processus fils partagent la même table des
descripteurs de fichier. Tout descripteur créé par un processus
est également valide pour l'autre processus. De même si un
processus ferme un descripteur, ou modifie ses attributs (en utilisant
l'opération fcntl(2) F_SETFD), l'autre processus en est
aussi affecté.
Si CLONE_FILES n'est pas positionné, le processus fils
hérite d'une copie des descripteurs de fichier ouverts par l'appelant
au moment de l'appel clone(). (Les copies des descripteurs de
fichier dans le fils sont associées aux mêmes descriptions de
fichiers ouverts (consultez open(2)) que les descripteurs de
fichier correspondants dans le processus appelant.) Les opérations
effectuées ensuite sur un descripteur par un des processus
n'affectent pas l'autre processus.
- CLONE_FS
- Si l'attribut CLONE_FS est positionné, le
processus appelant et le processus fils partagent les mêmes
informations concernant le système de fichiers. Ceci inclut la racine
du système de fichiers, le répertoire de travail, et l'umask.
Tout appel à chroot(2), chdir(2) ou umask(2)
effectué par un processus aura également influence sur l'autre
processus.
Si CLONE_FS n'est pas choisi, le processus travaille sur une copie
des informations de l'appelant concernant le système de fichiers.
Cette copie est effectuée lors de l'invocation de clone(). Les
appels à chroot(2), chdir(2), umask(2)
effectués par un processus n'affectent pas l'autre processus.
- CLONE_IO (depuis Linux 2.6.25)
- Si CLONE_IO est défini, alors le nouveau
processus partage un contexte d'entrées-sorties avec le processus
appelant. Si cet attribut n'est pas défini, alors (comme pour
fork(2)) le nouveau processus a son propre contexte
d'entrées-sorties.
Le contexte d'entrées-sorties correspond à la visibilité que
l'ordonnanceur de disques a des entrées-sorties (c'est-à-dire,
ce que l'ordonnanceur d'entrée-sorties utilise pour modéliser
l'ordonnancement des entrées-sorties d'un processus). Si des
processus partagent le même contexte d'entrées-sorties, ils sont
traités comme un seul par l'ordonnanceur d'entrées-sorties. Par
conséquent, ils partagent le même temps d'accès aux
disques. Pour certains ordonnanceurs d'entrées-sorties, si deux
processus partagent un contexte d'entrées-sorties, ils seront
autorisés à intercaler leurs accès disque. Si plusieurs
threads utilisent des entrées-sorties pour le même processus (
aio_read(3), par exemple), ils devraient utiliser CLONE_IO
pour obtenir de meilleurs performances d'entrées-sorties.
Si le noyau n'a pas été configuré avec l'option
CONFIG_BLOCK, cet attribut n'a aucun effet.
- CLONE_NEWIPC (depuis Linux 2.6.19)
- Si CLONE_NEWIPC est défini, alors créer le
processus dans un nouvel espace de noms IPC. Si cet attribut n'est pas
défini, alors (comme pour fork(2)) le processus est
créé dans le même espace de noms IPC que le processus
appelant. Cet attribut est sensé être utilisé pour
l'implémentation de conteneurs.
Un espace de noms IPC consiste en un jeu d'identifiants pour des objets IPC
System V (ces objets sont créés en utilisant
msgctl(2), semctl(2) et shmctl(2)). Les objets
créés dans un espace de noms IPC sont visibles de tous les
autres membres de cet espace de noms, mais ne sont pas visibles des
processus des autres espaces de noms.
Quand un espace de noms est détruit (c'est-à-dire, quand le
dernier processus membre de cet espace de noms se termine), tous les
objets IPC de cet espace de noms sont automatiquement détruits.
Utiliser cet attribut nécessite : un noyau configuré avec les
options CONFIG_SYSVIPC et CONFIG_IPC_NS et que le processus
soit privilégié ( CAP_SYS_ADMIN). Cet attribut ne peut
pas être utilisé en même temps que
CLONE_SYSVSEM.
- CLONE_NEWNET (depuis Linux 2.6.24)
- (L'implémentation de cet attribut n'est complète
que depuis le noyau 2.6.29.)
Si CLONE_NEWNET est défini, alors créer le processus dans
un nouvel espace de noms réseau. SI cet attribut n'est pas
défini, alors (comme pour fork(2)) le processus est
créé dans le même espace de noms réseau que le
processus appelant. Cet attribut est sensé être utilisé
pour l'implémentation de conteneurs.
Un espace de noms réseau fournit une vue isolée de la pile
réseau (interfaces des périphériques réseau, piles des
protocoles IPv4 et IPv6, tables de routage, règles de pare-feu, les
arbres de répertoire /proc/net et /sys/class/net, les
sockets, etc.). Un périphérique réseau physique ne peut
être que dans un seul espace de noms réseau. Une paire
d'interface réseau virtuelle (« veth ») fournit
une abstraction similaire à pipe qui peut être utilisé pour
créer un pont vers une interface réseau physique d'un autre
espace de noms réseau.
Quand un espace de noms réseau est libéré (c'est-à-dire,
quand le dernier processus de l'espace de noms se termine), ses
périphériques réseau physiques sont remis dans l'espace de
noms réseau initial (pas celui du processus père).
Utiliser cet attribut nécessite : un noyau configuré avec
l'option CONFIG_NET_NS et que le processus soit
privilégié ( CAP_SYS_ADMIN).
- CLONE_NEWNS (depuis Linux 2.4.19)
- Démarrer le processus dans un nouvel espace de noms de
montage.
Chaque processus se trouve dans un espace de noms de montage. Cet
espace de noms du processus regroupe les données
décrivant la hiérarchie des fichiers vus par le processus
(l'ensemble des montages). Après un fork(2) ou clone()
sans l'attribut CLONE_NEWNS le fils se déroule dans le
même espace de noms de montage que son père. Les appels
système mount(2) et umount(2) modifient l'espace de
noms de montage du processus appelant, et affectent ainsi tous les
processus se déroulant dans le même espace de noms, sans
affecter les processus se trouvant dans d'autres espaces de noms de
montage.
Après un clone() avec l'attribut CLONE_NEWNS le fils
cloné démarre dans un nouvel espace de noms de montage,
initialisé avec une copie de l'espace de noms du père.
Seul un processus privilégié (un processus ayant la capacité
CAP_SYS_ADMIN) peut spécifier l'attribut CLONE_NEWNS.
Il n'est pas possible de spécifier à la fois CLONE_NEWNS
et CLONE_FS pour le même appel clone().
- CLONE_NEWPID (depuis Linux 2.6.24)
- Si CLONE_NEWPID est défini, alors créer le
processus dans un nouvel espace de noms de PID. Si cet attribut n'est pas
défini, alors (comme pour fork(2)) le processus est
créé dans le même espace de noms de PID que le processus
appelant. Cet attribut est sensé être utilisé pour
l'implémentation de conteneurs.
Un espace de noms de PID fournit un environnement isolés pour les
PID : les PID d'un nouvel espace de noms de PID commence à 1,
comme pour un système seul, et les appels à fork(2),
vfork(2) et clone() produiront des processus avec des PID
uniques dans l'espace de noms.
Le premier processus créé dans un nouvel espace de noms
(c'est-à-dire, le processus créé en utilisant l'attribut
CLONE_NEWPID) a un PID de 1 et est le processus
« init » pour l'espace de noms. Les fils qui
deviennent orphelins dans cet espace de noms seront adoptés par ce
processus plutôt que par init(8). Contrairement à
l'init traditionnel, le processus « init » d'un
espace de noms de PID peut se terminer et, s'il le fait, tous les
processus dans l'espace de noms sont alors terminés.
Les espaces de noms de PID forment une hiérarchie. Quand un espace de
noms de PID est créé, les processus de cet espace de noms sont
visibles depuis l'espace de noms de PID du processus qui a créé
le nouvel espace de noms ; de la même façon, si l'espace de
noms parent est lui-même le fils d'un autre espace de noms de PID,
alors les processus du fils et du père seront tous visibles de
l'espace de noms grand-père. À l'inverse, les processus de
l'espace de noms de PID fils ne voient pas les processus de l'espace de
noms parent. L'existence d'une hiérarchie d'espaces de noms signifie
que chaque processus peut désormais avoir plusieurs PID : un par
espace de noms dans lequel il est visible ; chacun de ces PID est
unique dans les espaces de noms correspondants. (Un appel à
getpid(2) renvoie toujours le PID associé à l'espace de
noms dans lequel le processus se trouve.)
Après avoir créé un nouvel espace de noms, il est utile pour
le fils de changer son répertoire racine et monter une nouvelle
instance de procfs dans /proc de telle sorte que des outils comme
ps(1) fonctionnent correctement. (Si CLONE_NEWNS est
également présent dans flags, alors il n'est pas
nécessaire de changer de répertorie racine : une nouvelle
instance de procfs peut être monté directement dans
/proc.)
L'utilisation de cet attribut nécessite : un noyau configuré
avec l'option CONFIG_PID_NS et que le processus soit
privilégié ( CAP_SYS_ADMIN). Cet attribut ne peut pas
être utilisé en même temps que CLONE_THREAD.
- CLONE_NEWUTS (depuis Linux 2.6.19)
- Si CLONE_NEWUTS est défini, alors créer le
processus dans un nouvel espace de noms de UTS, dont les identifiants sont
initialisés en dupliquant les identifiants de l'espace de noms UTS du
processus appelant. Si cet attribut n'est pas défini, alors (comme
pour fork(2)) le processus est créé dans le même
espace de noms UTS que le processus appelant. Cet attribut est sensé
être utilisé pour l'implémentation de conteneurs.
Un espace de noms UTS est l'ensemble des identifiants renvoyés par
uname(2) ; parmi lesquels le nom de domaine et le nom
d'hôte peuvent être modifiés respectivement à l'aide
de setdomainname(2) et sethostname(2). Les modifications
apportés à ces identifiants dans un espace de noms UTS sont
visibles par tous les processus du même espace de noms, mais ne sont
pas visibles des processus des autres espaces de noms UTS.
L'utilisation de cet attribut nécessite : un noyau configuré
avec l'option CONFIG_UTS_NS et que le processus soit
privilégié ( CAP_SYS_ADMIN).
- CLONE_PARENT (depuis Linux 2.3.12)
- Si CLONE_PARENT est présent, le père du
nouveau fils (comme il est indiqué par getppid(2)) sera le
même que celui du processus appelant.
Si CLONE_PARENT n'est pas fourni, alors (comme pour fork(2))
le père du processus fils sera le processus appelant.
Remarquez que c'est le processus père, tel qu'indiqué par
getppid(2), qui est notifié lors de la fin du fils. Ainsi, si
CLONE_PARENT est présent, alors c'est le père du
processus appelant, et non ce dernier, qui sera notifié.
- CLONE_PARENT_SETTID (depuis Linux 2.5.49)
- Enregistrer l'ID du thread enfant à ptid dans
la mémoire du père et du fils. (Dans Linux 2.5.32-2.5.48 il y a
un attribut CLONE_SETTID qui fait cela.)
- CLONE_PID (obsolète)
- Si l'attribut CLONE_PID est positionné, les
processus appelant et fils ont le même numéro de processus.
C'est bien pour hacker le système, mais autrement il n'est plus
utilisé. Depuis 2.3.21, cet attribut ne peut être utilisé
que par le processus de démarrage du système (PID 0). Il a
disparu dans Linux 2.5.16.
- CLONE_PTRACE
- Si l'attribut CLONE_PTRACE est positionné et si
l'appelant est suivi par un débogueur, alors le fils sera
également suivi (consultez ptrace(2)).
- CLONE_SETTLS (depuis Linux 2.5.32)
- Le paramètre newtls est le nouveau descripteur
TLS (Thread Local Storage). (Consultez set_thread_area(2).)
- CLONE_SIGHAND
- Si l'attribut CLONE_SIGHAND est positionné, le
processus appelant et le processus fils partagent la même table des
gestionnaires de signaux. Si l'appelant, ou le fils, appelle
sigaction(2) pour modifier le comportement associé à un
signal, ce comportement est également changé pour l'autre
processus. Néanmoins, l'appelant et le fils ont toujours des masques
de signaux distincts, et leurs ensembles de signaux bloqués sont
indépendants. L'un des processus peut donc bloquer un signal en
utilisant sigprocmask(2) sans affecter l'autre processus.
Si CLONE_SIGHAND n'est pas utilisé, le processus fils
hérite d'une copie des gestionnaires de signaux de l'appelant lors de
l'invocation de clone(). Les appels à sigaction(2)
effectués ensuite depuis un processus n'ont pas d'effets sur l'autre
processus.
Depuis Linux 2.6.0-test6, l'attribut CLONE_VM doit également
être spécifié dans flags si CLONE_SIGHAND
l'est.
- CLONE_STOPPED (depuis Linux 2.6.0-test2)
- Si l'attribut CLONE_STOPPED est positionné, le
fils est initialement stoppé (comme s'il avait reçu le signal
SIGSTOP), et doit être relancé en lui envoyant le signal
SIGCONT.
Cet attribut est marqué comme obsolète depuis Linux 2.6.25, et a
été complètement supprimé dans Linux 2.6.38.
- CLONE_SYSVSEM (depuis Linux 2.5.10)
- Si CLONE_SYSVSEM est positionné, le fils et le
processus appelant partagent la même liste de compteurs
« undo » pour les sémaphores System V
(consultez semop(2)). Si cet attribut n'est pas utilisé, le
fils a une liste « undo » séparée,
initialement vide.
- CLONE_THREAD (depuis Linux 2.4.0-test8)
- Si CLONE_THREAD est présent, le fils est
placé dans le même groupe de threads que le processus appelant.
Afin de rendre l'explication de CLONE_THREAD plus lisible, le terme
« thread » est utilisé pour parler des processus
dans un même groupe de threads.
Les groupes de threads sont une fonctionnalité ajoutées dans Linux
2.4 pour supporter la notion POSIX d'ensemble de threads partageant un
même PID. En interne, ce PID partagé est appelé identifiant
de groupe de threads (TGID).Depuis Linux 2.4, l'appel getpid(2)
renvoie l'identifiant du groupe de thread de l'appelant.
Les threads dans un groupe peuvent être distingués par leur
identifiant de thread (TID, unique sur le système). Le TID d'un
nouveau thread est renvoyé par clone() au processus appelant,
et un thread peut obtenir son propre TID en utilisant gettid(2).
Quand clone() est appelé sans positionner CLONE_THREAD,
le nouveau thread est placé dans un nouveau groupe de thread dont le
TGID est identique au TID du nouveau thread. Ce thread est le
leader du nouveau groupe.
Un nouveau thread créé en utilisant CLONE_THREAD a le
même processus père que l'appelant de clone() (de
même qu'avec CLONE_PARENT), ainsi les appels à
getppid(2) renvoient la même valeur à tous les threads
dans un même groupe. Lorsqu'un thread créé avec
CLONE_THREAD termine, le thread qui a appelé clone()
pour le créer ne reçoit pas le signal SIGCHLD (ou autre
notification de terminaison) ; de même, l'état d'un tel
thread ne peut être obtenu par wait(2). Le thread est dit
détaché.
Lorsque tous les threads d'un groupe de threads terminent, le processus
parent du groupe reçoit un signal SIGCHLD (ou autre indicateur
de terminaison).
Si l'un des threads dans un groupe de threads appelle execve(2), tous
les threads sauf le leader sont tués, et le nouveau programme est
exécuté dans le leader du groupe de threads.
Si l'un des threads dans un groupe crée un fils avec fork(2),
n'importe lequel des threads du groupe peut utiliser wait(2) sur ce
fils.
Depuis Linux 2.5.35, l'attribut CLONE_SIGHAND de flags doit
être positionné si CLONE_THREAD l'est.
Un signal peut être envoyé à un groupe de threads dans son
ensemble (c'est‐à‐dire à un TGID) avec
kill(2), ou bien à un thread en particulier (à un TID)
avec tgkill(2).
Les gestions de signaux sont définies au niveau des processus : si
un signal sans gestionnaire est reçu par un thread, il affectera
(tuera, stoppera, relancera, ou sera ignoré par) tous les membres du
groupe de threads.
Chaque thread a son propre masque de signaux, défini par
sigprocmask(2), mais les signaux peuvent être en attente soit
pour le processus dans son ensemble (donc peut être reçu par
n'importe lequel des threads du groupe), quand ils sont envoyés avec
kill(2), soit pour un thread particulier, lorsqu'ils sont
envoyés par tgkill(2). Un appel à sigpending(2)
renvoie un ensemble de signaux qui est l'union des processus en attente
pour le processus et ceux en attente pour le thread appelant.
Si kill(2) est utilisé pour envoyer un signal à un groupe
de threads, et si le groupe a installé un gestionnaire pour ce
signal, alors le gestionnaire sera exécuté dans exactement un
des membres du groupe de threads, choisi de façon arbitraire parmi
ceux qui n'ont pas bloqué ce signal. Si plusieurs threads dans un
groupe attendent le même signal en utilisant sigwaitinfo(2),
le noyau choisira arbitrairement l'un d'entre eux pour délivrer le
signal envoyé par kill(2).
- CLONE_UNTRACED (depuis Linux 2.5.46)
- Si l'attribut CLONE_UNTRACED est positionné,
alors un processus traçant le père ne peut pas forcer
CLONE_PTRACE pour ce fils.
- CLONE_VFORK
- Si le bit CLONE_VFORK est actif, l'exécution du
processus appelant est suspendue jusqu'à ce que le fils libère
ses ressources de mémoire virtuelle par un appel execve(2) ou
_exit(2) (comme avec vfork(2)).
Si CLONE_VFORK n'est pas indiqué, alors les deux processus sont
ordonnancés à partir de la fin de l'appel, et l'application ne
doit pas considérer que l'ordre d'exécution soit
déterminé.
- CLONE_VM
- Si le bit CLONE_VM est actif, le processus appelant
et le processus fils s'exécutent dans le même espace
mémoire. En particulier, les écritures en mémoire
effectuées par l'un des processus sont visibles par l'autre. De
même toute projection en mémoire, ou toute suppression de
projection, effectuées avec mmap(2) ou munmap(2) par
l'un des processus affectera également l'autre processus.
Si CLONE_VM n'est pas actif, le processus fils utilisera une copie
distincte de l'espace mémoire de l'appelant. Le cliché est
réalisé lors de l'invocation de clone(). Les
écritures ou les projections de fichiers en mémoire
effectuées par un processus n'affectent pas l'autre processus, comme
cela se passe avec fork(2).
sys_clone¶
L'appel système
sys_clone ressemble plus à
fork(2), en
ceci que l'exécution dans le processus fils continue à partir du
point d'appel. À ce titre, les arguments
fn et
arg de la
fonction d'enrobage de
clone() sont omis. De plus, l'ordre des
arguments change. L'interface brute de l'appel système est à peu
près :
long clone(unsigned long flags, void *child_stack,
void * ptid, void *ctid,
struct pt_regs *regs);
Une autre différence : pour
sys_clone, l'argument
child_stack peut être nul, puisque la sémantique de
copie-en-écriture assure que le fils recevra une copie indépendante
des pages de la pile dès qu'un des deux processus la modifiera. Pour que
cela fonctionne, il faut naturellement que
CLONE_VM ne soit pas
présent.
Linux 2.4 et antérieurs¶
Sous Linux 2.4 et plus anciens,
clone() ne prend pas les arguments
ptid,
tls et
ctid.
VALEUR RENVOYÉE¶
En cas de réussite, le TID du processus fils est renvoyé dans le
thread d'exécution de l'appelant. En cas d'échec, -1 est
renvoyé dans le contexte de l'appelant, aucun fils n'est créé,
et
errno contiendra le code d'erreur.
ERREURS¶
- EAGAIN
- Trop de processus en cours d'exécution.
- EINVAL
- CLONE_SIGHAND a été spécifié
mais pas CLONE_VM (depuis Linux 2.6.0-test6).
- EINVAL
- CLONE_THREAD a été spécifié mais
pas CLONE_SIGHAND (depuis Linux 2.5.35).
- EINVAL
- Les attributs CLONE_NEWNS et CLONE_FS ont
été indiqués simultanément dans flags.
- EINVAL
- Les attributs CLONE_NEWIPC et CLONE_SYSVSEM
ont été indiqués simultanément dans flags.
- EINVAL
- Les attributs CLONE_NEWPID et CLONE_THREAD
ont été indiqués simultanément dans flags.
- EINVAL
- Renvoyée par clone() quand une valeur nulle a
été indiquée pour le paramètre
child_stack.
- EINVAL
- CLONE_NEWIPC a été indiqué dans
flags, mais le noyau n'a pas été configuré avec les
options CONFIG_SYSVIPC et CONFIG_IPC_NS.
- EINVAL
- CLONE_NEWNET a été indiqué dans
flags, mais le noyau n'a pas été configuré avec
l'option CONFIG_NET_NS.
- EINVAL
- CLONE_NEWPID a été indiqué dans
flags, mais le noyau n'a pas été configuré avec
l'option CONFIG_PID_NS.
- EINVAL
- CLONE_NEWUTS a été indiqué dans
flags, mais le noyau n'a pas été configuré avec
l'option CONFIG_UTS.
- ENOMEM
- Pas assez de mémoire pour copier les parties du
contexte du processus appelant qui doivent être dupliquées, ou
pour allouer une structure de tâche pour le processus fils.
- EPERM
- CLONE_NEWIPC, CLONE_NEWNET,
CLONE_NEWNS, CLONE_NEWPID ou CLONE_NEWUTS a
été spécifié par un processus non privilégié
(processus sans CAP_SYS_ADMIN).
- EPERM
- CLONE_PID a été réclamé par un
processus autre que le processus 0.
VERSIONS¶
Il n'y a pas de définition pour
clone() dans la libc5. glibc2
fournit une définition de
clone() comme décrit ici.
Les appels système
clone() et
sys_clone sont spécifiques
à Linux et ne doivent pas être employés dans des programmes
portables.
NOTES¶
Dans les noyaux 2.4.x,
CLONE_THREAD ne rend pas en général le
processus père de l'appelant père du nouveau thread. Cependant, pour
les versions 2.4.7 à 2.4.18 du noyau, l'attribut
CLONE_THREAD
impliquait
CLONE_PARENT (de même qu'avec les noyaux 2.6).
CLONE_DETACHED a existé pendant un moment (introduit dans 2.5.32):
le père ne veut pas de signal à la mort du fils. Dans 2.6.2, la
nécessité d'utiliser ce paramètre avec
CLONE_THREAD a
été supprimée. Cet attribut est toujours défini, mais n'a
plus aucun effet.
Sur i386,
clone() ne devrait pas être appelé via vsyscall, mais
directement en utilisant
int $0x80.
Sur IA-64, un appel système différent est utilisé :
int __clone2(int (*fn)(void *),
void *child_stack_base, size_t stack_size,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
L'appel système
__clone2() fonctionne comme
clone(), sauf que
child_stack_base pointe sur la plus petite adresse de la pile du fils,
et
stack_size indique la taille de la pile sur laquelle pointe
child_stack_base.
BOGUES¶
Les versions de la bibliothèque C GNU qui gèrent la bibliothèque
de gestion des threads NPTL contiennent une fonction enveloppe pour
getpid(2) qui effectue un cache des PID. Ce cache nécessite une
prise en charge par l'enveloppe de
clone() de la glibc, mais telle
qu'il est actuellement implémenté, le cache peut ne pas être
à jour sous certaines circonstances. En particulier, si un signal est
distribué à un fils juste après l'appel à
clone(),
alors un appel à
getpid(2) dans le gestionnaire de signaux du
signal peut renvoyer le PID du processus appelant (le père), si
l'enveloppe de clone n'a toujours pas eu le temps de mettre le cache de PID
à jour pour le fils. (Cette discussion ignore le cas où le fils a
été créé en utilisant
CLONE_THREAD, quand
getpid(2) doit renvoyer la même valeur pour le fils et pour
le processus qui a appelé
clone(), puisque l'appelant et le fils
se trouvent dans le même groupe de threads. Ce problème de cache
n'apparaît pas non plus si le paramètre
flags contient
CLONE_VM.) Pour obtenir la véritable valeur, il peut être
nécessaire d'utiliser quelque chose comme ceci :
#include <syscall.h>
pid_t mypid;
mypid = syscall(SYS_getpid);
VOIR AUSSI¶
fork(2),
futex(2),
getpid(2),
gettid(2),
set_thread_area(2),
set_tid_address(2),
tkill(2),
unshare(2),
wait(2),
capabilities(7),
pthreads(7)
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/>.
Christophe Blaess <
http://www.blaess.fr/christophe/> (1996-2003), Alain
Portal <
http://manpagesfr.free.fr/> (2003-2006). Julien Cristau et
l'équipe francophone de traduction de Debian (2006-2009).
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> ».