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

Reply via email to