execv和fork:告知parent子进程无法执行该文件

时间:2016-04-13 04:58:02

标签: c fork waitpid execv

主进程如何知道子进程未能执行该文件(例如没有这样的文件或目录)?例如,在下面的代码中,我们如何让run()返回0以外的东西?谢谢!

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

enum ErrorType { noError, immediateFailure, returnFailure, forkFailure };

using namespace std;

int run(void)
{
    int error = noError;
    //char proc[] = "/bin/uname";
    char proc[] = "/usr/bin/Idontexist";
    char *const params[] = {proc, NULL};

    pid_t pid = fork();

    printf("pid = %d\n",pid);

    if (pid == 0)
    {
        if ( execv(proc,params)==-1 )
        {
            error = immediateFailure;
        }
        printf("child: error = %d\n",error);
    }
    else if (pid > 0)
    {
        /*  This is the parent process
         *  incase you want to do something
         *  like wait for the child process to finish
         */
        int waitError;
        waitpid(pid, &waitError, 0);

        if ( waitError )
            error = returnFailure;

        printf("parent: error = %d, waitError = %d\n",error,waitError);
    }
    else
    {
        error = forkFailure;
    }

    return error;
}

int main(void)
{
    printf("run() = %d\n",run());

    return 0;
}

输出:

pid = 4286
pid = 0
child: error = 1
run() = 1
parent: error = 0, waitError = 0
run() = 0

4 个答案:

答案 0 :(得分:1)

在我的情况下,declare @val timestamp = 0x0000AAE200B29565 select cast(cast(@val as datetime) as varchar(max)) 不会导致返回子进程的状态exit(EXIT_FAILURE),始终是waitpid() EXIT_FAILURE。我的解决方案是在0 / abort()执行失败的情况下execv()子进程。

答案 1 :(得分:0)

问题是在execv失败后处理错误。孩子将error设置为immediateFailure并将其返回main。然后main打印错误编号,并返回0。但是0意味着成功,所以父进程认为孩子成功了。

解决方案是从main返回错误编号,或在子代码中调用exit,例如

if (pid == 0)
{
    execv(proc,params);
    error = immediateFailure;
    printf("child: error = %d\n",error);
    exit( error );
}

请注意,您无需检查execv的返回值,因为execv如果成功则不会返回。它只会在失败时返回,并且总是返回-1。

答案 2 :(得分:0)

您需要使用值 main exit()返回错误代码。现在,您在所有情况下return 0 main waitpid,这将是父母从exit(error)收到的孩子的退出代码。

最好的解决方法是在子进程中添加printf("child: error = %d\n",error); exit(error);

grep

在任何情况下都使用整数常量而不是随机枚举常量枚举。 1和2是许多unix命令的常见返回值,1表示命令不成功(例如bash未找到任何匹配项),2 +表示命令确实失败(错误的参数)或者这样)`。

zsh127和其他shell使用#define COMMAND_NOT_RUNNABLE 127 /* ... */ execv(proc, params); // exec never returns if successful. perror(proc); exit(COMMAND_NOT_RUNNABLE); 作为退出代码,表示命令未找到/不可运行;因此建议这样做:

NSMutableArray *dataArray = [NSMutableArray array];
for (int i = 0; i<5; i++){
    [dataArray addObject:[UITextView new]];
    dataArray[i].text = "here";
                 ^Property 'text' not found on object of type 'id'
}

答案 3 :(得分:0)

除了提议的exit(error);之外,您还应为waitpid提供具体选项。在我将调用更改为waitpid(pid, &waitError, WUNTRACED | WCONTINUED);

之前,您的代码对我不起作用