首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >execvp/fork --如何捕获不成功的执行?

execvp/fork --如何捕获不成功的执行?
EN

Stack Overflow用户
提问于 2012-12-05 02:58:37
回答 3查看 7.3K关注 0票数 6

现在我正在编写一个C程序,它必须执行子进程。我没有同时处理多个子进程或其他任何事情,所以这很简单。我确实成功地执行了内置的shell程序(例如cat和echo),但我还需要能够判断这些程序中的一个程序何时无法成功执行。我用下面的简化代码来尝试:

代码语言:javascript
复制
int returnStatus; // The return status of the child process.
pid_t pid = fork();

if (pid == -1) // error with forking.
{
   // Not really important for this question.
}
else if (pid == 0) // We're in the child process.
{
   execvp(programName, programNameAndCommandsArray); // vars declared above fork().

   // If this code executes the execution has failed.
   exit(127); // This exit code was taken from a exec tutorial -- why 127?
}
else // We're in the parent process.
{
   wait(&returnStatus); // Wait for the child process to exit.

   if (returnStatus == -1) // The child process execution failed.
   {
      // Log an error of execution.
   }
}

因此,例如,如果我尝试执行rm fileThatDoesntExist.txt,我会认为这是一个失败,因为文件不存在。我如何才能做到这一点呢?此外,虽然execvp()调用成功地执行了内置的shell程序,但它并不执行可执行文件的当前目录中的程序(即在其中运行此代码的程序);为了让它运行当前目录中的程序,我还需要做些什么吗?

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-05 03:08:09

这是一个经典的问题,有一个非常优雅的解决方案。在派生之前,在父级中创建一个pipe。在fork之后,父级应该关闭管道的写入端,并阻止从读取端尝试read。孩子应该关闭读取端,并使用fcntl为写入端设置close-on-exec标志。

现在,如果子进程成功调用execvp,则管道的写入端将关闭,没有数据,父进程中的read将返回0。如果子进程中的execvp失败,则将错误代码写入管道,父进程中的read将返回非零值,并已读取错误代码以供父进程处理。

票数 18
EN

Stack Overflow用户

发布于 2012-12-05 03:07:29

wait(2)为您提供的不仅仅是子进程的退出状态。为了获得实际的退出状态,您需要使用WIFEXITED()宏测试子进程是否正常退出(而不是通过信号等异常退出),然后使用WEXITSTATUS()宏来获取实际的退出状态:

代码语言:javascript
复制
wait(&status);
if(WIFEXITED(status))
{
    if(WEXITSTATUS(status) == 0)
    {
        // Program succeeded
    }
    else
    {
        // Program failed but exited normally
    }
}
else
{
    // Program exited abnormally
}

为了让execvp(3)在当前目录中运行程序,您需要将当前目录添加到$PATH环境中(通常不是一个好主意),或者向其传递完整路径,例如使用./myprogram而不仅仅是myprogram

票数 3
EN

Stack Overflow用户

发布于 2012-12-05 03:05:30

在故障检测方面,如果exec()函数用新的进程替换了当前进程,那么当前进程就消失了;被执行的程序判断它被要求做的事情是成功还是失败都没有关系。但是,fork之前的父进程可以发现该子进程的退出代码,该代码可能包含命令成功/失败信息。

在查找可执行文件方面,execvp()复制了shell的操作,搜索当前路径。如果它在工作目录中找不到可执行文件,则该目录很可能不在搜索路径中(或者文件实际上不是可执行文件)。您可以尝试通过完整路径名指定它们。

如果您只是想运行一个命令并等待结果,那么您可能希望使用system()函数来为您处理这个问题,而不是使用fork/exec自己构建它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13710003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档