В других ответах цитируется стандарт 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
устанавливает argv[0]
echoargv
равным 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);
Если вы этого не сделаете, злоумышленник может вызвать отказ вашей программы по своему желанию или может заставить вашу программу сообщать пользователю о совершенно неправильных вещах.
person
Community
schedule
29.12.2011