system
Table des matières
Retour à l'index
NOM
system - Exécuter une commande d'interpréteur
BIBLIOTHÈQUE
Bibliothèque C standard (libc, -lc)
SYNOPSIS
#include <stdlib.h>
int system(const char *commande);
DESCRIPTION
La fonction de bibliothèque system() se comporte comme si elle utilisait
fork(2) pour créer un processus enfant qui exécuterait la commande
d’interpréteur indiquée dans commande en utilisant execl(3) comme
ceci :
execl("/bin/sh", "sh", "-c", commande, (char *) NULL);
system() se termine après l’exécution de la commande.
Lors de l’exécution de la commande, SIGCHLD sera bloqué, et SIGINT et
SIGQUIT seront ignorés dans le processus qui appelle system() (ces
signaux seront traités conformément à leurs valeurs par défaut dans le
processus enfant qui exécute commande).
Si la valeur de commande est NULL, system() renvoie un état indiquant
si un interpréteur de commande est disponible sur le système.
VALEUR RENVOYÉE
La valeur renvoyée par system() est une des suivantes :
- -
-
Si commande est NULL, alors une valeur différente de zéro est renvoyée si
un interpréteur de commandes est accessible, et 0 sinon.
- -
-
Si un processus enfant n’a pas pu être créé ou si son état n’a pas pu être
récupéré, la valeur renvoyée est -1 et errno est définie pour indiquer
l'erreur.
- -
-
Si un interpréteur n’a pas pu s’exécuter dans le processus enfant, alors la
valeur renvoyée est comme si l’interpréteur enfant s’était terminé en
appelant _exit(2) avec l’état 127.
- -
-
Si tous les appels système réussissent, alors la valeur renvoyée est l’état
de retour de l’interpréteur enfant utilisé pour exécuter commande (l’état
final d’un interpréteur est l’état final de la dernière commande qu’il
exécute).
Dans les deux derniers cas, la valeur renvoyée est un « état d’attente » qui
peut être examiné en utilisant les macros décrites dans waitpid(2)
(c’est-à-dire WIFEXITED(), WEXITSTATUS(), etc.).
system() n'affecte pas l'état d'attente des autres processus enfants.
ERREURS
system() peut échouer avec une des erreurs décrites pour fork(2).
ATTRIBUTS
Pour une explication des termes utilisés dans cette section, consulter
attributes(7).
| Interface | Attribut | Valeur
|
|
system()
| Sécurité des threads | MT-Safe
|
STANDARDS
C11, POSIX.1-2008.
HISTORIQUE
POSIX.1-2001, C89.
NOTES
system() fournit simplicité et commodité : elle gère tous les détails des
appels de fork(2), execl(3) et waitpid(2), ainsi que les
manipulations nécessaires des signaux ; de plus, l’interpréteur de commande
réalise les substitutions habituelles et les redirections des entrées et
sorties de commande. L'inconvénient principal de system() est son
manque d'efficacité : des appels système supplémentaires sont nécessaires
pour créer le processus qui exécute l’interpréteur de commande et pour
exécuter l’interpréteur de commande.
Si la macro de test de fonctionnalité _XOPEN_SOURCE est définie (avant
d'inclure tout fichier d'en-tête), les macros décrites dans
waitpid(2) (WEXITSTATUS(), etc.) sont disponibles en incluant
<stdlib.h>.
Comme mentionné plus haut, system() ignore SIGINT et SIGQUIT. Un
programme qui l'appelle depuis une boucle risque de ne pas pouvoir être
interrompu, à moins qu'il ne vérifie le code de retour de l'enfant. Par
exemple :
while (quelque_chose) {
int ret = system("toto");
if (WIFSIGNALED(ret) &&
(WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT))
break;
}
Selon POSIX.1, il n'est pas précisé si les gestionnaires enregistrés à
l'aide de pthread_atfork(3) sont appelés au cours de l'exécution de
system(). Dans l'implémentation de la glibc, de tels gestionnaires ne
sont pas appelés.
Avant la glibc 2.1.3, la vérification de la disponibilité de /bin/sh
n'était pas réellement exécutée lorsque commande était NULL. Il était
supposé être toujours disponible, et system() renvoyait toujours 1
dans ce cas. Depuis la glibc 2.1.3, cette vérification est effectuée, car,
même si POSIX.1-2001 impose une implémentation conforme pour fournir un
interpréteur, cet interpréteur peut ne pas être disponible ou exécutable si
le programme appelant a auparavant appelé chroot(2) (ce qui n'est pas
spécifié dans POSIX.1-2001).
La commande d’interpréteur peut se terminer avec un état de 127, ce qui
provoque une valeur renvoyée de system() non distinguable du cas où un
interpréteur n’a pas pu être exécuté dans le processus enfant.
Mises en garde
N'utilisez pas system() à partir d'un programme avec privilèges (un
programme set-user-ID, set-group-ID ou possédant des capacités), car des
valeurs particulières de certaines variables d'environnement pourraient être
utilisées pour corrompre l'intégrité du système. Par exemple, PATH
pourrait être redéfinie de façon à exécuter un programme arbitraire avec
privilèges. Utilisez plutôt la famille de fonctions exec(3), mais pas
execlp(3) ou execvp(3) (qui utilisent aussi la variable
d'environnement PATH pour rechercher un exécutable).
En fait, system() ne fonctionnera pas correctement à partir de programmes
ayant des privilèges set-user-ID ou set-group-ID sur les systèmes où
/bin/sh redirige vers bash version 2, car ce dernier annule les
privilèges au démarrage par mesure de sécurité (Debian utilise un
interpréteur de commande différent, dash(1), qui n'effectue pas cette
annulation de privilèges si on l'invoque à l'aide du lien symbolique sh).
Toute entrée utilisateur qui constitue une partie de commande doit être
nettoyée avec soin afin de s'assurer que des commandes de l'interpréteur
ou des options de commandes inattendues ne seront pas exécutées. Les risques
de ce type sont particulièrement graves lorsqu'on utilise system() à
partir d'un programme avec privilèges.
BOGUES
Si le nom de la commande commence par un trait d'union, sh(1) interprète
ce nom comme une option et le résultat est indéterminé (voir l'option -c
de sh(1)). Pour contourner ce problème, préfixez le nom de la commande
avec une espace comme dans l'appel suivant :
system(" -nom-de-commande-problématique");
VOIR AUSSI
sh(1), execve(2), fork(2), sigaction(2), sigprocmask(2),
wait(2), exec(3), signal(7)
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
Lucien Gentis <lucien.gentis@waika9.com>
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
-
- VALEUR RENVOYÉE
-
- ERREURS
-
- ATTRIBUTS
-
- STANDARDS
-
- HISTORIQUE
-
- NOTES
-
- Mises en garde
-
- BOGUES
-
- VOIR AUSSI
-
- TRADUCTION
-
This document was created by
man2html,
using the manual pages.
Time: 05:06:28 GMT, September 19, 2025