J'ai passé les deux derniers jours à essayer de comprendre l'appel système execlp()
, mais je suis là maintenant. Laissez-moi aller droit au problème.
Le man page
De execlp déclare l'appel système en tant que int execlp(const char *file, const char *arg, ...);
avec la description suivante: l'argument de caractère constant et les ellipses suivants dans execl (), execlp () et execle () les fonctions peuvent être considérées comme arg0, arg1, ..., argn.
Pourtant, je vois que l'appel système est appelé de la sorte dans notre manuel: execlp(“/bin/sh”, ..., “ls -l /bin/??”, ...);
(les "..." doivent nous être déterminés en tant qu'étudiants). Cependant, cet appel système ne ressemble en rien à la déclaration sur man page
De l’appel système.
Je suis super confus. Toute aide est appréciée.
ce prototype:
int execlp(const char *file, const char *arg, ...);
Dit que execlp est une fonction à argument variable. Il faut 2 const char *
. Le reste des arguments, le cas échéant, sont les arguments supplémentaires à transférer au programme que nous voulons exécuter - également char *
- tous ces éléments sont des chaînes C (et le dernier argument doit être un pointeur NULL)
Ainsi, l'argument file
est le nom du chemin d'un fichier exécutable à exécuter. arg
est la chaîne que nous souhaitons voir sous la forme argv[0]
dans l'exécutable. Par convention, argv[0]
Est simplement le nom de fichier de l'exécutable, normalement identique à file
.
Les ...
Sont maintenant les arguments supplémentaires à donner à l'exécutable.
Supposons que vous exécutiez ceci depuis 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 dans le shell,/bin/sh, et vous donnez une commande au shell à exécuter. Cette commande est "ls -l/bin/??". Vous pouvez l'exécuter manuellement à partir d'une ligne de commande/Shell:
$ ls -l /bin/??
Maintenant, comment lancez-vous un shell et lui dites d’exécuter une commande? Vous ouvrez la documentation/la page de manuel de votre shell et vous la lisez.
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 secondaire: /bin/??
Est en train de faire une correspondance de motif, cette correspondance de motif est effectuée par le shell et 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 y ait un fichier nommé /bin/??
) Car il n'y a pas de Shell qui interprète et développe/bin/??
La limite de execl est que lorsque vous exécutez une commande Shell ou tout autre script qui ne se trouve pas dans le répertoire de travail actuel, vous devez alors indiquer 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 consiste à utiliser la fonction execlp, qui recherche le fichier (1er argument de execlp) dans les répertoires pointés par PATH:
execlp("ls", "ls", "-la", NULL);