【发布时间】:2018-04-19 20:42:44
【问题描述】:
我正在研究另一个 StackOverflow question 的内容,我认为现在是复习我的 unix 系统调用知识的好时机。
在尝试execvp(没有故意分叉)时,我遇到了一些让我困惑的事情
我写了 4 个测试程序
程序 1
#include <stdio.h>
int main() {
//printf("Doge\n");
execvp("ls");
printf("Foo\n");
return 0;
}
程序按预期运行,目录内容打印出来,Foo打印语句没有
程序 2
但是,当我取消注释第一个打印语句并让程序成为这个时
#include <stdio.h>
int main() {
printf("Doge\n");
execvp("ls");
printf("Foo\n");
return 0;
}
execvp 返回一个-1 并发出两个打印语句。为什么?
程序 3
我隐约记得在大学尝试使用 unix 系统调用时必须使用 unistd.h。
所以我包含了它,但不是execvp 有不同的签名,它需要更多的参数而不仅仅是程序的名称。所以我这样做了
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Doge\n");
char *const parmList[] = {"ls", NULL};
execvp("ls", parmList);
printf("Foo\n");
return 0;
}
这很有效。这让我很困惑。为什么 exec 在第一个程序中起作用? 我还使用了This 作为系统调用的引用。
终于写完了
程序 4
#include <stdio.h>
//#include <unistd.h>
int main() {
printf("Doge\n");
char *const parmList[] = {"ls", NULL};
execvp("ls", parmList);
printf("Foo\n");
return 0;
}
这也可以按预期工作。
有人可以解释发生了什么吗?
【问题讨论】:
-
execvp("ls");是未定义的行为:第二个参数是参数列表。你在扔垃圾。 -
但是当我包含
unistd.h时,为什么它只以编译器错误的形式抱怨呢?此外,如果execp仅使用 2 个参数定义,为什么它甚至让我execvp("ls")? -
没有警告选项,
execvp被静默隐式声明,不检查参数列表。 -
请原谅我的无知,但是默默地隐式声明,不检查参数列表是什么意思?如果
execp是在unistd中定义的,我怎么能在不包含它的情况下运行它? -
因为编译器是允许的,所以必须始终设置最高级别的警告。
标签: c exec system-calls