无法以正确的方式执行其他程序

Can't exec other programs in a proper way

本文关键字:方式 执行 其他 程序      更新时间:2023-10-16

我正在尝试从自己的内部执行另一个程序,但我不了解一些事情。所以我写了此代码:

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
total 88
-rwxr-xr-x 1 bezik bezik 77560 Nov 29 19:53 colors
-rwxr-xr-x 1 bezik bezik    63 Nov 26 21:45 compile
drwxr-xr-x 2 bezik bezik  4096 Nov 26 20:46 headers
drwxr-xr-x 2 bezik bezik  4096 Nov 23 00:48 sources
###Run decorator:
##Run
#Result: -1

有人可以向我解释,为什么从run_decorator()函数调用execvp失败?

读取仔细 execvp(3)的文档。它说execl等...

第一个论点,按照惯例,应指向 与正在执行的文件关联的文件名。列表 参数必须由空指针终止,并且由于这些是 variadic功能,此指针必须施放(char *) NULL

以及关于execvp

指针的数组必须由空指针终止。

因此您应该代码:

char* args[] = {  "sudo", "ls", "-l",  NULL };
execvp("sudo", args);

btw, execvp根本不返回,失败。通话后无需保留结果。

但是您需要,当execvp返回时(这仅在失败时发生)显示一些错误消息。我建议:

perror("execvp");
exit(EXIT_FAILURE);

,您可以找到有效的参数要调用,在这种确切的情况下,_EXIT(2)而不是退出(3)。我仍然更喜欢exit(因为它会冲洗STDIO缓冲区并运行Atexit(3)注册的处理程序)。

有人可以向我解释,为什么execvp失败

是的,errno(3)。Perror(3)。

使用

不要忘记阅读 每个使用的功能的文档。对于系统调用(在SYSCALLS(2)中列出)和标准C库功能(请参见Intro(3)),您通常应处理故障情况(通常使用errno,至少通过perror,然后通过exit

我不明白为什么您需要sudo使用ls。在很少有情况下,由于您的工作目录是可列出的(然后sudo是没有用的),因此您甚至可以使用stat(2)(2)(2)(3)因此无需fork,然后execvp /bin/ls程序)。

还阅读有关执行(2)和凭据(7)(以及setReuid(2))的setuid技术的信息。请参阅此(您可以使用自己的setuid程序避免使用sudo)。

顺便说一句,您应该使用所有警告和调试信息(带有GCC的g++ -Wall -Wextra -g)进行编译,并使用调试器gdb(也许是Strace(1)和Valgrind(1))。