Re: The right way to get the ouput from a pipe into a widget



El mar, 10-12-2002 a las 20:10, Havoc Pennington escribió:
On Tue, Dec 10, 2002 at 07:21:54PM -0300, German Poo Caaman~o wrote:

I'm trying to connect the ouput from programs like ping and
traceroute and show its results into some GTK widgets.  
So, I use pipe, fork and exec.

Use g_spawn_async_with_pipes() instead, it'll immediately make this a
lot simpler.

Really.  Thanks for the hint.

I'd appreaciatte any hint or idea about what I missing,
or if my thought are right or wrong.

What you want to do is:

 - create the child process with g_spawn_async_with_pipes()
   creating a pipe on the child's stdout/stderr
 - use g_io_add_watch() to add a callback to be invoked 
   when there is input on the pipe (G_IO_IN)
 - when there's input, do a single call to read()
   and write the data that you read to the text view. 
   Don't read() twice, or you may block. (Unless you set the 
   pipe nonblocking)
 - when you get G_IO_HUP or G_IO_ERR passed to your IO watch 
   callback, the child process will have exited, so you want 
   to close your end of the pipe, and remove the IO watch.

Thanks a lot.  It works quite fine right now.

The snippet is the following, may be useful for someone else
(only the last statement is missing, yet)


if (g_spawn_async_with_pipes (dir, argv, NULL,
                      G_SPAWN_FILE_AND_ARGV_ZERO,
                      NULL,
                      NULL,
                      &child_pid, NULL, &pout, &perr,
                      &err)) 
{
        channel = g_io_channel_unix_new (pout);
        g_io_add_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR |
                G_IO_NVAL, io_dialog, buffer);
                g_io_channel_unref (channel);
                
        channel = g_io_channel_unix_new (perr);
        g_io_add_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR |
                G_IO_NVAL, io_dialog, buffer);
        g_io_channel_unref (channel);
} else {
        gtk_text_buffer_insert_at_cursor (
            GTK_TEXT_BUFFER (buffer), err->message, 
            strlen (err->message));
            /*g_warning ("Error: %s\n", err->message);*/
            g_error_free (err);
}

static gboolean
io_dialog (GIOChannel * channel, GIOCondition condition, gpointer data)
{
        gchar *text, *text_utf8;
        gint len;
        gssize bytes_written;

        g_return_val_if_fail (channel != NULL, FALSE);
        g_return_val_if_fail (data != NULL, FALSE);
        
        if (condition & G_IO_IN) {
                g_io_channel_read_line (channel, &text, &len, 
                        NULL, NULL);

                text_utf8 = g_locale_to_utf8 (text, len,
                        NULL, &bytes_written, NULL);

                gtk_text_buffer_insert_at_cursor
                    (GTK_TEXT_BUFFER (data), text_utf8, bytes_written);
                g_free (text);
                g_free (text_utf8);
                return TRUE;
        }
        return FALSE;
}

-- 
German Poo Caaman~o
mailto:gpoo ubiobio cl
http://www.ubiobio.cl/~gpoo/chilelindo.html




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]