posix_spawn(3) Library Functions Manual posix_spawn(3) NOM posix_spawn, posix_spawnp -- Engendrer un processus BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include 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 utilisees pour creer un processus enfant qui execute le fichier indique. Ces fonctions sont specifiees par POSIX pour fournir une methode standard de creation de nouveaux processus sur les machines n'ayant pas la capacite de prendre l'appel systeme fork(2) en charge. Ces machines sont en general de petits systemes embarques sans MMU. Les fonctions posix_spawn() et posix_spawnp() fournissent les fonctionnalites de fork(2) et exec(3) combinees, completees par des etapes facultatives de nettoyage dans l'enfant avant l'appel a exec(3). Ces fonctions n'ont pas vocation a remplacer les appels systemes fork(2) et execve(2). En fait, elles ne fournissent qu'un sous-ensemble des fonctionnalites qui peuvent etre realisees par ces appels systemes. La seule difference entre posix_spawn() et posix_spawnp() est la maniere avec laquelle elles specifient le fichier devant etre execute par le processus enfant. Avec posix_spawn(), le fichier executable est indique par un chemin (absolu ou relatif). Avec posix_spawnp(), le fichier executable n'est indique que par un nom de fichier et le systeme le cherche dans la liste des repertoires indiques dans PATH (de la meme facon que execvp(3)). Le reste de cette page est ecrit du point de vue de posix_spawn() et il est a garder en memoire que posix_spawnp() ne differe que par le point qui vient d'etre decrit. Les arguments restants de ces fonctions sont comme suit : pid pointe vers un tampon utilise 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 etre effectuees par l'enfant entre les etapes fork(2) et exec(3). Cet objet est initialise et rempli avant l'appel a 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 specifie divers attributs du processus enfant cree. Cet objet est initialise et rempli avant l'appel a 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 etre execute dans le processus enfant, de la meme facon que execve(2). Ci-dessous, les fonctions sont decrites selon une methode en trois etapes : fork(), pre-exec() (execute dans l'enfant) et exec() (execute dans l'enfant). L'etape fork() Depuis la glibc 2.24, la fonction posix_spawn() commence par appeler clone(2) avec les drapeaux CLONE_VM et CLONE_VFORK. Les implementations plus anciennes utilisent fork(2) ou meme vfork(2) (voir ci-dessous). L'identifiant du nouveau processus enfant est place dans *pid. La fonction posix_spawn() rend alors la main au processus appelant. Ensuite, le parent peut utiliser l'un des appels systeme decrits dans wait(2) pour verifier l'etat du processus enfant. Si l'enfant echoue dans n'importe laquelle des etapes de nettoyage decrites ci-dessous ou n'arrive pas a executer le fichier indique, il retourne avec un etat 127. Avant la glibc 2.24, le processus enfant est cree avec vfork(2) au lieu de fork(2) lorsqu'une des conditions suivantes est remplie : - l'element spawn-flags de l'objet d'attributs sur lequel attrp pointe contient le drapeau POSIX_SPAWN_USEVFORK specifique a GNU ; ou - file_actions est NULL et l'element 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 utilisee si l'appelant le demande ou si aucun nettoyage n'est attendu dans l'enfant avant qu'il n'exec(3)ute le fichier demande. L'etape pre-exec() : nettoyage Entre les etapes fork() et exec(), un processus enfant peut avoir a effectuer un ensemble d'actions de nettoyage. Les fonctions posix_spawn() et posix_spawnp() prennent en charge un ensemble, petit et bien determine, de taches systeme que l'enfant peut accomplir avant d'executer le fichier executable. Ces operations sont controlees 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 defaut, algorithme d'ordonnancement et parametres, groupe du processus, et les identifiants d'utilisateur et de groupe effectifs sont changes comme indique dans l'objet d'attributs vers lequel attrp pointe. (2) Les actions sur fichier, telles qu'indiquees dans l'argument file_action, sont effectuees dans l'ordre dans lequel elles ont ete specifiees par les appels aux fonctions posix_spawn_file_actions_add*(). (3) Les descripteurs de fichiers avec le drapeau FD_CLOEXEC sont fermes. Tous les attributs de processus de l'enfant, autres que ceux affectes par les attributs indiques dans l'objet vers lequel attrp pointe et par les actions sur fichier indiquees dans l'objet vers lequel file_actions pointe, seront affectes comme si l'enfant avait ete cree par fork(2) et que le programme avait ete execute par execve(2). Les actions d'attributs de processus sont definies par l'objet d'attributs vers lequel attrp pointe. L'attribut spawn-flags (indique par un appel a posix_spawnattr_setflags(3)) controle les actions globales effectuees, et les autres attributs de l'objet determinent les valeurs utilisees durant ces actions. Les effets des drapeaux qui peuvent etre indiques dans spawn-flags sont les suivants : POSIX_SPAWN_SETSIGMASK Fixe le masque de signaux a l'ensemble donne dans l'attribut spawn-sigmask de l'objet vers lequel attrp pointe. Si le drapeau POSIX_SPAWN_SETSIGMASK n'est pas leve, alors l'enfant herite du masque de signaux de son parent. POSIX_SPAWN_SETSIGDEF Reetablit la disposition de tous les signaux indiques dans l'attribut spawn-sigdefault de l'objet vers lequel attrp pointe a la valeur par defaut. Pour le traitement des dispositions de signaux non specifiees dans l'attribut spawn-sigdefault ou le traitement lorsque POSIX_SPAWN_SETSIGDEF n'est pas specifie, consultez execve(2). POSIX_SPAWN_SETSCHEDPARAM Si ce drapeau est leve et que le drapeau POSIX_SPAWN_SETSCHEDULER n'est pas leve, fixer alors les parametres de l'ordonnanceur aux parametres definis dans l'attribut spawn-schedparam de l'objet sur lequel attrp pointe. POSIX_SPAWN_SETSCHEDULER Fixe l'algorithme de strategie d'ordonnancement et les parametres de l'enfant comme suit : - La strategie d'ordonnancement est reglee a la valeur indiquee dans l'attribut spawn-schedpolicy de l'objet sur lequel attrp pointe. - Les parametres de l'ordonnanceur sont fixes a la valeur indiquee 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 specifies, l'enfant herite du parent les attributs correspondants de l'ordonnanceur. POSIX_SPAWN_RESETIDS Si le drapeau est leve, reinitialiser les UID et GID effectifs aux UID et GID reels du processus parent. Si ce drapeau n'est pas indique, 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 actives sur le fichier executable, leur effet surcharge la valeur des UID et GID effectifs (voir execve(2)). POSIX_SPAWN_SETPGROUP Fixer le groupe du processus a la valeur indiquee dans l'attribut spawn-pgroup de l'objet sur lequel attrp pointe. Si l'attribut spawn-pgroup a une valeur de 0, l'identifiant de groupe du processus enfant est rendu identique a l'identifiant de processus. Si le drapeau POSIX_SPAWN_SETPGROUP n'est pas leve, l'enfant herite 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 implementations plus anciennes, lever ce drapeau force l'etape fork() a utiliser vfork(2) a la place de fork(2). La macro de test de fonctionnalites _GNU_SOURCE doit etre definie pour obtenir une definition de cette constante. POSIX_SPAWN_SETSID (depuis la glibc 2.26) Si ce drapeau est leve, le processus enfant doit creer 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 fonctionnalites _GNU_SOURCE doit etre definie pour obtenir la definition de cette constante. Si attrp est NULL, alors les comportements par defaut decrits plus haut pour chaque drapeau s'appliquent. L'argument file_actions indique une sequence d'operations sur fichier effectuees dans le processus enfant apres le traitement general decrit plus haut et avant de faire l'etape exec(). Si file_actions est NULL, aucune action specifique n'est effectuee et la semantique standard de exec(3) s'applique : les descripteurs de fichier ouverts avant exec() restent ouverts dans le nouveau processus a l'exception de ceux pour lesquels le drapeau FD_CLOEXEC a ete leve. Les verrous de fichier restent en place. Si file_actions n'est pas NULL, il contient un ensemble ordonne de demandes pour executer open(2), close(2) et dup2() sur des fichiers . Ces requetes sont ajoutees a file_actions par posix_spawn_file_actions_addopen(3), posix_spawn_file_actions_addclose(3) et posix_spawn_file_actions_adddup2(3). Les operations demandees sont effectuees dans l'ordre dans lequel elles ont ete ajoutees a file_actions. Si une des actions de nettoyage echoue (a 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'operations de descripteur de fichier peuvent echouer), le processus enfant termine avec un code de retour de 127. L'etape exec() Une fois que l'enfant s'est dedouble sans erreur et a execute toutes les etapes pre-exec(), l'enfant lance l'executable souhaite. Le processus enfant recupere son environnement depuis l'argument envp, analyse comme si execve(2) avait ete appele avec. Les arguments du processus cree viennent de l'argument argv, analyse comme pour execve(2). VALEUR RENVOYEE En cas de succes, posix_spawn() et posix_spawnp() placent l'identifiant du processus enfant dans pid et renvoient 0. En cas d'erreur lors de l'etape fork(), aucun enfant n'est cree, le contenu de *pid n'est pas defini et ces fonctions renvoient un code d'erreur comme decrit plus bas. Meme lorsque ces fonctions renvoient un etat de reussite, le processus enfant peut encore echouer pour une plethore de raisons liees au pre-exec(). De plus, exec(3) peut echouer. Dans tous ces cas, le processus enfant termine avec 127 comme code de retour. ERREURS Les fonctions posix_spawn() et posix_spawnp() n'echouent que dans le cas ou l'appel sous-jacent a fork(2), vfork(2) ou clone(2) echoue. Dans ces cas, ces fonctions renvoient un code d'erreur correspondant aux erreurs decrites pour fork(2), vfork(2) ou clone(2). De plus, ces fonction echouent si : ENOSYS Fonction non prise en charge sur ce systeme. STANDARDS POSIX.1-2008. HISTORIQUE glibc 2.2. POSIX.1-2001. NOTES Les activites de nettoyage dans l'enfant sont controlees 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 donnees posix_spawnattr_t et posix_spawn_file_actions_t sont evoques comme des objets et leurs elements ne sont pas specifies par des noms. Les programmes portables doivent initialiser ces objets par l'appel aux fonctions specifiees par POSIX uniquement. En d'autres termes, bien que ces objets puissent etre implementes avec des structures contenant des champs, les programmes portables doivent eviter toute dependance a de tels details d'implementation. Selon POSIX, il n'est pas determine si les gestionnaires de dedoublement etablis avec pthread_atfork(3) sont appeles lorsque posix_spawn() est appelee. Depuis la version 2.24 de la glibc, les gestionnaires de dedoublement ne sont jamais executes. Sur des implementations plus anciennes, les gestionnaires de dedoublement ne sont appeles que si l'enfant est cree avec fork(2). Il n'existe pas de fonction << posix_fspawn >> (c'est-a-dire une fonction qui serait a posix_spawn() ce que fexecve(3) est a execve(2)). Cependant, cette fonctionnalite peut etre obtenue en specifiant l'argument path comme l'un des fichiers dans le repertoire /proc/self/fd de l'appelant. BOGUES POSIX.1 specifie que lorsque POSIX_SPAWN_SETSCHEDULER est indique dans spawn-flags, alors POSIX_SPAWN_SETSCHEDPARAM est ignore s'il est present. Cependant, avant la version 2.14 de la glibc, les appels a posix_spawn() echouent avec une erreur si POSIX_SPAWN_SETSCHEDULER est indique sans que POSIX_SPAWN_SETSCHEDPARAM ne le soit egalement. 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 etre utilises pour creer des objets d'actions sur fichier ou d'attributs. Les arguments de la ligne de commande restants sont utilises comme nom de l'executable et comme arguments de ligne de commande du programme execute dans l'enfant. Dans la premiere invocation, la commande date(1) est executee dans l'enfant et l'appel a 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 Etat de l'enfant : termine, statut=0 Dans la deuxieme invocation, l'option en ligne de commande -c est utilisee pour creer un objet d'actions sur fichier qui ferme la sortie standard dans l'enfant. Par la suite, date(1) echoue lors d'une tentative d'ecriture et termine avec un etat 1. $ ./a.out -c date PID de l'enfant : 7636 date : erreur d'ecriture : Mauvais descripteur de fichier Etat de l'enfant : termine, etat=1 Dans l'invocation suivante, l'option en ligne de commande -s est utilisee pour creer un objet d'attributs qui indique que tous les signaux (blocables) doivent etre bloques dans l'enfant. Par la suite, une tentative de tuer l'enfant par le signal par defaut envoye par kill(1) (c'est-a-dire SIGTERM) echoue car ce signal est bloque. Par consequent, il est necessaire d'utiliser SIGKILL pour tuer l'enfant (car SIGKILL ne peut etre bloque). $ ./a.out -s sleep 60 & [1] 7637 $ PID de l'enfant : 7638 $ kill 7638 $ kill -KILL 7638 $ Etat de l'enfant : tue par le signal 9 [1]+ Fait ./a.out -s sleep 60 Lorsque l'enfant tente d'executer une commande qui n'existe pas, l'appel a exec(3) echoue et l'enfant termine avec un etat 127. $ ./a.out xxxxx PID de l'enfant : 10190 Statut de l'enfant : termine, etat=127 Source du programme #include #include #include #include #include #include #include #include #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), , Base Definitions volume of POSIX.1-2001, http://www.opengroup.org/unix/online.html TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Gregoire Scano Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 posix_spawn(3)