2017-08-14 87 views
0

我就遇到了這個問題,幾個小時前暢通。Linux下C,waitpid函數()由處理信號,返回值-1,並將errno 5

即使我有固定的,我只是不明白爲什麼會這樣。

signal(SIGHUP, sighupHandler); 
. 
. 
. 
// sync with child by getting a char written by child 
fgetc(pipe_in); 
close(pipe_in); 
int status; 
if(waitpid(initProcessPid, &status, 0) == -1){ 
    printf("debug: errno is %d\n", errno); 
    printf("failed to wait for init process to end\n"); 
} 

每次waitpid函數()塊中一個SIGHUP發生,waitpid函數()返回-1,並將errno 5.

雖然EINTR應該在錯誤號由ALK指出這種情況下,是EINTR 4,不是5

幾個小時收集來自gdb的想法,因爲我沒有真正在做什麼SIGHUP當前之後,我改變了我的代碼:

signal(SIGHUP, SIG_IGN); 

然後它工作正常,SI GHUP不再打破waitpid()模塊。

我是工作在Linux容器,其目的是單個文件和靜態的。 https://github.com/Kethen/minicontainer

+1

https://stackoverflow.com/q/41474299/2371524 –

+0

來自['waitpid()'的POSIX文檔](http://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html) (Linux的手冊頁基本上是一樣的):「*** ERRORS ** 如果發生以下情況,waitpid()函數將失敗:[...] [EINTR] 函數被信號中斷。 ..]「*」 – alk

+2

另外,不要使用'signal()',因爲它的語義不同;請務必使用['sigaction()'](http://man7.org/linux/man-pages/man2/sigaction.2.html)。另外,如果同時包含''和'',則可以使用'strerror(errno)'獲取可讀的錯誤字符串。 –

回答

0

作爲每wait()/waitpid() POSIX documentaion

wait()功能須安排調用線程阻塞變得直到由子進程終止產生的狀態信息提供給線程,或直至分娩的信號,其作用是任一執行信號捕獲函數或終止進程,或發生錯誤。

如果由於信號到調用進程的遞送wait()waitpid()回報,-1應退還和errno設置爲[EINTR]

由於您已經配置了SIGHUP來執行一個函數,所以它被上面的強調子句覆蓋。

這與許多其他系統調用時信號中斷,可以返回EAGAIN。你可以處理它的方法之一是用類似代碼:

// Keep waiting while being interrupted. 

int rc, err; 
do { 
    rc = waitpid (initProcessPid, &status, 0); 
    err = errno; 
} while ((rc == -1) && (err == EINTR)); 

// Any error other than interruption will be caught here. 

if (rc == -1) { 
    printf ("debug: errno is %d\n", err); 
    printf ("failed to wait for init process to end\n"); 
} 

你也是正確的認爲Linux一般規定,這應該是4而不是5但事實並非總是如此。有些系統使用大不相同的值(如IBM iSeries,將這些常見錯誤代碼放在3400左右的某處)。

你應該檢查對特定而不是一個固定值。