Je ne comprends pas comment execlp() fonctionne sous Linux
J'ai passé les 2 derniers jours à essayer de comprendre l'appel système execlp()
, mais pourtant je suis là. Permettez-moi de passer directement à la question.
Le man page
de execlp déclare l'appel système comme int execlp(const char *file, const char *arg, ...);
avec la description: le const char arg et les ellipses suivantes dans les fonctions execl (), execlp () et execle () peuvent être considérés comme arg0, arg1, ..., argn.
Pourtant, je vois l'appel système appelé comme ceci dans notre livre de texte: execlp(“/bin/sh”, ..., “ls -l /bin/??”, ...);
(le"..."sont pour nous de comprendre que étudiant). Cependant, cet appel système ne ressemble même pas à la déclaration sur le man page
de l'appel système.
Je suis super confus. Toute aide est appréciée.
2 réponses
Ce prototype:
int execlp(const char *file, const char *arg, ...);
Indique que execlp est une fonction d'argument variable. Il faut 2 const char *
. Le reste des arguments, le cas échéant, sont les arguments supplémentaires à remettre au programme que nous voulons exécuter - aussi char *
- Tous ces éléments sont des chaînes C (et le dernier argument doit être un pointeur NULL)
Donc, {la[9]} argument est le nom du chemin d'accès d'un fichier exécutable à exécuter. {[10] } est la chaîne que nous voulons apparaître comme argv[0]
dans l'exécutable. Par convention, argv[0]
est juste le nom de fichier de l'exécutable, normalement il est défini sur file
.
Le ...
sont maintenant les arguments supplémentaires pour donner à l'exécutable.
Disons que vous exécutez ceci à partir d'une ligne de commande/shell:
$ ls
, ce serait execlp("ls", "ls", (char *)NULL);
Ou si vous exécutez
$ ls -l /
, ce serait execlp("ls", "ls", "-l", "/", (char *)NULL);
Ainsi de suite à execlp("/bin/sh", ..., "ls -l /bin/??", ...);
Ici, vous allez au shell, / bin / sh, et vous donnez au shell une commande à exécuter. Cette commande est " ls - l / bin/??". Vous pouvez exécuter manuellement à partir d'un ligne de commande/shell:
$ ls -l /bin/??
Maintenant, comment voulez-vous exécuter un shell et dites lui d'exécuter une commande ? Vous ouvrez la page documentation / man pour votre shell et lisez-la.
Ce que vous voulez exécuter est:
$ /bin/sh -c "ls -l /bin/??"
Cela devient
execlp("/bin/sh","/bin/sh", "-c", "ls -l /bin/??", (char *)NULL);
Note de côté:
Le /bin/??
fait la correspondance de modèle, cette correspondance de modèle est faite par le shell, et elle s'étend à tous les fichiers sous /bin/ avec 2 caractères. Si vous avez simplement fait
execlp("ls","ls", "-l", "/bin/??", (char *)NULL);
Probablement rien ne se passerait (à moins qu'il n'y ait un fichier réellement nommé /bin/??
) car il n'y a pas de shell qui interprète et développe /bin/??
La limitation d'execl est que lors de l'exécution d'une commande shell ou de tout autre script qui ne se trouve pas dans le répertoire de travail actuel, nous devons passer le chemin complet de la commande ou du script. Exemple:
execl("/bin/ls", "ls", "-la", NULL);
La solution de contournement pour passer le chemin complet de l'exécutable est d'utiliser la fonction execlp, que recherche le fichier (1er argument de execlp) dans ces répertoires pointé par le CHEMIN:
execlp("ls", "ls", "-la", NULL);