C ++暂时重定向或禁用stdio

时间:2016-05-23 07:57:20

标签: c++ stdio

在MacOS X下的C ++项目中,我们使用stdio与客户进行交互。然而,我们使用的dylib也使用stdio来打印“打开日志文件”。这打破了我们客户和应用程序之间的所有通信。我查看了将stdio重定向到文件或暂时禁用stdio的示例。然而,我们无法成功。

那么,我们如何在与dylib交互时暂时禁用或重定向stdio。

2 个答案:

答案 0 :(得分:2)

OSX是POSIX系统,与所有POSIX系统一样,标准输出是文件描述符STDOUT_FILENO(这是一个定义为1的宏)。

您可以对另一个文件描述符duplicate STDOUT_FILENO执行open临时文件,并将临时文件复制为dup2 STDOUT_FILENO 。然后,只要有输出到标准输出(使用普通write,C printf或C ++ std::cout),它就会被放入临时文件中。

完成临时“重定向”后,您只需将保存的标准输出(从第一次dup调用)复制回STDOUT_FILENO即可。并关闭并删除临时文件。

如下所示:

int saved_stdout = dup(STDOUT_FILENO);

int temp_file = open("/tmp/temp_stdout", O_WRONLY, 0600);
dup2(temp_file, STDOUT_FILENO);  // Replace standard out

// Code here to write to standard output
// It should all end up in the file /tmp/temp_stdout

dup2(saved_stdout, STDOUT_FILENO);  // Restore old standard out
close(temp_file)
unlink("/tmp/temp_stdout");  // Remove file

答案 1 :(得分:1)

void RedirectStandardStreamsToDEVNULL(int *_piOriginalSTDIN_FILENO, int *_piOriginalSTDOUT_FILENO, int *_piOriginalSTDERR_FILENO)
{
        //flushing pending things before redirection.
        //fflush(stdin);
        fflush(stdout);
        fflush(stderr);

        *_piOriginalSTDIN_FILENO = dup(STDIN_FILENO);
        *_piOriginalSTDOUT_FILENO = dup(STDOUT_FILENO);
        *_piOriginalSTDERR_FILENO = dup(STDERR_FILENO);

        int devnull = open("/dev/null", O_RDWR);
        dup2(devnull, STDIN_FILENO);
        dup2(devnull, STDOUT_FILENO);
        dup2(devnull, STDERR_FILENO);
        close(devnull);
}
void RestoreStandardStreams(int *_piOriginalSTDIN_FILENO, int *_piOriginalSTDOUT_FILENO, int *_piOriginalSTDERR_FILENO)
{
        //flushing pending things before restoring.
        //fflush(stdin);
        fflush(stdout);
        fflush(stderr);

        dup2(*_piOriginalSTDIN_FILENO, STDIN_FILENO);
        dup2(*_piOriginalSTDOUT_FILENO, STDOUT_FILENO);
        dup2(*_piOriginalSTDERR_FILENO, STDERR_FILENO);
}

void myfunction()
{
    int iOriginalSTDIN_FILENO = -1;
    int iOriginalSTDOUT_FILENO = -1;
    int iOriginalSTDERR_FILENO = -1;
    RedirectStandardStreamsToDEVNULL(&iOriginalSTDIN_FILENO, &iOriginalSTDOUT_FILENO, &iOriginalSTDERR_FILENO);

//all of your code which prints to stdout or stderr will be directed to /dev/null

    RestoreStandardStreams(&iOriginalSTDIN_FILENO, &iOriginalSTDOUT_FILENO, &iOriginalSTDERR_FILENO);

}

重点是识别代码中dylib内部调用的函数。现在,使用上述的Redirect和Restore功能包围这些功能。