Redirect FROM stderr to another file descriptor

2019-01-28 22:09发布

My program calls library functions which print to stderr. I want to intervene so that all write calls to file descriptor #2 will instead get sent to somewhere else.

Here is my first attempt:

bool redirect_stderr (int fd)
{
    return dup2 (2, fd) > 0;
}

Here, fd was successfully obtained from open("/foo/bar",O_APPEND|O_CREAT)

After this function returns true, std::cerr<<"blah" goes to the terminal and not to the file.

What am I doing wrong?

Thanks.

UPDATE

Thanks, larsmans, but I'm not there yet...

void redirect_stderr_to (const char * output_file)
{
    int fd = open (output_file, O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);

    if (fd < 0) {
        throw RUNTIME_ERROR;
    }
    else {
        if (-1 == dup2 (fd, STDERR_FILENO))
            throw RUNTIME_ERROR;

        std :: cout << (std::cerr ? "Fine\n" : "Bad\n");
        char x [100];
        std :: cerr
            << "Output to " << getcwd (x, 100) << " / " << output_file
            <<  " yields " << fd << " errno: " << errno << "\n";
        std :: cout << (std::cerr ? "Fine\n" : "Bad\n");
    }
}

This outputs

Fine
Bad

to stdout and the given file is empty. (It is correctly created if it doesn't exist.)

2条回答
贪生不怕死
2楼-- · 2019-01-28 22:20

You reversed the arguments: it's

dup2(from_fd, to_fd)

i.e.

dup2(fd, 2)

(see POSIX.2008 or your manpages.)

查看更多
做个烂人
3楼-- · 2019-01-28 22:23

Just for completeness: You could even achieve your goal with freopen(name, mode, stderr), which is a Standard/ANSI/ISO C89 and C99 function.

查看更多
登录 后发表回答