2016-04-13 6 views
3

子プロセスがファイルの実行に失敗したことをマスタープロセスがどのように知ることができますか?たとえば、次のコードでは、run()を使って0以外の値を返す方法を教えてください。ありがとう!execvとfork:子プロセスがファイルの実行に失敗したことを親に通知します

#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; 
} 

出力:execvが失敗した後

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

答えて

0

エラーコードをまたはexit()の値で返す必要があります。今度はreturn0からmainになります。これは、親がwaitpidから受け取る子の終了コードになります。

最高の修正は、子プロセスでexit(error)を追加することです:代わりにランダムenum定数の列挙型のいずれの場合でも使用整数の定数で

printf("child: error = %d\n",error); 
exit(error); 

。 1と2は多くのunixコマンドからの共通の戻り値です.1はコマンドが成功しなかったことを意味します(例えば grepは一致しませんでした)。2+はコマンドが実際に失敗したことを意味します。

bashzshおよび他のシェルは、コマンドを通知する終了コードとして127を使用 /実行可能ではないが見つかりません。したがってこれは推奨されます:提案exit(error);に加えて

#define COMMAND_NOT_RUNNABLE 127 

/* ... */ 

execv(proc, params); // exec never returns if successful. 
perror(proc); 
exit(COMMAND_NOT_RUNNABLE); 
0

問題は、エラーの扱いです。子はerrorimmediateFailureに設定し、それを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を返します。

0

あなたはwaitpidのために特定のオプションを与える必要があります。呼び出しを変更するまでコードが私のために機能しませんでしたwaitpid(pid, &waitError, WUNTRACED | WCONTINUED);

関連する問題