¿Cuándo puede argv tener nulo?

Lo que entiendo acerca de pasar argumentos a main () desde la línea de comandos es que argc tiene un valor mínimo de 1 y argv [0] siempre tendrá el nombre del progtwig con su ruta de acceso.

Si se proporcionan argumentos en la línea de comando, entonces argc tendrá un valor mayor que uno y argv 1 a argv [argc-1] tendrá esos argumentos.

Ahora un párrafo en este enlace dice que

argv [0] será una cadena que contenga el nombre del progtwig o una cadena nula si no está disponible.

Ahora, ¿cómo y cuándo puede argv [0] tener una cadena nula? Me refiero a que el nombre del progtwig con su ruta siempre estará disponible, entonces ¿cuándo puede ser nulo?

El escritor dice que “si eso no está disponible”, pero ¿cuándo y cómo es posible que el nombre del progtwig no esté disponible?

Con la clase de llamadas exec , especifique el nombre del progtwig y el ejecutable del progtwig por separado para que luego pueda establecerlo en NULL.

Pero esa cita es en realidad del estándar ISO (posiblemente parafraseado) y ese estándar cubre una gama terriblemente grande de entornos de ejecución, desde el microcontrolador más pequeño hasta el mainframe z10 Enterprise.

Muchos de esos sistemas integrados estarían en una situación en la que un nombre ejecutable tiene poco sentido.

Del último borrador de c1x:

El valor de argc debe ser no negativo.

El valor argv[argc] será un puntero nulo.

Si el valor de argc es mayor que cero, los miembros de la matriz argv[0] a argv[argc-1] inclusive contendrán punteros a las cadenas, que reciben los valores definidos por la implementación por el entorno del host antes del inicio del progtwig.

Esto significa que, si argc es cero (y puede ser), argv [0] es NULL.

Pero, incluso cuando argc no es 0, es posible que no obtenga el nombre del progtwig, ya que el estándar también establece:

Si el valor de argc es mayor que cero, la cadena apuntada por argv[0] representa el nombre del progtwig; argv[0][0] será el carácter nulo si el nombre del progtwig no está disponible desde el entorno host. Si el valor de argc es mayor que uno, las cadenas apuntadas por argv[1] a argv[argc-1] representan los parámetros del progtwig.

Por lo tanto, no existe ningún requisito bajo el estándar de que se proporcione un nombre de progtwig. He visto progtwigs utilizar una amplia selección de opciones para este valor:

  • ningún valor en absoluto (por supuesta seguridad).
  • una mentira flagrante (como sleep por una pieza maliciosa de código).
  • el nombre real del progtwig (como sleep ).
  • una ligeramente modificada (como -ksh para el shell de inicio de sesión).
  • un nombre descriptivo (p. ej., progname - a program for something ).

De acuerdo con esta lista de correo , argv[0] puede ser nulo si argc == 0 . Pero no explican cuando argc podría ser alguna vez cero. Sospecho que argc sería cero en situaciones donde un ejecutable no se lanzó “normalmente” (es decir, a través de una línea de comando, popen , etc.) – y de hecho, como se mencionó en @paxdiablo, puede establecer manualmente argv con la familia exec de funciones , por lo que argc podría ser cero dependiendo de esos argumentos.

Pero, en su sección Rationale :

Las primeras propuestas requerían que el valor de argc pasado a main() fuera “uno o más”. Esto fue impulsado por el mismo requisito en los borradores del estándar ISO C. De hecho, las implementaciones históricas han pasado un valor de cero cuando no se proporcionan argumentos a la persona que llama de las funciones de ejecución. Este requisito se eliminó del estándar ISO C y posteriormente también se eliminó de este volumen de IEEE Std 1003.1-2001. La redacción, en particular el uso de la palabra debería, requiere que una Aplicación POSIX de Conformidad Estricta transfiera al menos un argumento a la función exec, garantizando así que argc sea ​​uno o más cuando sea invocado por dicha aplicación. De hecho, esta es una buena práctica, ya que muchas aplicaciones existentes hacen referencia a argv[0] sin verificar primero el valor de argc .

Así que ahí lo tienen: las aplicaciones POSIX estrictamente conformes deben tener argc ser mayor que cero, pero eso de ninguna manera está garantizado.

Hay un poco más de información sobre el estándar con respecto a argc y argv en la sección Inicio del progtwig .

Es posible imaginar plataformas donde los progtwigs no tienen nombres, quizás el código simplemente se carga al inicio. En esos, argv [0] podría ser NULL. El estándar C ciertamente permite un valor argc de cero, y dice que argv [argc] debe ser NULL.

Ejemplo POSIX ejecutable

ac

 #define _XOPEN_SOURCE 700 #include  int main(void) { char *argv[] = {NULL}; char *envp[] = {NULL}; execve("b.out", argv, envp); } 

bc

 #include  int main(int argc, char **argv) { if (argc == 0 && argv[0] == NULL) puts("yup"); } 

Entonces:

 gcc ac -o a.out gcc bc -o b.out ./a.out 

Da:

 yup 

Probado en Ubuntu 16.10.

Pruebe el progtwig existente con la lista de argumentos vacía

Aquí hay un contenedor que toma un camino como argumento, y lo ejecuta como un comando sin argumentos:

 #include  #include  int main(int argc, char**argv) { char *empty[] = {NULL}; execve(argv[1], empty, empty); perror("empty-args: execve failed"); // Bad Address (EFAULT) if our argv[1] == NULL return 1; } 

uso:

 ./empty-args ./arg-count 
    Intereting Posts