其他回复引用了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 的 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);
如果您不这样做,攻击者可能会导致您的程序随意出现段错误,或者可能让您的程序向用户报告完全错误的内容。