[Vala] [Genie] How to do non-blocking i/o from stdin



Hi guys,

I'm somewhat new to the Genie language and also to Glib. I'm trying to do non-blocking i/o from stdin. In my program stdin will come directly from the keyboard or through a pipe. I created the following class and, on Windows, it immediately crashes when instantiated. The Windows pop-up error indicates 'ntdll.dll' as the source of the crash. I'm using Vala 0.12.0, WindowsXT64 Pro, and stdin is coming from the keyboard. Help!

If I am going about this all wrong, please feel free to criticize my current non-working implementation! ;-)

Thanks,
Ron

=======================
[indent=4]
uses
    GLib
    Posix  // Note to myself: requires '--pkg=posix' in build

const INPUT_BUF_SIZE : int = 254

//______________________________________________________________________________
// Input class
//
//    get user input from stdin (non-blocking) using IOChannel
//
//    intended usage:
//  var input = new Input
//  if ( input.is_ready() )
//      var str = input.get_string()
//      // process string
// code modeled on the following URL:
// http://code.valaide.org/content/snippet-read-inputevent-structs-devinputevent-using-iochannels
//______________________________________________________________________________
class Input : Object
    prop _iochan : IOChannel
    prop _buf  : array of char[]
    prop _length : size_t
    prop _status : GLib.IOStatus

    init
        _buf = new array of char[INPUT_BUF_SIZE + 1]
        clear()
        _iochan = new IOChannel.win32_new_fd(0)  // stdin channel
if ( !(_iochan.add_watch(IOCondition.IN | IOCondition.HUP, _readline) != 0) )
            print "Cannot add watch on IOChannel\n"
        print "not crashed yet..."  // this line prints

    def _readline(io:IOChannel , condition:IOCondition) : bool
        print "crashed before this...\n"  // this line does not print
        if ( (condition & IOCondition.HUP) == IOCondition.HUP )
            print("Broken pipe\n")
            return false
        else if ( (condition & IOCondition.IN) == IOCondition.IN )
            var fd = io.unix_get_fd()  // docs say it works in Windows too
            _length = Posix.read(fd, (void *)_buf, INPUT_BUF_SIZE + 1)
            if ( _length < 0 )
                print "Cannot read stdin IOChannel\n"
                return false
        return true

    def clear ()
        _buf[0] = '\0'
        _length = 0
        _status = GLib.IOStatus.NORMAL

    def is_ready() : bool
        return ( _length > 0 )

    def get_string() : string
        var str = ""
        if ( _length > 0 && _status == GLib.IOStatus.NORMAL )
            for ch in _buf
if ( !(ch == '\r' || ch == '\n') ) // don't copy terminating 'enter'
                    str += ch.to_string()
        return str

//______________________________________________________________________________
init
    input = new Input()  // crash!
    print "Didn't crash!\n"  // this line does not print




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