Provided by: manpages-fr-dev_4.27.0-1_all 

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;
/* Lire les options de la ligne de commande pouvant être utilisées
pour indiquer un objet d'attributs et un objet d'actions sur fichier
fichier pour l'enfant. */
attrp = NULL;
file_actionsp = NULL;
while ((opt = getopt(argc, argv, "sc")) != -1) {
switch (opt) {
case 'c': /* -c: fermer la sortie standard dans
l'enfant */
/* Créer un objet d'actions de fichier et lui ajouter
une action "fermer". */
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: bloquer tous les signaux dans
l'enfant */
/* Créer un objet d'attributs et lui ajouter
une action "établir un masque de signaux". */
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;
}
}
/* Créer l'enfant. Le nom du programme à exécuter et les arguments de
la ligne de commande sont récupérés dans les arguments de la ligne
de commande de ce programme. L'environnement du programme exécuté
dans l'enfant est identique à l'environnement du parent. */
s = posix_spawnp(&child_pid, argv[optind], file_actionsp, attrp,
&argv[optind], environ);
if (s != 0)
errExitEN(s, "posix_spawn");
/* Détruire tout objet créé précédemment. */
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 de l'enfant : %jd\n", (intmax_t) child_pid);
/* Observer l’état de l'enfant jusqu'à son arrêt. */
do {
s = waitpid(child_pid, &status, WUNTRACED | WCONTINUED);
if (s == -1)
errExit("waitpid");
printf("Child status: ");
if (WIFEXITED(status)) {
printf("terminé, état=%d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("tué par le signal %d\n", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
printf("arrêté par le signal %d\n", WSTOPSIG(status));
} else if (WIFCONTINUED(status)) {
printf("reprise\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 à
debian-l10n-french@lists.debian.org.
Pages du manuel de Linux 6.9.1 15 juin 2024 posix_spawn(3)