我在课堂上得到了这段代码:
int main(int argc, char **argv)
{
if(argc)
{
return 1;
}
puts(argv[3]);
return 0;
}
现在,我应该编写第二个程序,执行该程序并将其打印为“ Hello World!”。因此,我必须找到一种在argc保持为0的同时传递参数的方法(我假设使用execv)。
这是我到目前为止所拥有的:
int main()
{
pid_t pid = fork();
if(pid == 0)
{
char *argv[] = { "filepath", "placeholder",
"placeholder, "Hello World!" };
execv("filepath", argv);
exit(0);
}
else
{
waitpid(pid, 0, 0);
}
return 0;
}
这将在Linux上运行。
我尝试了mbj的原始建议,以在arguments数组中传递0,可惜这没有用。但是,如果我将0作为第一个参数,则argc变为0,但是当尝试打印参数时,我得到了输出“ LC_MEASUREMENT = de_DE.UTF-8”。谷歌搜索并没有真正帮助我。
我在这里全神贯注,因此不胜感激。
答案 0 :(得分:2)
好吧,经过我自己的尝试,我现在想通了。
由于将以NULL
(0
)开头的数组传递给execv
会导致程序打印出LC_MEASUREMENT=de_DE.UTF-8
,因此我意识到它必须表示{{1 }}是指进程 environment 中的一个元素(LC_MEASUREMENT是用于在Linux中配置语言环境设置的环境变量之一)。
argv[3]
由于execv
将当前环境复制到新程序中,因此我们只需要修改环境并将字符串execv
放在正确的位置,然后调用"Hello World!"
。事实证明,要打印的字符串是环境索引2指向的字符串。
要访问当前环境,我们需要在execv
外部声明environ
变量:
main
然后在调用external char **environ;
int main()
{
...
之前执行此操作:
execv
char *argv[] = { NULL };
environ[2] = "Hello world!";
execv("filepath", argv);
的简单解决方案我们可以使用execve
函数,而不是在调用external char **environ
之前声明execv
并修改当前环境,该函数可以让我们传入一个新的字符串数组以用作环境该程序:
execve
如上面的代码片段所示,无论我们使用哪种方法, char *argv[] = { NULL };
char *envp[] = { "foo", "bar", "Hello World!", NULL };
execve("filepath", argv, envp);
都必须位于环境的索引"Hello World!"
处。
之所以起作用,是因为有一个标准,用于在执行程序时如何在进程内存中布置命令行参数和环境:char指针的环境数组位于命令行参数数组之后。
由于这些数组以NULL条目终止,因此看起来像这样:
2
我希望ASCII技术可以帮助您理解为什么在执行这样的程序时+---------+---------------------------------------+
| Args | Environment |
+---------+---------+---------+---------+---------+
| NULL | envp[0] | envp[1] | envp[2] | NULL |
+---------+---------+---------+---------+---------+
^ ^ ^
| | |
argv[0] argv[1] ... argv[3]
与argv[3]
的含义相同。