Entonces aquí tenemos que pasar el nombre del archivo dos veces en la función.
No son exactamente lo mismo que observa al observar que uno de ellos se usa como argv[0]valor. Esto no tiene que ser el mismo que el nombre base del ejecutable; muchas / la mayoría de las cosas lo ignoran y puedes poner lo que quieras allí.
El primero es la ruta real al ejecutable, para lo cual existe una necesidad obvia. El segundo se pasa al proceso aparentemente como el nombre utilizado para invocarlo, pero, por ejemplo:
execl("/bin/ls", "banana", "-l", NULL);
Funcionará bien, suponiendo que /bin/lses el camino correcto.
Algunas aplicaciones, sin embargo, hacen uso de argv[0]. Por lo general, estos tienen uno o más enlaces simbólicos en $PATH; Esto es común con las utilidades de compresión (a veces usan envoltorios de shell). Si lo ha xzinstalado, stat $(which xzcat)muestra que es un enlace xzy man xzcates el mismo man xzque explica "xzcat es equivalente a xz --decompress --stdout". La forma en que xz puede determinar cómo se invocó es comprobando argv[0], haciendo estos equivalentes:
execl("/bin/xz", "xzcat", "somefile.xz", NULL);
execl("/bin/xz", "xz", "--decompress", "--stdout", "somefile.xz", NULL);
busyboxpuede ser lo que quieres que sea, dependiendo de cómo lo llames, ¿verdad?/bin/lsfuera busybox, ¡no sabría cómo ejecutarbanana!No tiene que pasar el nombre del archivo dos veces.
El primero es el archivo que realmente está ejecutado.
El segundo argumento es lo que debería ser el
argv[0]proceso, es decir, lo que el proceso debería ver como su nombre. Por ejemplo, si se ejecutalsdesde el shell, el primer argumento es/bin/ls, el segundo es justols.Puede ejecutar un determinado archivo y llamarlo de otra manera a través del segundo argumento; el programa puede verificar su nombre y comportarse de manera diferente según el nombre. Esto también se puede hacer a través de enlaces duros (o enlaces simbólicos) pero de esta manera se da más flexibilidad.
fuente
argv[0]en el nombre del enlace.La conclusión es que
argv[0]se puede establecer en cualquier cosa (incluidoNULL). Por convención ,argv[0]se establecerá en la ruta en la que se inició el ejecutable (por el proceso de shell cuando lo haceexecve()).Si
./fooydir/barson dos enlaces diferentes (duros o simbólicos) al mismo ejecutable, entonces el inicio del programa desde el shell utilizando las dos rutas se estableceráargv[0]en./fooydir/bar, respectivamente.El hecho de que
argv[0]puede ser aNULLmenudo se pasa por alto. El siguiente código podría bloquearse para unNULLargv[0]por ejemplo (aunque glibc imprime algo como <null> en su lugarargv[0]):Una alternativa en Linux es usar
/proc/self/exepara tales casos.fuente
./fooy una vez comodir/bar.argv[0]será diferente para esos dos casos (en cada caso será la misma que la ruta que utilizó).argv[0]cualquier cosa cuando ustedexec*()mismo programa. Es una convención del shell establecerargv[0]la ruta que se usó para iniciar el programa (y es aconsejable hacer lo mismo cuandoexec*()un programa, ya que muchos programas inspeccionanargv[0]y esperan que mantenga la ruta).