Nous devons donc ici passer deux fois le nom du fichier dans la fonction.
Ce n'est pas tout à fait la même chose que vous remarquez en observant que l' un d'eux est utilisé comme argv[0]
valeur. Cela ne doit pas nécessairement être le même que le nom de base de l'exécutable; beaucoup / la plupart des choses l'ignorent et vous pouvez y mettre tout ce que vous voulez.
Le premier est le chemin réel vers l'exécutable, pour lequel il existe une nécessité évidente. Le second est passé au processus ostensiblement comme le nom utilisé pour l'invoquer, mais, par exemple:
execl("/bin/ls", "banana", "-l", NULL);
Fonctionnera bien, en supposant que /bin/ls
c'est le bon chemin.
Cependant, certaines applications utilisent argv[0]
. Habituellement, ceux-ci contiennent un ou plusieurs liens symboliques $PATH
; ceci est courant avec les utilitaires de compression (ils utilisent parfois des wrappers shell à la place). Si vous avez xz
installé, stat $(which xzcat)
montre que c'est un lien vers xz
, et man xzcat
est le même que celui man xz
qui explique "xzcat est équivalent à xz --decompress --stdout". La façon dont xz peut dire comment il a été invoqué est en vérifiant argv[0]
, ce qui rend ces équivalents:
execl("/bin/xz", "xzcat", "somefile.xz", NULL);
execl("/bin/xz", "xz", "--decompress", "--stdout", "somefile.xz", NULL);
busybox
peut être ce que vous voulez qu'il soit selon la façon dont vous l'appelez bien?/bin/ls
était busybox, il ne saurait pas s'exécuterbanana
!Vous n'avez pas à transmettre le nom de fichier deux fois.
Le premier est le fichier qui est réellement exécuté.
Le deuxième argument est ce que devrait être le
argv[0]
processus, c'est-à-dire ce que le processus devrait voir comme son nom. Par exemple, si vous exécutez àls
partir du shell, le premier argument est/bin/ls
, le second est justels
.Vous pouvez exécuter un certain fichier et l'appeler autrement via le deuxième argument; le programme peut vérifier son nom et se comporter différemment selon le nom. Cela peut également être fait via des liens durs (ou des liens symboliques), mais cela donne plus de flexibilité.
la source
argv[0]
le nom du lien.Le point à
argv[0]
retenir est qu'il peut être réglé sur n'importe quoi (y comprisNULL
). Par convention ,argv[0]
sera défini sur le chemin à partir duquel l'exécutable a été démarré (par le processus shell quand il le faitexecve()
).Si
./foo
etdir/bar
sont deux liens différents (physiques ou symboliques) vers le même exécutable, le démarrage du programme à partir du shell en utilisant les deux chemins sera définiargv[0]
sur./foo
etdir/bar
, respectivement.Le fait que ce
argv[0]
soit possibleNULL
est souvent ignoré. Le code suivant peut se bloquer pour unNULL
argv[0]
par exemple (bien que la glibc imprime quelque chose comme <null> à la place pourargv[0]
):Une alternative sur Linux est d'utiliser
/proc/self/exe
pour de tels cas.la source
./foo
et une fois commedir/bar
.argv[0]
sera différent pour ces deux cas (dans chaque cas, ce sera le même que le chemin que vous avez utilisé).argv[0]
n'importe quoi lorsque vousexec*()
programmez vous-même. C'est une convention du shell de définirargv[0]
le chemin qui a été utilisé pour démarrer le programme (et il est sage de faire la même chose lorsque vousexec*()
programmez, car de nombreux programmes inspectentargv[0]
et s'attendent à ce qu'il contienne le chemin).