2013-01-25 36 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

相关问题