How to capture cerr from another program?

I wrote an application in C++ that throws exceptions, and catch sends error messages to cerr.
Now I am writing a tester in C++ that calls the application.
The tester should compare the application's error messages to expected error messages.
The tester uses system() to run the application; but am at a lose as how to capture the application's error messages.
system() function does not return the cerr messages. http://www.cplusplus.com/reference/cstdlib/system/

Is there a way the tester can run the application and capture the application's error messages?

Thank you.

update: I am using Linux.
Last edited on
You can't use standard functions to do this, you have to use OS-specific functions.

If you're on Windows, basically you do this by opening one-way pipes and passing the 'in' ends to the new process via CreateProcess(), through the STARTUPINFO structure, while the calling process holds the 'out' ends and read from them. See:
CreateProcess(): https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
STARTINFO, and more specifically the hStd* members: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx

If you're on Linux, the thing about the pipes is the same. The functions you have to call are obviously different.
See:
http://stackoverflow.com/questions/9405985/linux-3-0-executing-child-process-with-piped-stdin-stdout
http://stackoverflow.com/questions/17716359/redirect-child-processs-stdin-and-stdout-to-pipes
POSIX-ish systems provide popen(3):
http://man7.org/linux/man-pages/man3/popen.3.html

IIRC, Windows provides _popen() in the C library.

This is suitable for one-way communication only (the use of std::system() implies this is acceptable). You will need to use the system's shell syntax to redirect standard error to you.
Last edited on
> Is there a way the tester can run the application and capture the application's error messages?

All command processors support redirection of stderr with 2> and 2>>;
redirect the program's stderr to a file, and then read the file in the tester.

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <cstdlib>
#include <fstream>

int main()
{
    std::system( "bad_command 2> stderr.txt" ) ;

    std::cout << "\n-------------- stderr: -------------------\n"
              << std::ifstream( "stderr.txt" ).rdbuf()
              << "-------------------------------------------\n" ;
}

http://rextester.com/DWIC20793
Last edited on
I am using Linux.

Thank you for all the responses.
It will take some time to digest all the new information you have provided.
I will post results later.
I went with the example from JLBorges because it's so simple.
The following works as intended.

Thanks JLBorges.

tester.cpp
1
2
3
4
5
6
7
8
9
10
11
12
#include <fstream>
#include <string>
#include <iostream>

int main()
{
    std::cerr << "cerr1 from tester\n";

    system("./app 2> stderr.txt");

    std::cerr << "cerr3 from tester\n";
}


app.cpp
1
2
3
4
5
6
7
8
9
#include <fstream>
#include <string>
#include <iostream>

int main()
{
    std::cerr << "cerr2 from app\n";
    std::cout << "cout from app\n";
}


output from terminal:
1
2
3
4
5
6
$ g++ app.cpp -o app
$ g++ tester.cpp -o tester
$ ./tester
cerr1 from tester
cout from app
cerr3 from tester


stderr.txt:
cerr2 from app
Last edited on
Topic archived. No new replies allowed.