Search code examples
c++unixprocessstdoutpid

read stdout of a process in itself using c++


Consider we have some_function and it prints result to stdout instead returning it.Changing it's defination is out of our scope and there's no alternative to it. We're left with option of reading it from stdout. So the question.

How to read stdout of C++ program in itself.

It is possible to get pid I searched if we can get fd of the same programm but I'm not able to find anything.

#include <unistd.h>
#include <sys/types.h>
#include <iostream>
void some_function(){
    std::cout<<"Hello World";
}

int main(){


    int pid = ::getpid();
    string s = //What to write here.

    cout<<"Printing";

    some_function(); //This function prints "Hello World" to screen

    cout<<s; //"PrintingHello World"
    return  0;
}

How to attach pipe to same process i.e instead of creating child process.

Some might think of creating child process and call some_function in it, to be able to read its stdout in parent process, but No, some_function depends on process which calls it and hence we want to call it the very process instead of creating child process.


Solution

  • This isn't hard to do, but IMO it's quite a hack, and it won't work with a multithreaded program:

    // make a temp file to store the function's stdout
    int newStdOut = mkstemp( "/tmp/stdout.XXXXXXX" );
    
    // save the original stdout
    int tmpStdOut = dup( STDOUT_FILENO );
    
    // clear stdout
    fflush( stdout );
    
    // now point the stdout file descriptor to the file
    dup2( newStdOut, STDOUT_FILENO );
    
    // call the function we want to collect the stdout from
    some_function();
    
    // make sure stdout is empty
    fflush( stdout );
    
    // restore original stdout
    dup2( tmpStdOut, STDOUT_FILENO );
    
    // the tmp file now contains whatever some_function() wrote to stdout
    

    Error checking, proper headers, syncing C stdout with C++ cout, and reading from and cleaning up the temp file are left as exercises... ;-)

    Note that you can't safely use a pipe - the function can write enough to fill up the pipe, and you can't read from the pipe because you've called the function.