2016-04-13 37 views
3

Ana işlem, alt işlemin dosyayı yürütemediğini nasıl bilir (örneğin, böyle bir dosya veya dizin yok)? Örneğin, aşağıdaki kodda, 0'dan başka bir şey döndürmek için run() işlevini nasıl alabiliriz? Teşekkürler!execv ve fork: ebeveynin çocuğun dosyayı yürütemediğini bildirme

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

çıkışı:

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

cevap

0

Sen değerle main veya exit() gelen hata kodunu dönmek gerekir. Artık, main'dan numaralı telefondan 0 numaralı telefonu return yapıyorsunuz ve bu, ebeveynin waitpid'dan aldığı çocuğun çıkış kodu olacaktır.

iyi düzeltme alt süreçte exit(error) eklemektir: yerine rastgele enum sabitleri enum her durumda kullanılması tamsayı sabitleri olarak

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

. 1 ve 2, komutun başarılı olmadığı anlamına gelen birçok unix komutundan gelen ortak geri dönüş değerleridir (örneğin grep, herhangi bir eşleşme bulamadı) ve 2+ anlamı, komutun gerçekten başarısız olduğu anlamına gelir (yanlış argümanlar veya benzeri).

bash, zsh ve kabuklar komutu sinyal çıkış kodu 127 kullanmak/çalıştırılabilir olmayan bulunamadı; böylece bu tavsiye ederim: Önerilen exit(error); ek olarak

#define COMMAND_NOT_RUNNABLE 127 

/* ... */ 

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

sorun execv sonra hata ele alma başarısız olması. Çocuk error'u immediateFailure'a ayarlar ve bunu main'a döndürür. Sonra main hata numarasını yazdırır ve 0 döndürür. Ancak 0 başarı anlamına gelir, bu nedenle ebeveyn süreci çocuğun başarılı olduğunu düşünür. Çözüm, hata numarasını main numaralı telefondan döndürmek veya exit numaralı telefon numaralarını çocuk koduna, örn. Eğer başarılı olursa dönmeyecek execv beri execv dönüş değerini kontrol etmek gerekmez

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

Not. Sadece başarısız olursa geri döner ve her zaman -1 değerini döndürür.

0

Eğer waitpid için özel seçenekleri vermelidir. waitpid(pid, &waitError, WUNTRACED | WCONTINUED);

numaralı telefonu değiştirene kadar kodunuz benim için çalışmadı.