Re: gdk_input_add() and GdkInputCondition mapping



On Mon, 23 Apr 2001, Emil Ong wrote:

Hi,

I'm working on an application that creates a display based on input from
standard in.  I'm using gdk_input_add() to get the input from standard in,
but I'm having a problem when piping to my application: when the left hand
side of the pipe closes its standard out (usually on exit), my handler
continues to be called.
<...>

I'm not absolutely certain about this, because I don't have time to test
and check it, but the gdk_input_add() facility is behaving similarly to
select(): it will tell you the file descriptor is readable when it is
closed.  The correct way to handle this is to read() straight away (the
poll() is not achieving anything).  The read() call returns 0 for EOF
if the file descriptor was closed.  I've modified your example below.

void handle_input(gpointer data, gint source, GdkInputCondition condition)
{
    char buf[1024];
    size_t rv;

  do_read:
    rv = read(source, buf, 1024);
    if(rv == 0) {
        /* The remote end closed the connection */
        /* Remove your callback and perform any necessary cleanup */
    }
    else {
        printf(buf);
    }
}

It is also worth switching stdin to non-blocking mode, to avoid read()
blocking (and hanging the GUI) when there is actually no data ready
(this can still happen even if select() or similar reported data being
there).  Something like

#include <fcntl.h>

int flags;

...

flags = fcntl(skt, F_GETFL, 0);
if(flags == -1) {
    /* Error */
}

flags |= O_NONBLOCK;

if(fcntl(skt, F_SETFL, flags) == -1) {
    /* Error */
}

Should do it.  If you do this, you'll need a little extra error handling
on the read() call (I've added the EINTR check for good measure):

if(rv == -1) {
    switch(errno) {
    case EAGAIN:
        /* We attempted a read from stdin but there was no data there */
        return;
    case EINTR:
        /* System call was interrupted by a UNIX signal.  Usually I would
           use goto() to re-attempt the read() */
        goto do_read;
    default:
        /* Display an error message */
    }
}

Jonathan






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