Redirecting stderr: in single process, *not* in a child process. - Programmer

This is a discussion on Redirecting stderr: in single process, *not* in a child process. - Programmer ; Hello all. I spent a long day yesterday battling trying to achieve something that sounds very simple until you actually try and do it. Let me explain the situation: I've taken a third party bit of server software that comes ...

+ Reply to Thread
Results 1 to 5 of 5

Thread: Redirecting stderr: in single process, *not* in a child process.

  1. Redirecting stderr: in single process, *not* in a child process.

    Hello all.

    I spent a long day yesterday battling trying to achieve something that
    sounds very simple until you actually try and do it. Let me explain
    the situation:

    I've taken a third party bit of server software that comes with a BSD
    license and I have written a thin wrapper for it using our standard C+
    + classes for logging, configuration, service management etc. The
    source code for the original software is basically unchanged, and I
    want to keep it this way so that is simple to upgrade it when need be.

    The problem is that the software uses simple c-style logging to
    stderr, using fprintf mostly. What I want to do is capture this
    output and send it somewhere else within my own application.

    On unix I have solved this problem in the following manner:

    Create a pair of interconnected sockets using the "socketpair" call.
    Use dup2 to make stderr send its output to one of these sockets.
    Start a thread to monitor the other end of the socket and process
    the output as it arrives.

    This would all work fine on windows except on win32, sockets are not
    the same as file descriptors. In short the method I am using on Unix
    will not work on windows, or not that I can see.

    I've spent hours trying to find an alternative solution to this simple
    problem, playing with SetStdHandler, pipes, named pipes, sockets and
    all sorts. I have yet to find a way to redirect everything sent to
    "stderr" to a place of my choosing.

    An example of how hard this is can be seen in the following code:


    ///
    /// Function: main()
    ///
    int main ( int argc, char * const argv[] )
    {
    HANDLE hRead, hWrite;

    if ( !CreatePipe( &hRead, &hWrite ,NULL, 10 ) )
    return FALSE;

    SetStdHandle( STD_ERROR_HANDLE, hWrite );

    fprintf( stderr, "This will NOT go to the pipe, but instead to the
    console\n" );

    return 0;
    }


    Even though I redirect the stderr to my pipe, that output will go to
    the screen. Apparantly stderr has already been setup within the
    printf code, and calling SetStdHandle has no effect.

    In short I'm completely stumped. If someone can show me a way to do
    this I would be most grateful. All examples on the web seem to be
    oriented towards how to redirect the output of a child process, which
    is really not what I'm trying to do here.

    Thanks in advance.

    Jamie

  2. Re: Redirecting stderr: in single process, *not* in a child process.

    JKP wrote:
    > Hello all.
    >
    > I spent a long day yesterday battling trying to achieve something that
    > sounds very simple until you actually try and do it. Let me explain
    > the situation:
    >
    > I've taken a third party bit of server software that comes with a BSD
    > license and I have written a thin wrapper for it using our standard C+
    > + classes for logging, configuration, service management etc. The
    > source code for the original software is basically unchanged, and I
    > want to keep it this way so that is simple to upgrade it when need be.
    >
    > The problem is that the software uses simple c-style logging to
    > stderr, using fprintf mostly. What I want to do is capture this
    > output and send it somewhere else within my own application.
    >
    > On unix I have solved this problem in the following manner:
    >
    > Create a pair of interconnected sockets using the "socketpair" call.
    > Use dup2 to make stderr send its output to one of these sockets.
    > Start a thread to monitor the other end of the socket and process
    > the output as it arrives.
    >
    > This would all work fine on windows except on win32, sockets are not
    > the same as file descriptors. In short the method I am using on Unix
    > will not work on windows, or not that I can see.
    >
    > I've spent hours trying to find an alternative solution to this simple
    > problem, playing with SetStdHandler, pipes, named pipes, sockets and
    > all sorts. I have yet to find a way to redirect everything sent to
    > "stderr" to a place of my choosing.
    >
    > An example of how hard this is can be seen in the following code:
    >
    >
    > ///
    > /// Function: main()
    > ///
    > int main ( int argc, char * const argv[] )
    > {
    > HANDLE hRead, hWrite;
    >
    > if ( !CreatePipe( &hRead, &hWrite ,NULL, 10 ) )
    > return FALSE;
    >
    > SetStdHandle( STD_ERROR_HANDLE, hWrite );
    >
    > fprintf( stderr, "This will NOT go to the pipe, but instead to the
    > console\n" );
    >
    > return 0;
    > }
    >

    >
    > Even though I redirect the stderr to my pipe, that output will go to
    > the screen. Apparantly stderr has already been setup within the
    > printf code, and calling SetStdHandle has no effect.
    >
    > In short I'm completely stumped. If someone can show me a way to do
    > this I would be most grateful. All examples on the web seem to be
    > oriented towards how to redirect the output of a child process, which
    > is really not what I'm trying to do here.
    >
    > Thanks in advance.
    >
    > Jamie


    Try using _pipe() and _dup2().

    --
    Norm

    To reply, change domain to an adult feline.


  3. Re: Redirecting stderr: in single process, *not* in a child process.

    try it.
    FILE *p = freopen("c:\\a.txt", "w", stderr);
    fprintf(stderr, "Anand");
    fclose(p);
    Thanks
    Anand
    On Aug 15, 6:29*pm, Norman Bullen
    wrote:
    > JKP wrote:
    > > Hello all.

    >
    > > I spent a long day yesterday battling trying to achieve something that
    > > sounds very simple until you actually try and do it. *Let me explain
    > > the situation:

    >
    > > I've taken a third party bit of server software that comes with a BSD
    > > license and I have written a thin wrapper for it using our standard C+
    > > + classes for logging, configuration, service management etc. *The
    > > source code for the original software is basically unchanged, and I
    > > want to keep it this way so that is simple to upgrade it when need be.

    >
    > > The problem is that the software uses simple c-style logging to
    > > stderr, using fprintf mostly. *What I want to do is capture this
    > > output and send it somewhere else within my own application.

    >
    > > On unix I have solved this problem in the following manner:

    >
    > > Create a pair of interconnected sockets using the "socketpair" call..
    > > Use dup2 to make stderr send its output to one of these sockets.
    > > Start a thread to monitor the other end of the socket and process
    > > the output as it arrives.

    >
    > > This would all work fine on windows except on win32, sockets are not
    > > the same as file descriptors. *In short the method I am using on Unix
    > > will not work on windows, or not that I can see.

    >
    > > I've spent hours trying to find an alternative solution to this simple
    > > problem, playing with SetStdHandler, pipes, named pipes, sockets and
    > > all sorts. *I have yet to find a way to redirect everything sent to
    > > "stderr" to a place of my choosing.

    >
    > > An example of how hard this is can be seen in the following code:

    >
    > >
    > > ///
    > > /// Function: main()
    > > ///
    > > int main ( int argc, char * const argv[] )
    > > {
    > > * *HANDLE hRead, hWrite;

    >
    > > * *if ( !CreatePipe( &hRead, &hWrite ,NULL, 10 ) )
    > > * * * * * *return FALSE;

    >
    > > * *SetStdHandle( STD_ERROR_HANDLE, hWrite );

    >
    > > * *fprintf( stderr, "This will NOT go to the pipe, but instead to the
    > > console\n" );

    >
    > > * *return 0;
    > > }
    > >

    >
    > > Even though I redirect the stderr to my pipe, that output will go to
    > > the screen. *Apparantly stderr has already been setup within the
    > > printf code, and calling SetStdHandle has no effect.

    >
    > > In short I'm completely stumped. *If someone can show me a way to do
    > > this I would be most grateful. *All examples on the web seem to be
    > > oriented towards how to redirect the output of a child process, which
    > > is really not what I'm trying to do here.

    >
    > > Thanks in advance.

    >
    > > Jamie

    >
    > Try using _pipe() and _dup2().
    >
    > --
    > Norm
    >
    > To reply, change domain to an adult feline.



  4. Re: Redirecting stderr: in single process, *not* in a child process.

    Hi Jamie, I've had a similar problem in Windows -- redirecting stderr to a named pipe NOT in a child process -- and solved it thus:

    1. Create a named pipe using CreateFile() if the code is to to be a pipe client, or CreateNamedPipe() + ConnectNamedPipe() if it's to be a pipe server. You might need to spawn a thread to listen for connections depending on how your program works.

    2. I don't like working in the Windows() world with file and stream I/O, so I take the Windows file handle for the pipe and make a C file descriptor of it, using _open_osfhandle(). I then call _fdopen() on the file descriptor, so I now have a FILE * representing my output pipe handle. Let's call the FILE * fout.

    3. *stderr = *fout; // now, all code writing to stderr goes to fout


    4. setvbuf(stderr, NULL, _IONBF, 0); // Things dont work unless we make stderr unbuffered

    That's it. Let me know if you want details/code.

  5. Re: Redirecting stderr: in single process, *not* in a child process.

    >> That's it. Let me know if you want details/code.

    Hi

    Please, if still possible, could you post further details?? Win32 API will always be a mistery for me...

    Thx!

+ Reply to Thread