Другие ответы цитировали стандарт C и показали, что argv[0]
и может быть NULL
, или это может быть пустая строка (""
). Вы должны написать свою программу с предположением, что это может произойти, потому что в противном случае вы создаете (небольшую) угрозу безопасности. Вы можете легко вызвать вашу программу и установить argv
на то, что хочет атакующий. В качестве доказательства рассмотрим следующие две программы. Первый, echoargv.c
распечатывает содержимое argv
:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int i;
for (i = 0; i < argc; ++i)
printf("argv[%d] = \"%s\"\n", i, argv[i]);
exit(0);
}
Второй, argv0
, вызывает любую другую программу и позволяет пользователю указать argv другой программы:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv) {
(void) execv(argv[1], argv+2);
perror("execv");
exit(1);
}
(Это версия для Posix. Нестандартные среды могут нуждаться в изменениях.)
Вот как их использовать:
$ gcc -o echoargv echoargv.c
$ gcc -o argv0 argv0.c
$ ./argv0 ./echoargv
$ ./argv0 ./echoargv ''
argv[0] = ""
$ ./argv0 ./echoargv 'this is fun' 'it is fun indeed'
argv[0] = "this is fun"
argv[1] = "it is fun indeed"
$
Первый запуск argv0
устанавливает echoargv
s argv[0]
в NULL.
Второй запуск делает это пустой строкой.
Третий прогон здесь просто для удовольствия: обратите внимание, что argv[0]
не нужно иметь
все, что связано с реальным названием программы.
Как это может вас укусить? Если, например, вы слепо распечатываете название вашей программы в сообщении об использовании:
printf("usage: %s [options] [FILE]...\n", argv[0]);
Лучше:
const char *program_name = "some default name"; /* (global) variable */
if (argv[0] && argv[0][0])
program_name = argv[0];
printf("usage: %s [options] [FILE]...\n", program_name);
Если вы этого не сделаете, злоумышленник может заставить вашу программу по умолчанию вызывать segfault или заставить вашу программу сообщать пользователю о совершенно неправильных вещах.