execvp/fork-如何捕获不成功的执行? [英] execvp/fork -- how to catch unsuccessful executions?

查看:253
本文介绍了execvp/fork-如何捕获不成功的执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,我正在编写一个必须执行子进程的C程序.我不会同时执行多个子进程或执行任何操作,因此这非常简单.我肯定可以成功执行内置的shell程序(即cat和echo之类的东西),但是我还需要能够分辨出其中一个程序何时无法成功执行.我正在尝试使用以下简化代码:

Right now I'm writing a C program that must execute a child process. I'm not doing multiple child processes simultaneously or anything, so this is fairly straightforward. I am definitely executing the built-in shell programs (i.e. things like cat and echo) successfully, but I also need to be able to tell when one of these programs fails to execute successfully. I'm trying this with the following simplified code:

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程序,但它不执行可执行文件的当前目录中的程序(即此代码在其中运行的程序);为了让它在当前目录中运行程序,我还有其他事情要做吗?

So for example, if I try to execute rm fileThatDoesntExist.txt, I would like to consider that a failure since the file didn't exist. How can I accomplish this? Also, while that execvp() call successfully executes built-in shell programs, it doesn't execute programs in the current directory of the executable (i.e. the program that this code is running inside of); Is there something else that I have to do in order to get it to run programs in the current directory?

谢谢!

推荐答案

这是一个经典的问题,提供了非常优雅的解决方案.在分叉之前,在父级中创建一个pipe.在fork之后,父级应关闭管道的写入端,并阻止尝试从读取端到read的操作.小孩应该关闭阅读端,并使用fcntl设置执行结束时的close-on-exec标志.

This is a classic problem with a very elegant solution. Before forking, create a pipe in the parent. After fork, the parent should close the writing end of the pipe, and block attempting to read from the reading end. The child should close the reading end and set the close-on-exec flag, using fcntl, for the writing end.

现在,如果子级成功调用execvp,则管道的写入端将关闭,并且没有数据,父级中的read将返回0.如果子级中的execvp失败,则写入错误代码到管道,并且父级中的read在读取了父级要处理的错误代码后,将返回非零值.

Now, if the child calls execvp successfully, the writing end of the pipe will be closed with no data, and read in the parent will return 0. If execvp fails in the child, write the error code to the pipe, and read in the parent will return nonzero, having read the error code for the parent to handle.

这篇关于execvp/fork-如何捕获不成功的执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆