| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 5 | |
Hi, I am running a program that is calling a library which prints out messages with printf. I would like to be able to show these messages in a qt dialog . Is it possible to do so? Thanks, Marie -- [ signature omitted ]
Use QMessageBox. Karl On Wednesday 29 August 2007 11:07, Marie-Christine Vallet wrote: > Hi, > I am running a program that is calling a library which prints out > messages with printf. I would like to be able to show these messages in > a qt dialog . Is it possible to do so? > Thanks, > Marie > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with > "unsubscribe" in the subject or the body. List archive and information: > http://lists.trolltech.com/qt-interest/ -- [ signature omitted ]
Karl Ruetz wrote: > Use QMessageBox. > So far so good, but how can I get the printf to show in it? -- [ signature omitted ]
El Miércoles 29 Agosto 2007, Marie-Christine Vallet escribió: > Karl Ruetz wrote: > > Use QMessageBox. > > So far so good, but how can I get the printf to show in it? To don't use printf. You use the string that you will use as a parameter in printf as the parameter of QMessageBox. regards, Lisandro. -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
Lisandro Damián Nicanor Pérez Meyer wrote: > El Miércoles 29 Agosto 2007, Marie-Christine Vallet escribió: > >> Karl Ruetz wrote: >> >>> Use QMessageBox. >>> >> So far so good, but how can I get the printf to show in it? >> > > To don't use printf. You use the string that you will use as a parameter in > printf as the parameter of QMessageBox. > > regards, Lisandro. > > > > the thing is it's in a library that does not use qt, so I guess it's not possible then. Thanks, Marie -- [ signature omitted ]
On August 29, 2007 11:01:33 am Marie-Christine Vallet wrote: > Lisandro Damián Nicanor Pérez Meyer wrote: > > El Miércoles 29 Agosto 2007, Marie-Christine Vallet escribió: > >> Karl Ruetz wrote: > >>> Use QMessageBox. > >> > >> So far so good, but how can I get the printf to show in it? > > > > To don't use printf. You use the string that you will use as a parameter > > in printf as the parameter of QMessageBox. > > > > regards, Lisandro. > > the thing is it's in a library that does not use qt, so I guess it's not > possible then. > Thanks, > Marie You may be able to use QProcess to do this. If it is a library linked in to your application rather than an external tool, matters are going to be more difficult. -- [ signature omitted ]
> > You may be able to use QProcess to do this. If it is a library linked in to > your application rather than an external tool, matters are going to be more > difficult. > it is a library linked to my application -- [ signature omitted ]
On August 29, 2007 11:14:33 am Marie-Christine Vallet wrote: > > You may be able to use QProcess to do this. If it is a library linked in > > to your application rather than an external tool, matters are going to be > > more difficult. > > it is a library linked to my application You may possibly be able to redirect stdout to a file so that your library dumps its output there, then read this file back in back in your main app. It's far from ideal, though, even if it could actually work. -- [ signature omitted ]
Chris Thompson wrote: > On August 29, 2007 11:14:33 am Marie-Christine Vallet wrote: > >>> You may be able to use QProcess to do this. If it is a library linked in >>> to your application rather than an external tool, matters are going to be >>> more difficult. >>> >> it is a library linked to my application >> > > You may possibly be able to redirect stdout to a file so that your library > dumps its output there, then read this file back in back in your main app. > It's far from ideal, though, even if it could actually work. > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body. > List archive and information: http://lists.trolltech.com/qt-interest/ > > > it is possible to redirect the output in a file. The reason I want to do this is to let the user know that the process is still running, but it is a long process for which I would like to printout the message, a bit like kdevelop where you see the output of the compiling message. thanks, Marie -- [ signature omitted ]
Hopefully this won't sound *too* much like Greek: I'm pretty sure it's possible to do what you want (at least on Unix/Linux) The key to how easily depends on what "file" it's printing to. If it *really* using printf (and not fprintf) then it's writing to stdout which has a file descriptor (fd) of 1. You can create a "pipe"(% man 2 pipe) which has a write end and a read end. You dup2 the write end of the pipe to fd1: dup2(<pipe_write_fd>,1) then when the library writes to fd 1, it will show up on the read end of the pipe. You read the read end of the pipe and output what you get to some qt text widget somewhere. The above is just a hint. Sorry I don't have some code handy. I'm vaguely thinking that Windows can do something similar, but it's been a while since I "went to the metal" with Windows so I just don't remember any details. Marie-Christine Vallet wrote: > Chris Thompson wrote: >> On August 29, 2007 11:14:33 am Marie-Christine Vallet wrote: >> >>>> You may be able to use QProcess to do this. If it is a library >>>> linked in >>>> to your application rather than an external tool, matters are going >>>> to be >>>> more difficult. >>>> >>> it is a library linked to my application >>> >> >> You may possibly be able to redirect stdout to a file so that your >> library dumps its output there, then read this file back in back in >> your main app. It's far from ideal, though, even if it could >> actually work. >> >> -- >> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx >> with "unsubscribe" in the subject or the body. >> List archive and information: http://lists.trolltech.com/qt-interest/ >> >> >> > it is possible to redirect the output in a file. The reason I want to > do this is to let the user know that the process is still running, but > it is a long process for which I would like to printout the message, a > bit like kdevelop where you see the output of the compiling message. > thanks, > Marie > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with > "unsubscribe" in the subject or the body. > List archive and information: http://lists.trolltech.com/qt-interest/ > -- [ signature omitted ]
Peter Hackett schrieb: > ... > The key to how easily depends on what "file" it's printing to. If it > *really* using printf > (and not fprintf) then it's writing to stdout which has a file > descriptor (fd) of 1. You can > create a "pipe"(% man 2 pipe) which has a write end and a read end. You > dup2 the write end Oh boy oh boy oh boy... where have all the good C programmers gone? :) All the workarounds (printing into a file, putting the library into an *.exe and calling it with QProcess and reading from stdout, using pipes, .... *sigh*) probably work in one way or another. But why don't you simply reroute the output written to stdout (and yes, printf really prints to stdout) to a buffer of yours (which is big enough to store the largest expected message from the library) at the beginning of your program (or at least just before you start calling functions from this library?) Basically you want to close stdout first so its file descriptor (which is 1) becomes unused. After that you dup(licate) the file descriptor which is open on a given buffer of yours and since dup() uses the next unused file descriptor (which would be 1 or stdout in this case) everyone who outputs data into stdout (such as printf) now writes into your buffer. It's a bit messy on Windows though - AFAIK we even had to use a thread to constantly read from the buffer (in case there was something to read), because the writer could be blocked otherwise under certain circumstances. This is even documented somewhere in the MSDN. On Unix (Windows) you want to look up dup() and company. Opening a stream (with a file descriptor) on a buffer should also be no problem. I have some code somewhere in our SVN repository, but since we removed this approach (see below) I cannot find it right now (I would have to dig in the older revisions). But I agree very much with one of the previous posts that message handling should never be done in a library (with printf - yucks!). Error codes (or exceptions, if you prefer) should be returned and user strings should only be allocated in the very top GUI layer. Cheers, Oliver -- [ signature omitted ]
Peter Hackett schrieb:
> Hopefully this won't sound *too* much like Greek:
> ...
> The above is just a hint. Sorry I don't have some code handy.
Hmm, and the above was not all that wrong - in fact we did it more or
less like that (sorry, I thought with "pipe" you meant the '|' shell
pipe or something - didn't remember that there was the pipe() function ;)
In the meantime I have checked why we needed a thread (consumer) to read
from the pipe as soon as there is something to read. This was the case
on both Unix and Windows. I am not sure why a thread is needed at all,
but oviously because you could end up in a deadlock if you had only one
thread: when you write more than the pipe could store, then a successive
write() would block forever.
Anyway, here's the code, take it "as is" ("It's your fault when there is
a fault" and all the other lawyerish disclaimers apply), for Unix:
// BEGIN StreamDirector_Unix.cpp
#include <unistd.h>
#include <stdio.h>
#include "StreamReaderThread.h"
#include "StreamDirector.h"
// some convenience defines, for readability
#define PIPE_READ_HANDLE 0
#define PIPE_WRITE_HANDLE 1
static int oldStdout;
static int pipeHandle[2];
static StreamReaderThread *streamReaderThread = 0;
static void cleanUp()
{
// close pipe
(void)::close (pipeHandle[PIPE_READ_HANDLE]);
(void)::close (pipeHandle[PIPE_WRITE_HANDLE]);
// reset stdout
(void)::dup2 (oldStdout, STDOUT_FILENO);
(void)::close (oldStdout);
if (streamReaderThread != 0)
{
delete streamReaderThread;
streamReaderThread = 0;
}
}
bool StreamDirector::redirectStdout (char *buffer, const unsigned int
bufferSize)
{
int status;
// save stdout
oldStdout = ::dup (STDOUT_FILENO);
// create a pipe for communication between license library and the
application
status = pipe (pipeHandle);
if (status != 0)
{
cleanUp();
return false;
}
// redirect stdout, stdout is now written into the pipe
(void)close (STDOUT_FILENO);
status = dup2 (pipeHandle[PIPE_WRITE_HANDLE], STDOUT_FILENO);
if (status == -1)
{
cleanUp();
return false;
}
// unbuffered stdout
setvbuf (stdout, NULL, _IONBF, bufferSize);
streamReaderThread = new StreamReaderThread
(pipeHandle[PIPE_READ_HANDLE], buffer, bufferSize);
if (streamReaderThread == 0)
{
cleanUp();
return false;
}
// start the thread
streamReaderThread->start();
return true;
}
void StreamDirector::finishStdout()
{
char eof = static_cast<char>(EOF);
/* write termination char to thread */
(void)write (fileno(stdout), &eof, 1);
// wait until thread ends
if (streamReaderThread != 0)
{
streamReaderThread->wait();
}
cleanUp();
}
// END StreamDirector_Unix.cpp
Here's the code for Windows:
// BEGIN StreamDirector_Win32.cpp
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>
#include "StreamReaderThread.h"
#include "StreamDirector.h"
static HANDLE writePipeHandle, readPipeHandle;
static HANDLE oldStdoutHandle; // saves the old
standard out
//static HANDLE readerThreadHandle; // thread which
constantly reads from stdout
// until no more data
is available
static StreamReaderThread *streamReaderThread = 0;
static void cleanUp()
{
// close pipe
(void)::CloseHandle (readPipeHandle);
(void)::CloseHandle (writePipeHandle);
// reset stdout
(void)::SetStdHandle (STD_OUTPUT_HANDLE, oldStdoutHandle);
(void)::CloseHandle (oldStdoutHandle);
if (streamReaderThread != 0)
{
delete streamReaderThread;
streamReaderThread = 0;
}
}
bool StreamDirector::redirectStdout (char *buffer, const unsigned int
bufferSize)
{
int hConHandle = 0;
int status = 0;
long lStdHandle = 0;
FILE *fp = NULL;
// save stdout
oldStdoutHandle = ::GetStdHandle (STD_OUTPUT_HANDLE);
status = ::CreatePipe (&readPipeHandle, &writePipeHandle, NULL,
bufferSize);
if (status == 0)
{
cleanUp();
return false;
}
// redirect stdout, stdout is now written into the pipe
status = ::SetStdHandle (STD_OUTPUT_HANDLE, writePipeHandle);
if (status == 0)
{
cleanUp();
return false;
}
// redirect unbuffered stdout to the buffer - this cast produces a
warning
// but is okay, example taken from MSDev library
lStdHandle = reinterpret_cast<long>(GetStdHandle (STD_OUTPUT_HANDLE));
hConHandle = ::_open_osfhandle (lStdHandle, _O_TEXT);
fp = ::_fdopen (hConHandle, "w");
*stdout = *fp;
// unbuffered stdout
::setvbuf (stdout, NULL, _IONBF, bufferSize);
/*
because the process plays the role of producer and consumer, the
consumer part has to run into
a thread: if the producer writes more bytes into the pipe than
the size of its buffer, the
corresponding write function (e.g printf(), fprintf(stdout, ..),
write(fileno(stdout), ..) blocks
and the process ends in a deadlock. for prevent this situation,
the thread continuously reads
from the pipe as long as data is present.
*/
// this cast produces a warning
// but is okay, example taken from MSDev library
hConHandle = ::_open_osfhandle
(reinterpret_cast<long>(readPipeHandle), _O_TEXT);
streamReaderThread = new StreamReaderThread (hConHandle, buffer,
bufferSize);
if (streamReaderThread == 0)
{
cleanUp();
return false;
}
// start the thread
streamReaderThread->start();
return true;
}
void StreamDirector::finishStdout()
{
char eof = static_cast<char>(EOF);
/* write termination char to thread */
::write (fileno (stdout), &eof, 1);
// wait until thread ends
streamReaderThread->wait();
cleanUp();
}
The threaded (QThread) consumer looks like this on Unix:
void StreamReaderThread::run()
{
size_t nofRead = 0;
size_t totRead = 0;
char *ptr = m_buffer; // points to the next entry to be written
while (::ioctl (m_fd, FIONREAD, &nofRead) >= 0)
{
if (totRead + nofRead > m_bufferSize) // buffer overflow
break;
if (nofRead > 0)
{
::read (m_fd, ptr, nofRead);
totRead += nofRead;
ptr += nofRead;
if (((int)*(ptr-1) & 0x00FF) == (EOF & 0x00FF)) // EOF
(too for IBM)
break;
}
}
*(ptr-1) = 0;
}
And for Windows:
void StreamReaderThread::run()
{
int nofRead = 0;
int bufferPos = 0; // points to the next entry to be written
while (true)
{
nofRead = read (m_fd, &m_buffer[bufferPos], m_bufferSize -
nofRead);
if (nofRead > 0)
{
bufferPos += nofRead;
}
if ((nofRead == 0) || (nofRead == -1) || (m_buffer[bufferPos -
1] == static_cast<char>(EOF)))
{
if (bufferPos > 0)
{
m_buffer[bufferPos - 1] = '\0';
}
else
{
// read error, nothing read
m_buffer[0] = '\0';
}
// exit the thread
break;
}
}
}
m_fd, m_buffer and m_bufferSize are given as parameters to the thread.
The m_buffer must off course be large enough to hold all messages which
are expected on stdout - in our case it is (or was, since we do not use
this ugly code anymore) simply a fixed size array of char. You could
also use a QByteArray or a QTextStream or whatever which would
dynamically change its size.
Again, I'm not sure why the thread is really necessary - I got this code
from another developer and he claimed to have taken this example from
the MSDN or so. It worked, I did not ask questions ... ;)
Hope that gives you some inspirations ;)
Cheers, Oliver
--
[ signature omitted ]
Till Oliver Knoll wrote:
> Peter Hackett schrieb:
>> Hopefully this won't sound *too* much like Greek:
>> ...
>> The above is just a hint. Sorry I don't have some code handy.
>
> Hmm, and the above was not all that wrong - in fact we did it more or
> less like that (sorry, I thought with "pipe" you meant the '|' shell
> pipe or something - didn't remember that there was the pipe() function ;)
>
> In the meantime I have checked why we needed a thread (consumer) to
> read from the pipe as soon as there is something to read. This was the
> case on both Unix and Windows. I am not sure why a thread is needed at
> all, but oviously because you could end up in a deadlock if you had
> only one thread: when you write more than the pipe could store, then a
> successive write() would block forever.
>
> Anyway, here's the code, take it "as is" ("It's your fault when there
> is a fault" and all the other lawyerish disclaimers apply), for Unix:
>
> // BEGIN StreamDirector_Unix.cpp
>
> #include <unistd.h>
> #include <stdio.h>
>
> #include "StreamReaderThread.h"
> #include "StreamDirector.h"
>
> // some convenience defines, for readability
> #define PIPE_READ_HANDLE 0
> #define PIPE_WRITE_HANDLE 1
>
> static int oldStdout;
> static int pipeHandle[2];
> static StreamReaderThread *streamReaderThread = 0;
>
> static void cleanUp()
> {
> // close pipe
> (void)::close (pipeHandle[PIPE_READ_HANDLE]);
> (void)::close (pipeHandle[PIPE_WRITE_HANDLE]);
> // reset stdout
> (void)::dup2 (oldStdout, STDOUT_FILENO);
> (void)::close (oldStdout);
>
> if (streamReaderThread != 0)
> {
> delete streamReaderThread;
> streamReaderThread = 0;
> }
> }
>
> bool StreamDirector::redirectStdout (char *buffer, const unsigned int
> bufferSize)
> {
> int status;
>
> // save stdout
> oldStdout = ::dup (STDOUT_FILENO);
>
> // create a pipe for communication between license library and
> the application
> status = pipe (pipeHandle);
> if (status != 0)
> {
> cleanUp();
> return false;
> }
>
> // redirect stdout, stdout is now written into the pipe
> (void)close (STDOUT_FILENO);
> status = dup2 (pipeHandle[PIPE_WRITE_HANDLE], STDOUT_FILENO);
> if (status == -1)
> {
> cleanUp();
> return false;
> }
>
> // unbuffered stdout
> setvbuf (stdout, NULL, _IONBF, bufferSize);
>
> streamReaderThread = new StreamReaderThread
> (pipeHandle[PIPE_READ_HANDLE], buffer, bufferSize);
> if (streamReaderThread == 0)
> {
> cleanUp();
> return false;
> }
>
> // start the thread
> streamReaderThread->start();
>
> return true;
> }
>
> void StreamDirector::finishStdout()
> {
> char eof = static_cast<char>(EOF);
>
> /* write termination char to thread */
> (void)write (fileno(stdout), &eof, 1);
>
> // wait until thread ends
> if (streamReaderThread != 0)
> {
> streamReaderThread->wait();
> }
>
> cleanUp();
>
> }
>
> // END StreamDirector_Unix.cpp
>
>
>
> Here's the code for Windows:
>
> // BEGIN StreamDirector_Win32.cpp
>
> #include <windows.h>
> #include <stdio.h>
> #include <fcntl.h>
> #include <io.h>
> #include <iostream>
> #include <fstream>
>
> #include "StreamReaderThread.h"
> #include "StreamDirector.h"
>
> static HANDLE writePipeHandle, readPipeHandle;
> static HANDLE oldStdoutHandle; // saves the old
> standard out
> //static HANDLE readerThreadHandle; // thread which
> constantly reads from stdout
> // until no more data
> is available
> static StreamReaderThread *streamReaderThread = 0;
>
> static void cleanUp()
> {
> // close pipe
> (void)::CloseHandle (readPipeHandle);
> (void)::CloseHandle (writePipeHandle);
> // reset stdout
> (void)::SetStdHandle (STD_OUTPUT_HANDLE, oldStdoutHandle);
> (void)::CloseHandle (oldStdoutHandle);
>
> if (streamReaderThread != 0)
> {
> delete streamReaderThread;
> streamReaderThread = 0;
> }
> }
>
> bool StreamDirector::redirectStdout (char *buffer, const unsigned int
> bufferSize)
> {
> int hConHandle = 0;
> int status = 0;
> long lStdHandle = 0;
> FILE *fp = NULL;
>
> // save stdout
> oldStdoutHandle = ::GetStdHandle (STD_OUTPUT_HANDLE);
>
> status = ::CreatePipe (&readPipeHandle, &writePipeHandle, NULL,
> bufferSize);
>
> if (status == 0)
> {
> cleanUp();
> return false;
> }
>
> // redirect stdout, stdout is now written into the pipe
> status = ::SetStdHandle (STD_OUTPUT_HANDLE, writePipeHandle);
> if (status == 0)
> {
> cleanUp();
> return false;
> }
>
> // redirect unbuffered stdout to the buffer - this cast produces a
> warning
> // but is okay, example taken from MSDev library
> lStdHandle = reinterpret_cast<long>(GetStdHandle
> (STD_OUTPUT_HANDLE));
> hConHandle = ::_open_osfhandle (lStdHandle, _O_TEXT);
>
> fp = ::_fdopen (hConHandle, "w");
> *stdout = *fp;
>
> // unbuffered stdout
> ::setvbuf (stdout, NULL, _IONBF, bufferSize);
>
> /*
> because the process plays the role of producer and consumer, the
> consumer part has to run into
> a thread: if the producer writes more bytes into the pipe than
> the size of its buffer, the
> corresponding write function (e.g printf(), fprintf(stdout, ..),
> write(fileno(stdout), ..) blocks
> and the process ends in a deadlock. for prevent this situation,
> the thread continuously reads
> from the pipe as long as data is present.
> */
> // this cast produces a warning
> // but is okay, example taken from MSDev library
> hConHandle = ::_open_osfhandle
> (reinterpret_cast<long>(readPipeHandle), _O_TEXT);
> streamReaderThread = new StreamReaderThread (hConHandle, buffer,
> bufferSize);
> if (streamReaderThread == 0)
> {
> cleanUp();
> return false;
> }
>
> // start the thread
> streamReaderThread->start();
>
> return true;
> }
>
> void StreamDirector::finishStdout()
> {
> char eof = static_cast<char>(EOF);
>
> /* write termination char to thread */
> ::write (fileno (stdout), &eof, 1);
>
> // wait until thread ends
> streamReaderThread->wait();
>
> cleanUp();
>
> }
>
> The threaded (QThread) consumer looks like this on Unix:
>
> void StreamReaderThread::run()
> {
> size_t nofRead = 0;
> size_t totRead = 0;
> char *ptr = m_buffer; // points to the next entry to be written
>
> while (::ioctl (m_fd, FIONREAD, &nofRead) >= 0)
> {
> if (totRead + nofRead > m_bufferSize) // buffer overflow
> break;
>
> if (nofRead > 0)
> {
> ::read (m_fd, ptr, nofRead);
>
> totRead += nofRead;
> ptr += nofRead;
>
> if (((int)*(ptr-1) & 0x00FF) == (EOF & 0x00FF)) // EOF
> (too for IBM)
> break;
> }
> }
>
> *(ptr-1) = 0;
> }
>
> And for Windows:
>
>
> void StreamReaderThread::run()
> {
> int nofRead = 0;
> int bufferPos = 0; // points to the next entry to be written
>
> while (true)
> {
> nofRead = read (m_fd, &m_buffer[bufferPos], m_bufferSize -
> nofRead);
> if (nofRead > 0)
> {
> bufferPos += nofRead;
> }
> if ((nofRead == 0) || (nofRead == -1) || (m_buffer[bufferPos -
> 1] == static_cast<char>(EOF)))
> {
> if (bufferPos > 0)
> {
> m_buffer[bufferPos - 1] = '\0';
> }
> else
> {
> // read error, nothing read
> m_buffer[0] = '\0';
> }
> // exit the thread
> break;
> }
> }
>
> }
>
> m_fd, m_buffer and m_bufferSize are given as parameters to the thread.
> The m_buffer must off course be large enough to hold all messages
> which are expected on stdout - in our case it is (or was, since we do
> not use this ugly code anymore) simply a fixed size array of char. You
> could also use a QByteArray or a QTextStream or whatever which would
> dynamically change its size.
>
> Again, I'm not sure why the thread is really necessary - I got this
> code from another developer and he claimed to have taken this example
> from the MSDN or so. It worked, I did not ask questions ... ;)
>
>
> Hope that gives you some inspirations ;)
>
> Cheers, Oliver
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
Thanks,
It will probably take some time for me to understand the code and
specially how to use it , but, I'm sure I will get inspired in the end....
Thank you very much,
Marie
--
[ signature omitted ]
Marie-Christine Vallet schrieb:
> Till Oliver Knoll wrote:
>> ...
>> Anyway, here's the code, take it "as is" ("It's your fault when there
>> is a fault" and all the other lawyerish disclaimers apply), for Unix:
>> [snip code]
> Thanks,
> It will probably take some time for me to understand the code and
> specially how to use it , but, I'm sure I will get inspired in the end....
Well, the usage is pretty much straight forward: somewhere before you
start calling your library functions (which call printf()) you simply put:
char myBuffer[1024]; // hopefully large enough ;)
unsigned int bufferSize = 1024;
if (StreamDirector::redirectStdout (myBuffer, bufferSize) == true)
{
// success
...
}
else {
// error handling (pipe could not created, dup2 failed etc.)
...
}
Note that the function redirectStdout() is declared static in the *.h
(which I did not provide, but it's easily derived).
The code itself I admit is a mess... ;)
Cheers, Oliver
--
[ signature omitted ]
Till Oliver Knoll wrote: > Peter Hackett schrieb: >> Hopefully this won't sound *too* much like Greek: >> ... >> The above is just a hint. Sorry I don't have some code handy. ... >> In the meantime I have checked why we needed a thread (consumer) to >> read from the pipe as soon as there is something to read. This was >> the case on both Unix and Windows. I am not sure why a thread is >> needed at all, but oviously because you could end up in a deadlock if >> you had only one thread: when you write more than the pipe could >> store, then a successive write() would block forever. ... Yes. The pipe has a finite size. If you didn't have a separate thread reading from the pipe, the library could fill up the pipe and would block and "no one" would ever read from it. Pipes have traditionally been used to set up communications between parent processes and there children. (pipe(2) is used to implement "|" in the shells.) -- [ signature omitted ]