在函数调用时拦截标准输出的内存文件

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.

我看到两个选择。

  1. 如果您知道输出的最大大小,并且大小不太大,请使用 socketpair 而不是 pipe。与管道不同,套接字允许更改 egress/ingress 缓冲区的大小。

  2. /tmp 上使用临时文件。在正常情况下,它不会接触磁盘(除非系统正在交换)。有几个函数用于此目的,例如 mkstemp (or tmpfile).