2013-01-25 74 views
0

在我的C程序中,我正在創建一個子進程並在子進程中運行execvp。但是我試圖將錯誤消息更改爲其他內容,對於execvp命令(如果出現錯誤)。如何在子進程中使用dup2?

我知道如果它返回,那是一個錯誤,那麼我可以在下一行打印我自己的自定義錯誤消息。這是一種可能發生的錯誤,例如,如果我將命令「sdfsd」給予execvp,就會發生這種情況。這部分爲我工作。

但是,如果我輸入「find sdfsd」,那麼它不會返回並打印「find:`sdfsd':沒有這樣的文件或目錄」。

我想改變這個消息(以及基本上來自exevcp的任何類型的錯誤消息)到我自己定製的消息。

我相信我可以用DUP2要做到這一點,但我不知道如何...

在子過程中,我試圖

dup2(STDERR_FILENO, 1); 
fclose(stderr); 

但這只是停止從寫作子進程任何錯誤消息。我仍然無法在所有情況下打印我自己的消息。

有誰知道如何做到這一點? 謝謝

回答

1

由於execvp永遠不會返回,如果它成功地啓動新程序,您將不能在子程序中運行execvp程序失敗後打印自己的錯誤信息。一種選擇是將stderr管道傳遞給父進程,在那裏攔截錯誤消息,然後打印自己的錯誤消息。

例如:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main(int argc, char **argv) 
{ 
    int ff, p[2]; 
    FILE *f; 
    char *vv[] = {"find", "garbage", (char *)NULL}; 
    char msg[100]; 

    if (pipe(p) != 0) 
    { 
    fprintf(stderr, "Pipe failed\n"); 
    return 1; 
    } 

    if ((ff = fork()) == -1) 
    { 
    fprintf(stderr, "Fork failed\n"); 
    return 1; 
    } 

    if (ff == 0) 
    { 
    /* In the child process */ 
    close(2); 
    close(p[0]); 
    dup2(p[1], 2); 
    execvp("find", vv); 
    return 1; 
    }; 

    /* In the parent process */ 
    close(p[1]); 
    f = fdopen(p[0], "r"); 
    if (f == NULL) 
    { 
    fprintf(stderr, "Fdopen failed\n"); 
    return 1; 
    } 
    if (fgets(msg, sizeof(msg), f) == NULL) 
    { 
    fprintf(stderr, "Fgets failed\n"); 
    return 1; 
    } 
    printf("Error message was: %s", msg); 
    /* and so on */ 
    return 0; 
} 
+0

沒有你需要關閉所有管道和文件描述符? – omega

+0

當進程結束時,它們應該自動關閉。在一個真正的程序中,在這之前清理它們可能會更好。 –

+0

所以基本上,在父進程中,在最後一部分中,如果從管道的讀端讀取,如果它是NULL,則在子進程中管道的寫入結束沒有寫入任何內容,這意味着沒有錯誤發生,如果它不是NULL,則在子進程中管道的寫入端寫入了一些內容,這意味着發生了錯誤。這是正確的嗎? – omega

相關問題