C++ Can';t以正确的方式执行其他程序
我试图从自己的内部执行另一个程序,但我不了解一些事情。所以我写了这段代码:C++ Can';t以正确的方式执行其他程序,c++,execvp,C++,Execvp,我试图从自己的内部执行另一个程序,但我不了解一些事情。所以我写了这段代码: void run() { cout << "##Run" << endl; pid_t process_id = fork(); if (process_id == 0) { char* args[] = { "sudo", "ls", "-l" }; auto i = execvp("sudo", args); cout << "#Result
void run() {
cout << "##Run" << endl;
pid_t process_id = fork();
if (process_id == 0) {
char* args[] = { "sudo", "ls", "-l" };
auto i = execvp("sudo", args);
cout << "#Result: " << i << endl;
return;
} else if (process_id < 0) {
throw std::runtime_error("fork() failed");
} else if (process_id > 0) {
wait(&process_id);
}
return;
}
void run_decorator() {
cout << "###Run decorator: " << endl;
run();
}
int main() {
run();
run_decorator();
return 0;
}
有人能给我解释一下为什么从run\u decorator()函数调用execvp失败吗?请仔细阅读的文档。它是关于execl
etc.:
按照惯例,第一个论点应该指向
与正在执行的文件关联的文件名。名单
参数必须由空指针终止,并且,因为它们是
变量函数,此指针必须强制转换为(char*)NULL
关于execvp
:
指针数组必须以空指针终止。
因此,您应该编写以下代码:
char* args[] = { "sudo", "ls", "-l", NULL };
execvp("sudo", args);
顺便说一句,execvp
除了失败之外,根本不返回。不需要在调用后保留其结果
但是,当execvp
返回时(这只发生在失败时),您需要显示一些错误消息。我建议:
perror("execvp");
exit(EXIT_FAILURE);
在这种情况下,您可以找到有效的参数来调用,而不是。我仍然更喜欢退出(因为它会刷新stdio缓冲区并运行已注册的处理程序)
有人能给我解释一下为什么执行失败吗
对。这是由
不要忘记仔细阅读每一个使用过的函数的文档。对于系统调用(在中列出)和标准C库函数(请参阅),通常应处理故障情况(通常使用errno
,至少通过perror
然后exit
)
我不明白你为什么需要sudo
和ls
。在很少的情况下,这可能是有用的,因为大多数时候你的程序是可列表的(那么sudo
是无用的),在这种情况下,你甚至可以使用,with(因此不需要fork
thenexecvp
the/bin/ls
程序)
还可以阅读和(和)中的技术。请参阅(您可以使用自己的setuid程序避免sudo
)
顺便说一句,您应该编译所有警告和调试信息(
g++-Wall-Wextra-g
with)和(可能还有和)。次要注意:您引用的文档部分错误。有关将NULL
强制转换为char*
的部分仅适用于execl*
系列(它们是varargs,因此不会对变量参数施加特定类型,如果NULL
只是0
,因此是int
-宽度,而不是指针宽度,或者如果指针类型出于任何原因不是恒定宽度,则会导致问题)。它不适用于execv*
系列(在涉及类型化数组的情况下,NULL
将被无缝地隐式强制为char*
)。按照习惯用法,您需要:char*args[]={“sudo”,“ls”,“-l”,NULL};
,无需强制转换。感谢您的回复,可能明天我会再次仔细研究文档(这次会更仔细).回答你的问题,我不需要将sudo与ls一起使用,这只是一个例子。可能是你不想要的情况sudo
:
perror("execvp");
exit(EXIT_FAILURE);