Coding a console program frontend



Hello,

I'm new to GTK+ programming.
I've a console program in C, and I need to create a simple frontent to it.
The frontend will show the progress and information about the state of the
console program.

I realise that I can pass the data using pipes, but is there a better
alternative?

Now, for testing the data transfer using a pipe, I've been hacking on a
simple example:

#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <glib.h>

static void createGUI( gint *parentToChild );
static gboolean readMessage( GIOChannel *channel, GIOCondition condition,
GtkLabel *label );
static void consoleProgram( gint *parentToChild );

static void createGUI( gint *parentToChild )
{
    GtkWidget *window, *label;
        GIOChannel *in;

        window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
        label = gtk_label_new( NULL );

        gtk_container_add( GTK_CONTAINER( window ), label );
        gtk_container_set_border_width( GTK_CONTAINER( window ), 5 );
        gtk_widget_set_size_request( window, 200, 100 );

        gtk_widget_show_all( window );

        /* Close the unnecessary pipe */
        close( parentToChild[1] );

        /* Create a read channels */
        if ( ( in = g_io_channel_unix_new( parentToChild[0] ) ) == NULL )
                g_error( "error: the channel could not be created.\n" );

        /* Watch the read channel for changes */
        if ( !g_io_add_watch( in, G_IO_IN | G_IO_HUP,
             ( GIOFunc ) readMessage, ( gpointer ) label ) )
                g_error( "error: Read watch could not be added.\n" );

        gtk_window_set_title( GTK_WINDOW( window ), "Counter GUI" );
}

static gboolean readMessage( GIOChannel *channel, GIOCondition condition,
GtkLabel *label )
{
        gchar *message;
        gsize length;

        /* The pipe has died */
        if ( condition & G_IO_HUP )
                g_error( "error: The pipe has died.\n" );

        printf( "BEFORE READ LINE\n" );

        /* Read the data from pipe. */
        if ( g_io_channel_read_line( channel, &message, &length, NULL, NULL )
== G_IO_STATUS_ERROR )
                g_error ( "error: The message could not be read.\n" );

        printf( "AFTER READ LINE\n" );

        message[ length - 1 ] = 0;
        gtk_label_set_text( label, message );

        return TRUE;
}

static void consoleProgram( gint *parentToChild )
{
    close( parentToChild[0] );

    GIOChannel *out = g_io_channel_unix_new( parentToChild[1] );

    if ( out == NULL )
        g_error( "error: output channel could not be created.\n" );


    int count;
    gchar *msg[5] = { "message1", "message2", "message3", "message4",
"message5"
};

    for ( count = 0; count < 5; ++count )
    {
        fprintf( stderr, "%s\n", msg[count] );
        fflush( stderr );

        gsize length = 0;

        /* Send message to child. */
        if ( g_io_channel_write_chars( out, msg[count], -1, &length, NULL )
== G_IO_STATUS_ERROR )
            g_error( "error: The changes could not be written to the
pipe!\n" );

        fprintf( stderr, "Bytes writted = %d\n", length );

        g_io_channel_flush( out, NULL );

        sleep( 5 );
    }
}

int main( int argc, char **argv )
{
    gint parentToChild[2], pid;

    if ( pipe( parentToChild ) < 0 )
    {
        fprintf( stderr, "error: %s\n", g_strerror( errno ) );
        exit( 1 );
    }

    pid = fork();

    switch ( pid )
    {
        case -1:
            g_error( "error: %s\n", g_strerror( errno ) );
            exit( 1 );

        case 0: // GUI
            gtk_init( &argc, &argv );
            createGUI( parentToChild );
            gtk_main();
            break;

        default: // Console
            consoleProgram( parentToChild );
    }

    return 0;
}

However the child proccess (the GUI) when tries to read data from the pipe
it hangs. If you run this program you can see that the printf( "BEFORE READ
LINE\n" ) is printed but the printf( "AFTER READ LINE\n" ) is not..

What I'm doing wrong?


Thanks,

Pedro Saraiva



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