On Thu, Aug 26, 2010 at 11:01 AM, Hrvoje Niksic <[email protected]>wrote:
>
> The good news is that libraries shouldn't require a terminal for stdout
> because then they wouldn't work with stdout being redirected to a file
> (highly unlikely).
>
> The bad news is that this is harder to do correctly than it sounds. If you
> connect stdout to a pipe, then a thread (or a subprocess) should exist to
> collect output from the pipe, or the program deadlocks whenever a library
> prints a chunk of output larger than the pipe buffer.
>
> The other bad news is that the dup2/pipe solution is very Unix-specific.
> It is not clear if this is a problem to Richard.
>
Hi guys,
Thanks for the feedback, I'm now sorted.
You are correct, the libraries don't expect a terminal, no problem there.
The actual program I intend to use this in is a background process where the
actual processing executes in a separate thread while the main thread sits
in the main loop. With the watch on the read-end of the pipe, the callback
is fired and executes within the main loop, while all writing occurs on the
execution thread; i.e, backwards from what you suggest, but both processing
entities (write to, read from) are separate and so can't collide with or
block each other (he says, crossing fingers furiously).
I re-post the modified code, very pared down, using GIOChannel watching that
now works as expected/required.
thanks again,
richard
==== BEGIN CODE =====
*// save to:* io.c
*// compile as:* gcc io.c `pkg-config --cflags --libs glib-2.0`
#include <glib.h>
> #include <stdio.h>
> #include <string.h>
>
enum {READFD, WRITEFD, TTLPIPEFDS};
> int fd[TTLPIPEFDS];
>
gboolean my_callback(GIOChannel *source, GIOCondition condition, gpointer
data)
> {
> GMainLoop *loop = (GMainLoop *) data;
>
switch (condition)
> {
> case G_IO_IN:
{
gchar buf2[100];
> memset(buf2, 0, sizeof(buf2));
read(fd[READFD], buf2, sizeof(buf2)); // read the data from the
read-end of the pipe
> if (buf2[0])
> { // output to text file and to stderr
> FILE *fp = fopen("/tmp/test.out", "w+");
> fprintf(fp, "%s", buf2);
> fclose(fp);
> fprintf(stderr, "written to file: '%s'\n", buf2);
> }
g_main_loop_quit(loop);
g_io_channel_shutdown(source,TRUE,NULL);
}
> break;
> }
> return FALSE;
> }
>
gboolean idle_function(gpointer nil)
> {
> printf("printf() test" );
> fflush(stdout);
> return FALSE; // remove
> }
>
int main()
> {
> GMainLoop *loop = g_main_loop_new(NULL,FALSE);
> GIOChannel *channel;
>
if (pipe(fd) < 0) return(-1); // make a new
pipe
> if (dup2(fd[WRITEFD], fileno(stdout)) < 0) return(-1); // copy
stdout to write-end
> close(fd[WRITEFD]);
>
> g_idle_add((GSourceFunc) idle_function, NULL); // write message to
stdout
>
channel = g_io_channel_unix_new(fd[READFD]); // watch read-end of pipe
> g_io_add_watch(channel, G_IO_IN,(GIOFunc) my_callback, loop);
>
g_main_loop_run(loop);
>
> return 0;
}
==== END CODE =====
_______________________________________________
gtk-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtk-list