C++ 暂时重定向或禁用 stdio
C++ redirect or disable stdio temporarily
在 MacOS X 下的 C++ 项目中,我们使用 stdio 与客户端进行交互。然而,我们使用的 dylib 也使用 stdio 来打印 "open log files"。这打破了我们的客户和应用程序之间的所有通信。我查看了将 stdio 重定向到文件或暂时禁用 stdio 的示例。然而,我们未能成功。
那么,我们如何在与 dylib 交互时暂时禁用或重定向 stdio。
OSX 是一个 POSIX 系统,和所有 POSIX 系统一样,标准输出是文件描述符 STDOUT_FILENO
(这是一个定义为 1
的宏).
您可以做的是 duplicate STDOUT_FILENO
to another file descriptor, open 一个临时文件并将临时文件复制(使用 dup2
)为 STDOUT_FILENO
。然后每当有输出到标准输出(使用普通 write
、C printf
或 C++ std::cout
)时,它将被放入临时文件中。
完成临时 "redirection" 后,您只需将保存的标准输出(来自第一个 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
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 中调用的函数。现在,用上面描述的重定向和恢复函数包围这些函数。
在 MacOS X 下的 C++ 项目中,我们使用 stdio 与客户端进行交互。然而,我们使用的 dylib 也使用 stdio 来打印 "open log files"。这打破了我们的客户和应用程序之间的所有通信。我查看了将 stdio 重定向到文件或暂时禁用 stdio 的示例。然而,我们未能成功。
那么,我们如何在与 dylib 交互时暂时禁用或重定向 stdio。
OSX 是一个 POSIX 系统,和所有 POSIX 系统一样,标准输出是文件描述符 STDOUT_FILENO
(这是一个定义为 1
的宏).
您可以做的是 duplicate STDOUT_FILENO
to another file descriptor, open 一个临时文件并将临时文件复制(使用 dup2
)为 STDOUT_FILENO
。然后每当有输出到标准输出(使用普通 write
、C printf
或 C++ std::cout
)时,它将被放入临时文件中。
完成临时 "redirection" 后,您只需将保存的标准输出(来自第一个 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
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 中调用的函数。现在,用上面描述的重定向和恢复函数包围这些函数。