2012-11-11 31 views
0

我想從父級訪問分叉子進程的退出狀態,但我得到奇怪的答案。有時,我得到256或有時得到一個負數,這取決於我是指定&狀態還是隻是狀態。我知道我非常接近。有人可以給我提供一點幫助,我將如何得到EXIT_STATUSwaitpid錯誤的用法?

這裏是我的代碼

pid_t pid; 
int *status; 
if((pid = fork()) < 0) 
    fprintf(stdout, "Error forking child process\n"); 

else if (pid == 0) 
{ 
    execvp(input[0], input); 
    fprintf(stdout, "Invalid process!!\n"); 
    _exit(EXIT_FAILURE); 

} 
else 
{ 
    while (waitpid(-1, status, 0) != pid); 
    fprintf(stdout, "The status is %d\n", &status); 
} 

回答

4

您會看到這一行爲,因爲你不初始化您使用的指針,因此,你正在調用未定義行爲,這意味着,毫不誇張地說,在所有事情可能發生。嘗試改變status是一個int(而不是int*):

int status; 
/* ... */ 
while (waitpid(-1, &status, 0) != pid); 
fprintf(stdout, "The status is %d\n", status); 

您的代碼,而另一方面:

int * status; 

這將創建一個指向int的指針,不初始化。

while (waitpid(-1, status, 0) != pid); 

在這裏,您通過這個指針waitpid函數(),這將在 指向位置寫。既然你沒有初始化 的指針,它的寫入一個不確定內存 位置!這可能會崩潰的過程中或覆蓋 其他地方分配的內存,這可能會導致一個 自發崩潰後,或數據損壞!

fprintf(stdout, "The status is %d\n", &status); 

這樣就會打印出指針變量的地址 - 而不是 它所指向的價值!使用*status代替 &status可以讓這部分工作,但你仍然使用未初始化的指針是 。

我強烈建議你把你的編譯器的警告設置到最大(通過-Wall與海灣合作委員會),使其發出警告的一切。它會捕獲未初始化的指針的使用,並且它也可能會警告您使用指針類型值的%d格式說明符。

+0

我做了你所要求的改變。然而,我的狀態值爲256。由於執行execvp失敗,我期待-1。所以我試着將_exit改成_exit(-1)。但現在總是返回65280。 – haunteddevil619

+0

你不能直接解釋'status';只有低8位指的是進程退出代碼。使用'WIFEXITED(status)'確定進程是否乾淨地退出,然後使用'WEXITSTATUS(status)'獲得實際的退出狀態。 (請注意,負退出代碼不被很好的支持;您只能保證8個無符號位用於退出代碼。)請參見[waitpid()手冊頁](http://linux.die.net/man/2/waitpid)有關如何解釋「狀態」的更多細節。 – cdhowie

+0

我沒有得到你說的話,「如果這個過程乾淨地退出」。由於execvp失敗,進程必須以錯誤或(-1)退出。使用WIFEXITED後,我的退出狀態爲255。我認爲我還是不太瞭解這個 – haunteddevil619

0

不要用大量的或負數的返回值,他們混淆的東西。 作爲示例,在32位系統上:

對於int:255是0x000000ff -1是0xffffffff。因此,如果你返回-1中的任何八位塊,它們全部是0xff或者255.

如果你調用exit(1)或exit(2)或者exit(3)或者其他一些小的正數將爲你更好地發揮。在父母一定要先致電WIFEXITED(&status)

因爲你似乎想用的退出狀態「告訴」你一些有關的問題發生嘗試sysexits:http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits

或者乾脆用EXIT SUCCESSEXIT_FAILURE例如:return EXIT_SUCCESS;exit(EXIT_FAILURE);這是保證工作 - 即。,給你一個成功或失敗的回報。