<p>I am wrapping existing C++ code from a <strong>BSD</strong> project in our own custom wrapper and I want to integrate it to our code with as few changes as possible. This code uses <code>fprintf</code> to print to <strong>stderr</strong> in order to log / report errors.</p>

<p>I want to redirect this to an alternative place within the same process. On <strong>Unix</strong> I have done this with a <code>socketpair</code> and a <code>thread</code>: one end of the socket is where I send <strong>stderr</strong> (via a call to <code>dup2</code>) and the other end is monitored in a thread, where I can then process the output.</p>

<p>This does not work on <strong>Windows</strong> though because a socket is not the same as a file handle.</p>

<p>All documents I have found on the web show how to redirect output from a child process, which is not what I want.  How can I redirect <strong>stderr</strong> within the same process getting a callback of some sort when output is written?  (and before you say so, I've tried <code>SetStdHandle</code> but cannot find any way to make this work)...</p>

[{'answer_id': 7669, 'author': 'Greg Hewgill', 'author_id': 893, 'author_profile': 'https://Stackoverflow.com/users/893', 'pm_score': 4, 'selected': True, 'text': '<p>You can use a similar technique on Windows, you just need to use different words for the same concepts. :) This article: <a href="http://msdn.microsoft.com/en-us/library/ms682499.aspx" rel="noreferrer">http://msdn.microsoft.com/en-us/library/ms682499.aspx</a> uses a win32 pipe to handle I/O from another process, you just have to do the same thing with threads within the same process. Of course, in your case all output to stderr from anywhere in the process will be redirected to your consumer.</p>\n\n<p>Actually, other pieces of the puzzle you may need are <a href="http://msdn.microsoft.com/en-us/library/dye30d82(VS.80).aspx" rel="noreferrer">_fdopen</a> and <a href="http://msdn.microsoft.com/en-us/library/bdts1c9x(VS.71).aspx" rel="noreferrer">_open_osfhandle</a>. In fact, here\'s a related example from some <a href="http://hewgill.com/pilot/copilot/" rel="noreferrer">code</a> I released years ago:</p>\n\n<pre><code>DWORD CALLBACK DoDebugThread(void *)\n{\n    AllocConsole();\n    SetConsoleTitle("Copilot Debugger");\n    // The following is a really disgusting hack to make stdin and stdout attach\n    // to the newly created console using the MSVC++ libraries. I hope other\n    // operating systems don\'t need this kind of kludge.. :)\n    stdout-&gt;_file = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);\n    stdin-&gt;_file  = _open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE), _O_TEXT);\n    debug();\n    stdout-&gt;_file = -1;\n    stdin-&gt;_file  = -1;\n    FreeConsole();\n    CPU_run();\n    return 0;\n}   \n</code></pre>\n\n<p>In this case, the main process was a GUI process which doesn\'t start with stdio handles at all. It opens a console, then shoves the right handles into stdout and stdin so the debug() function (which was designed as a stdio interactive function) can interact with the newly created console. You should be able to open some pipes and do the same sort of thing to redirect stderr.</p>\n'}, {'answer_id': 7682, 'author': 'Greg Hewgill', 'author_id': 893, 'author_profile': 'https://Stackoverflow.com/users/893', 'pm_score': 2, 'selected': False, 'text': '<p>You have to remember that what MSVCRT calls "OS handles" are not Win32 handles, but another layer of handles added just to confuse you. MSVCRT tries to emulate the Unix handle numbers where <code>stdin</code> = 0, <code>stdout</code> = 1, <code>stderr</code> = 2 and so on. Win32 handles are numbered differently and their values always happen to be a multiple of 4. Opening the pipe and getting all the handles configured properly will require getting your hands messy. Using the MSVCRT source code and a debugger is probably a requirement.</p>\n'}, {'answer_id': 70478, 'author': 'Len Holgate', 'author_id': 7925, 'author_profile': 'https://Stackoverflow.com/users/7925', 'pm_score': 1, 'selected': False, 'text': '<p>You mention that you don\'t want to use a named pipe for internal use; it\'s probably worth poining out that the documentation for <a href="http://msdn.microsoft.com/en-us/library/aa365152(VS.85).aspx" rel="nofollow noreferrer">CreatePipe()</a> states, <em>"Anonymous pipes are implemented using a named pipe with a unique name. Therefore, you can often pass a handle to an anonymous pipe to a function that requires a handle to a named pipe."</em> So, I suggest that you just write a function that creates a similar pipe with the correct settings for async reading. I tend to use a GUID as a string (generated using <code>CoCreateGUID()</code> and <code>StringFromIID()</code>) to give me a unique name and then create the server and client ends of the named pipe with the correct settings for overlapped I/O (more details on this, and code, here:  <a href="http://www.lenholgate.com/blog/2008/02/process-management-using-jobs-on-windows.html" rel="nofollow noreferrer">http://www.lenholgate.com/blog/2008/02/process-management-using-jobs-on-windows.html</a>).</p>\n\n<p>Once I have that I wire up some code that I have to read a file using overlapped I/O with an I/O Completion Port and, well, then I just get async notifications of the data as it arrives...  However, I\'ve got a fair amount of well tested library code in there that makes it all happen... </p>\n\n<p>It\'s probably possible to set up the named pipe and then just do an overlapped read with an event in your <code>OVERLAPPED</code> structure and check the event to see if data was available... I don\'t have any code available that does that though.</p>\n'}]
['https://Stackoverflow.com/questions/7664', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/912/']