在函数调用时拦截标准输出的内存文件
In-memory file to intercept stdout on function call
我已经继承了这个必须从我的代码中调用的函数。功能是
来自一个神秘的编程语言的奇怪库——所以我不能假设
几乎所有关于它的东西,除了它打印一些有用的事实
信息到标准输出。
让我用
模拟一下它的效果
void black_box(int n)
{
for(int i=0; i<n; i++) std::cout << "x";
std::cout << "\n";
}
我想拦截并使用它输出的东西。为此,我重定向标准输出
到临时文件,调用 black_box
,然后恢复标准输出并读取
临时文件中的内容:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
int main(void){
int fd = open( "outbuff", O_RDWR | O_TRUNC | O_CREAT, 0600);
// Redirect stdout to fd
int tmp = dup(1);
dup2( fd, 1);
// Execute
black_box(100);
std::cout << std::flush;
// Restore old stdout
dup2(tmp, 1);
// Read output from the outbuff flie
struct stat st;
fstat(fd, &st);
std::string buf;
buf.resize(st.st_size);
lseek(fd, 0, SEEK_SET);
read(fd, &buf[0], st.st_size);
close(fd);
std::cout << "Captured: " << buf << "\n";
return 0;
}
这行得通。但是为这样的任务在磁盘上创建一个文件不是我想要的
引以为傲。我可以制作类似文件但在内存中的东西吗?
在建议管道之前,请考虑如果
black_box
缓冲区溢出。不,我需要它是单线程的——
开始一个额外的 process/thread 会破坏我正在尝试的整个目的
实现。
I want to intercept and use the stuff it outputs.
[...] please consider what would happen if black_box overflows its buffer.
我看到两个选择。
如果您知道输出的最大大小,并且大小不太大,请使用 socketpair
而不是 pipe
。与管道不同,套接字允许更改 egress/ingress 缓冲区的大小。
在 /tmp
上使用临时文件。在正常情况下,它不会接触磁盘(除非系统正在交换)。有几个函数用于此目的,例如 mkstemp
(or tmpfile
).
我已经继承了这个必须从我的代码中调用的函数。功能是 来自一个神秘的编程语言的奇怪库——所以我不能假设 几乎所有关于它的东西,除了它打印一些有用的事实 信息到标准输出。
让我用
模拟一下它的效果void black_box(int n)
{
for(int i=0; i<n; i++) std::cout << "x";
std::cout << "\n";
}
我想拦截并使用它输出的东西。为此,我重定向标准输出
到临时文件,调用 black_box
,然后恢复标准输出并读取
临时文件中的内容:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
int main(void){
int fd = open( "outbuff", O_RDWR | O_TRUNC | O_CREAT, 0600);
// Redirect stdout to fd
int tmp = dup(1);
dup2( fd, 1);
// Execute
black_box(100);
std::cout << std::flush;
// Restore old stdout
dup2(tmp, 1);
// Read output from the outbuff flie
struct stat st;
fstat(fd, &st);
std::string buf;
buf.resize(st.st_size);
lseek(fd, 0, SEEK_SET);
read(fd, &buf[0], st.st_size);
close(fd);
std::cout << "Captured: " << buf << "\n";
return 0;
}
这行得通。但是为这样的任务在磁盘上创建一个文件不是我想要的 引以为傲。我可以制作类似文件但在内存中的东西吗?
在建议管道之前,请考虑如果
black_box
缓冲区溢出。不,我需要它是单线程的——
开始一个额外的 process/thread 会破坏我正在尝试的整个目的
实现。
I want to intercept and use the stuff it outputs.
[...] please consider what would happen if black_box overflows its buffer.
我看到两个选择。
如果您知道输出的最大大小,并且大小不太大,请使用
socketpair
而不是pipe
。与管道不同,套接字允许更改 egress/ingress 缓冲区的大小。在
/tmp
上使用临时文件。在正常情况下,它不会接触磁盘(除非系统正在交换)。有几个函数用于此目的,例如mkstemp
(ortmpfile
).