posix_spawn
Table des matières
Retour à l'index
NOM
posix_spawn, posix_spawnp — Engendrer un processus
BIBLIOTHÈQUE
Bibliothèque C standard (libc, -lc)
SYNOPSIS
#include <spawn.h>
int posix_spawn(pid_t *restrict pid, const char *restrict path,
const posix_spawn_file_actions_t *restrict file_actions,
const posix_spawnattr_t *restrict attrp,
char *const argv[restrict],
char *const envp[restrict]);
int posix_spawnp(pid_t *restrict pid, const char *restrict file,
const posix_spawn_file_actions_t *restrict file_actions,
const posix_spawnattr_t *restrict attrp,
char *const argv[restrict],
char *const envp[restrict]);
DESCRIPTION
Les fonctions posix_spawn() et posix_spawnp() sont utilisées pour
créer un processus enfant qui exécute le fichier indiqué. Ces fonctions sont
spécifiées par POSIX pour fournir une méthode standard de création de
nouveaux processus sur les machines n'ayant pas la capacité de prendre
l'appel système fork(2) en charge. Ces machines sont en général de petits
systèmes embarqués sans MMU.
Les fonctions posix_spawn() et posix_spawnp() fournissent les
fonctionnalités de fork(2) et exec(3) combinées, complétées par des
étapes facultatives de nettoyage dans l'enfant avant l'appel à
exec(3). Ces fonctions n'ont pas vocation à remplacer les appels systèmes
fork(2) et execve(2). En fait, elles ne fournissent qu'un
sous-ensemble des fonctionnalités qui peuvent être réalisées par ces appels
systèmes.
La seule différence entre posix_spawn() et posix_spawnp() est la
manière avec laquelle elles spécifient le fichier devant être exécuté par le
processus enfant. Avec posix_spawn(), le fichier exécutable est indiqué
par un chemin (absolu ou relatif). Avec posix_spawnp(), le fichier
exécutable n'est indiqué que par un nom de fichier et le système le cherche
dans la liste des répertoires indiqués dans PATH (de la même façon que
execvp(3)). Le reste de cette page est écrit du point de vue de
posix_spawn() et il est à garder en mémoire que posix_spawnp() ne
diffère que par le point qui vient d'être décrit.
Les arguments restants de ces fonctions sont comme suit :
- pid
-
pointe vers un tampon utilisé pour retourner l'identifiant du nouveau
processus enfant.
- file_actions
-
pointe vers un objet d'actions sur fichier qui indique les actions en
lien avec des fichiers devant être effectuées par l'enfant entre les étapes
fork(2) et exec(3). Cet objet est initialisé et rempli avant l'appel à
posix_spawn() par un appel aux fonctions
posix_spawn_file_actions_init(3) et posix_spawn_file_actions_*().
- attrp
-
pointe vers un objet d'attributs qui spécifie divers attributs du
processus enfant créé. Cet objet est initialisé et rempli avant l'appel à
posix_spawn() par un appel aux fonctions posix_spawnattr_init(3) et
posix_spawnattr_*().
- argv
-
envp
indiquent la liste des arguments ainsi que l'environnement du programme qui
doit être exécuté dans le processus enfant, de la même façon que
execve(2).
Ci-dessous, les fonctions sont décrites selon une méthode en trois étapes :
fork(), pré-exec() (exécuté dans l'enfant) et exec() (exécuté dans
l'enfant).
L’étape fork()
Depuis la glibc 2.24, la fonction posix_spawn() commence par appeler
clone(2) avec les drapeaux CLONE_VM et CLONE_VFORK. Les
implémentations plus anciennes utilisent fork(2) ou même vfork(2)
(voir ci-dessous).
L'identifiant du nouveau processus enfant est placé dans *pid. La
fonction posix_spawn() rend alors la main au processus appelant.
Ensuite, le parent peut utiliser l'un des appels système décrits dans
wait(2) pour vérifier l’état du processus enfant. Si l'enfant échoue dans
n'importe laquelle des étapes de nettoyage décrites ci-dessous ou n'arrive
pas à exécuter le fichier indiqué, il retourne avec un état 127.
Avant la glibc 2.24, le processus enfant est créé avec vfork(2) au lieu
de fork(2) lorsqu'une des conditions suivantes est remplie :
- -
-
l'élément spawn-flags de l'objet d'attributs sur lequel attrp pointe
contient le drapeau POSIX_SPAWN_USEVFORK spécifique à GNU ; ou
- -
-
file_actions est NULL et l'élément spawn-flags de l'objet d'attributs
sur lequel pointe attrp ne contient pas POSIX_SPAWN_SETSIGMASK,
POSIX_SPAWN_SETSIGDEF, POSIX_SPAWN_SETSCHEDPARAM,
POSIX_SPAWN_SETSCHEDULER, POSIX_SPAWN_SETPGROUP ou
POSIX_SPAWN_RESETIDS.
En d'autres termes, vfork(2) est utilisée si l'appelant le demande ou si
aucun nettoyage n'est attendu dans l'enfant avant qu'il n'exec(3)ute le
fichier demandé.
L’étape pré-exec() : nettoyage
Entre les étapes fork() et exec(), un processus enfant peut avoir à
effectuer un ensemble d'actions de nettoyage. Les fonctions posix_spawn()
et posix_spawnp() prennent en charge un ensemble, petit et bien
déterminé, de tâches système que l'enfant peut accomplir avant d'exécuter le
fichier exécutable. Ces opérations sont contrôlées par l'objet d'attributs
sur lequel attrp pointe et l'objet d'actions sur fichier sur lequel
file_actions pointe. Dans l'enfant, le traitement est fait dans l'ordre
suivant :
- (1)
-
Actions d'attributs de processus : masque de signaux, gestionnaires de
signaux par défaut, algorithme d'ordonnancement et paramètres, groupe du
processus, et les identifiants d'utilisateur et de groupe effectifs sont
changés comme indiqué dans l'objet d'attributs vers lequel attrp pointe.
- (2)
-
Les actions sur fichier, telles qu'indiquées dans l'argument file_action,
sont effectuées dans l'ordre dans lequel elles ont été spécifiées par les
appels aux fonctions posix_spawn_file_actions_add*().
- (3)
-
Les descripteurs de fichiers avec le drapeau FD_CLOEXEC sont fermés.
Tous les attributs de processus de l'enfant, autres que ceux affectés par
les attributs indiqués dans l'objet vers lequel attrp pointe et par les
actions sur fichier indiquées dans l'objet vers lequel file_actions
pointe, seront affectés comme si l'enfant avait été créé par fork(2) et
que le programme avait été exécuté par execve(2).
Les actions d'attributs de processus sont définies par l'objet d'attributs
vers lequel attrp pointe. L'attribut spawn-flags (indiqué par un appel
à posix_spawnattr_setflags(3)) contrôle les actions globales effectuées,
et les autres attributs de l'objet déterminent les valeurs utilisées durant
ces actions.
Les effets des drapeaux qui peuvent être indiqués dans spawn-flags sont
les suivants :
- POSIX_SPAWN_SETSIGMASK
-
Fixe le masque de signaux à l'ensemble donné dans l'attribut
spawn-sigmask de l'objet vers lequel attrp pointe. Si le drapeau
POSIX_SPAWN_SETSIGMASK n'est pas levé, alors l'enfant hérite du masque de
signaux de son parent.
- POSIX_SPAWN_SETSIGDEF
-
Réétablit la disposition de tous les signaux indiqués dans l'attribut
spawn-sigdefault de l'objet vers lequel attrp pointe à la valeur par
défaut. Pour le traitement des dispositions de signaux non spécifiées dans
l'attribut spawn-sigdefault ou le traitement lorsque
POSIX_SPAWN_SETSIGDEF n'est pas spécifié, consultez execve(2).
- POSIX_SPAWN_SETSCHEDPARAM
-
Si ce drapeau est levé et que le drapeau POSIX_SPAWN_SETSCHEDULER n'est
pas levé, fixer alors les paramètres de l'ordonnanceur aux paramètres
définis dans l'attribut spawn-schedparam de l'objet sur lequel attrp
pointe.
- POSIX_SPAWN_SETSCHEDULER
-
Fixe l'algorithme de stratégie d'ordonnancement et les paramètres de
l'enfant comme suit :
-
- -
-
La stratégie d'ordonnancement est réglée à la valeur indiquée dans
l'attribut spawn-schedpolicy de l'objet sur lequel attrp pointe.
- -
-
Les paramètres de l'ordonnanceur sont fixés à la valeur indiquée dans
l'attribut spawn-schedparam de l'objet sur lequel attrp pointe (mais
voir la section BOGUES).
Si les drapeaux POSIX_SPAWN_SETSCHEDPARAM et
POSIX_SPAWN_SETSCHEDPOLICY ne sont pas spécifiés, l'enfant hérite du
parent les attributs correspondants de l'ordonnanceur.
- POSIX_SPAWN_RESETIDS
-
Si le drapeau est levé, réinitialiser les UID et GID effectifs aux UID et
GID réels du processus parent. Si ce drapeau n'est pas indiqué, alors
l'enfant conserve les UID et GID effectifs du processus parent. Dans les
deux cas, si les bits de permission set-user-ID et set-group-ID sont activés
sur le fichier exécutable, leur effet surcharge la valeur des UID et GID
effectifs (voir execve(2)).
- POSIX_SPAWN_SETPGROUP
-
Fixer le groupe du processus à la valeur indiquée dans l'attribut
spawn-pgroup de l'objet sur lequel attrp pointe. Si l'attribut
spawn-pgroup à une valeur de 0, l'identifiant de groupe du processus
enfant est rendu identique à l'identifiant de processus. Si le drapeau
POSIX_SPAWN_SETPGROUP n'est pas levé, l'enfant hérite de l'identifiant de
groupe du processus parent.
- POSIX_SPAWN_USEVFORK
-
Depuis la version 2.24 de la glibc, ce drapeau n'a aucun effet. Sur des
implémentations plus anciennes, lever ce drapeau force l’étape fork() à
utiliser vfork(2) à la place de fork(2). La macro de test de
fonctionnalités _GNU_SOURCE doit être définie pour obtenir une définition
de cette constante.
- POSIX_SPAWN_SETSID (depuis la glibc 2.26)
-
Si ce drapeau est levé, le processus enfant doit créer une nouvelle session
et devenir le responsable de cette session. Le processus enfant doit aussi
devenir le responsable du nouveau groupe du processus de la session (voir
setid(2)). La macro de test de fonctionnalités _GNU_SOURCE doit être
définie pour obtenir la définition de cette constante.
Si attrp est NULL, alors les comportements par défaut décrits plus haut
pour chaque drapeau s'appliquent.
L'argument file_actions indique une séquence d'opérations sur fichier
effectuées dans le processus enfant après le traitement général décrit plus
haut et avant de faire l’étape exec(). Si file_actions est NULL,
aucune action spécifique n'est effectuée et la sémantique standard de
exec(3) s'applique : les descripteurs de fichier ouverts avant exec()
restent ouverts dans le nouveau processus à l'exception de ceux pour
lesquels le drapeau FD_CLOEXEC a été levé. Les verrous de fichier restent
en place.
Si file_actions n'est pas NULL, il contient un ensemble ordonné de
demandes pour exécuter open(2), close(2) et dup2() sur des fichiers
. Ces requêtes sont ajoutées à file_actions par
posix_spawn_file_actions_addopen(3),
posix_spawn_file_actions_addclose(3) et
posix_spawn_file_actions_adddup2(3). Les opérations demandées sont
effectuées dans l'ordre dans lequel elles ont été ajoutées à
file_actions.
Si une des actions de nettoyage échoue (à cause de mauvaises valeurs ou pour
toute autre raison pour laquelle la gestion de signaux, l'ordonnancement de
processus, les fonctions d'identifiant de groupe de processus ou
d'opérations de descripteur de fichier peuvent échouer), le processus enfant
termine avec un code de retour de 127.
L’étape exec()
Une fois que l'enfant s'est dédoublé sans erreur et a exécuté toutes les
étapes pré-exec(), l'enfant lance l'exécutable souhaité.
Le processus enfant récupère son environnement depuis l'argument envp,
analysé comme si execve(2) avait été appelé avec. Les arguments du
processus créé viennent de l'argument argv, analysé comme pour
execve(2).
VALEUR RENVOYÉE
En cas de succès, posix_spawn() et posix_spawnp() placent
l'identifiant du processus enfant dans pid et renvoient 0. En cas
d'erreur lors de l’étape fork(), aucun enfant n'est créé, le contenu de
*pid n'est pas défini et ces fonctions renvoient un code d'erreur comme
décrit plus bas.
Même lorsque ces fonctions renvoient un état de réussite, le processus
enfant peut encore échouer pour une pléthore de raisons liées au
pré-exec(). De plus, exec(3) peut échouer. Dans tous ces cas, le
processus enfant termine avec 127 comme code de retour.
ERREURS
Les fonctions posix_spawn() et posix_spawnp() n'échouent que dans le
cas où l'appel sous-jacent à fork(2), vfork(2) ou clone(2)
échoue. Dans ces cas, ces fonctions renvoient un code d'erreur correspondant
aux erreurs décrites pour fork(2), vfork(2) ou clone(2).
De plus, ces fonction échouent si :
- ENOSYS
-
Fonction non prise en charge sur ce système.
STANDARDS
POSIX.1-2008.
HISTORIQUE
glibc 2.2. POSIX.1-2001.
NOTES
Les activités de nettoyage dans l'enfant sont contrôlées par les objets sur
lesquels attrp pointe (pour les actions n'agissant pas sur des fichiers)
et file_actions. Dans le jargon POSIX, les types de données
posix_spawnattr_t et posix_spawn_file_actions_t sont évoqués comme des
objets et leurs éléments ne sont pas spécifiés par des noms. Les programmes
portables doivent initialiser ces objets par l'appel aux fonctions
spécifiées par POSIX uniquement. En d'autres termes, bien que ces objets
puissent être implémentés avec des structures contenant des champs, les
programmes portables doivent éviter toute dépendance à de tels détails
d'implémentation.
Selon POSIX, il n'est pas déterminé si les gestionnaires de dédoublement
établis avec pthread_atfork(3) sont appelés lorsque posix_spawn() est
appelée. Depuis la version 2.24 de la glibc, les gestionnaires de
dédoublement ne sont jamais exécutés. Sur des implémentations plus
anciennes, les gestionnaires de dédoublement ne sont appelés que si l'enfant
est créé avec fork(2).
Il n'existe pas de fonction « posix_fspawn » (c'est-à-dire une fonction qui
serait à posix_spawn() ce que fexecve(3) est à
execve(2)). Cependant, cette fonctionnalité peut être obtenue en
spécifiant l'argument path comme l'un des fichiers dans le répertoire
/proc/self/fd de l'appelant.
BOGUES
POSIX.1 spécifie que lorsque POSIX_SPAWN_SETSCHEDULER est indiqué dans
spawn-flags, alors POSIX_SPAWN_SETSCHEDPARAM est ignoré s'il est
présent. Cependant, avant la version 2.14 de la glibc, les appels à
posix_spawn() échouent avec une erreur si POSIX_SPAWN_SETSCHEDULER est
indiqué sans que POSIX_SPAWN_SETSCHEDPARAM ne le soit également.
EXEMPLES
Le programme suivant illustre l'utilisation de plusieurs fonctions de l'API
spawn de POSIX. Le programme accepte des attributs en ligne de commande qui
peuvent être utilisés pour créer des objets d'actions sur fichier ou
d'attributs. Les arguments de la ligne de commande restants sont utilisés
comme nom de l'exécutable et comme arguments de ligne de commande du
programme exécuté dans l'enfant.
Dans la première invocation, la commande date(1) est exécutée dans
l'enfant et l'appel à posix_spawn() n'utilise pas d'objets d'actions sur
fichier ou d'attributs.
$ ./a.out date
PID de l'enfant : 7634
Tue Feb 1 19:47:50 CEST 2011
État de l'enfant : terminé, statut=0
Dans la deuxième invocation, l'option en ligne de commande -c est
utilisée pour créer un objet d'actions sur fichier qui ferme la sortie
standard dans l'enfant. Par la suite, date(1) échoue lors d'une tentative
d'écriture et termine avec un état 1.
$ ./a.out -c date
PID de l'enfant : 7636
date : erreur d'écriture : Mauvais descripteur de fichier
État de l'enfant : terminé, état=1
Dans l'invocation suivante, l'option en ligne de commande -s est utilisée
pour créer un objet d'attributs qui indique que tous les signaux (blocables)
doivent être bloqués dans l'enfant. Par la suite, une tentative de tuer
l'enfant par le signal par défaut envoyé par kill(1) (c'est-à-dire
SIGTERM) échoue car ce signal est bloqué. Par conséquent, il est
nécessaire d'utiliser SIGKILL pour tuer l'enfant (car SIGKILL ne peut
être bloqué).
$ ./a.out -s sleep 60 &
[1] 7637
$ PID de l'enfant : 7638
$ kill 7638
$ kill -KILL 7638
$ État de l'enfant : tué par le signal 9
[1]+ Fait ./a.out -s sleep 60
Lorsque l'enfant tente d'exécuter une commande qui n'existe pas, l'appel à
exec(3) échoue et l'enfant termine avec un état 127.
$ ./a.out xxxxx PID de l'enfant : 10190 Statut de l'enfant : terminé, état=127
Source du programme
#include <errno.h>
#include <spawn.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wait.h>
#define errExit(msg) do { perror(msg); \
exit(EXIT_FAILURE); } while (0)
#define errExitEN(en, msg) \
do { errno = en; perror(msg); \
exit(EXIT_FAILURE); } while (0)
char **environ;
int
main(int argc, char *argv[])
{
pid_t child_pid;
int s, opt, status;
sigset_t mask;
posix_spawnattr_t attr;
posix_spawnattr_t *attrp;
posix_spawn_file_actions_t file_actions;
posix_spawn_file_actions_t *file_actionsp;
/* Parse command-line options, which can be used to specify an
attributes object and file actions object for the child. */
attrp = NULL;
file_actionsp = NULL;
while ((opt = getopt(argc, argv, "sc")) != -1) {
switch (opt) {
case 'c': /* -c: close standard output in child */
/* Create a file actions object and add a "close"
action to it. */
s = posix_spawn_file_actions_init(&file_actions);
if (s != 0)
errExitEN(s, "posix_spawn_file_actions_init");
s = posix_spawn_file_actions_addclose(&file_actions,
STDOUT_FILENO);
if (s != 0)
errExitEN(s, "posix_spawn_file_actions_addclose");
file_actionsp = &file_actions;
break;
case 's': /* -s: block all signals in child */
/* Create an attributes object and add a "set signal mask"
action to it. */
s = posix_spawnattr_init(&attr);
if (s != 0)
errExitEN(s, "posix_spawnattr_init");
s = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK);
if (s != 0)
errExitEN(s, "posix_spawnattr_setflags");
sigfillset(&mask);
s = posix_spawnattr_setsigmask(&attr, &mask);
if (s != 0)
errExitEN(s, "posix_spawnattr_setsigmask");
attrp = &attr;
break;
}
}
/* Spawn the child. The name of the program to execute and the
command-line arguments are taken from the command-line arguments
of this program. The environment of the program execed in the
child is made the same as the parent's environment. */
s = posix_spawnp(&child_pid, argv[optind], file_actionsp, attrp,
&argv[optind], environ);
if (s != 0)
errExitEN(s, "posix_spawn");
/* Destroy any objects that we created earlier. */
if (attrp != NULL) {
s = posix_spawnattr_destroy(attrp);
if (s != 0)
errExitEN(s, "posix_spawnattr_destroy");
}
if (file_actionsp != NULL) {
s = posix_spawn_file_actions_destroy(file_actionsp);
if (s != 0)
errExitEN(s, "posix_spawn_file_actions_destroy");
}
printf("PID of child: %jd\n", (intmax_t) child_pid);
/* Monitor status of the child until it terminates. */
do {
s = waitpid(child_pid, &status, WUNTRACED | WCONTINUED);
if (s == -1)
errExit("waitpid");
printf("Child status: ");
if (WIFEXITED(status)) {
printf("exited, status=%d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("killed by signal %d\n", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
printf("stopped by signal %d\n", WSTOPSIG(status));
} else if (WIFCONTINUED(status)) {
printf("continued\n");
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
exit(EXIT_SUCCESS);
}
VOIR AUSSI
close(2), dup2(2), execl(2), execlp(2), fork(2), open(2),
sched_setparam(2), sched_setscheduler(2), setpgid(2), setuid(2),
sigaction(2), sigprocmask(2), posix_spawn_file_actions_addclose(3),
posix_spawn_file_actions_adddup2(3),
posix_spawn_file_actions_addopen(3),
posix_spawn_file_actions_destroy(3), posix_spawn_file_actions_init(3),
posix_spawnattr_destroy(3), posix_spawnattr_getflags(3),
posix_spawnattr_getpgroup(3), posix_spawnattr_getschedparam(3),
posix_spawnattr_getschedpolicy(3), posix_spawnattr_getsigdefault(3),
posix_spawnattr_getsigmask(3), posix_spawnattr_init(3),
posix_spawnattr_setflags(3), posix_spawnattr_setpgroup(3),
posix_spawnattr_setschedparam(3), posix_spawnattr_setschedpolicy(3),
posix_spawnattr_setsigdefault(3), posix_spawnattr_setsigmask(3),
pthread_atfork(3), <spawn.h>, Base Definitions volume of
POSIX.1-2001, http://www.opengroup.org/unix/online.html
TRADUCTION
La traduction française de cette page de manuel a été créée par
Christophe Blaess <https://www.blaess.fr/christophe/>,
Stéphan Rafin <stephan.rafin@laposte.net>,
Thierry Vignaud <tvignaud@mandriva.com>,
François Micaux,
Alain Portal <aportal@univ-montp2.fr>,
Jean-Philippe Guérard <fevrier@tigreraye.org>,
Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>,
Julien Cristau <jcristau@debian.org>,
Thomas Huriaux <thomas.huriaux@gmail.com>,
Nicolas François <nicolas.francois@centraliens.net>,
Florentin Duneau <fduneau@gmail.com>,
Simon Paillard <simon.paillard@resel.enst-bretagne.fr>,
Denis Barbier <barbier@debian.org>,
David Prévot <david@tilapin.org>
et
Grégoire Scano <gregoire.scano@malloc.fr>
Cette traduction est une documentation libre ; veuillez vous reporter à la
GNU General Public License version 3
concernant les conditions de copie et
de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel,
veuillez envoyer un message à
Index
- NOM
-
- BIBLIOTHÈQUE
-
- SYNOPSIS
-
- DESCRIPTION
-
- L’étape fork()
-
- L’étape pré-exec() : nettoyage
-
- L’étape exec()
-
- VALEUR RENVOYÉE
-
- ERREURS
-
- STANDARDS
-
- HISTORIQUE
-
- NOTES
-
- BOGUES
-
- EXEMPLES
-
- Source du programme
-
- VOIR AUSSI
-
- TRADUCTION
-
This document was created by
man2html,
using the manual pages.
Time: 05:06:21 GMT, September 19, 2025