/* acf3:comp.os.vms / baxter@xmws.uucp / 2:33 am Dec 22, 1990 */ In article <1990Nov20.184509.3252@objy.com>, ricks@prefect.objy.com (Rick L. Spickelmier) writes: > I'm trying to get XtAddInput to work on VMS with the input > coming from a pipe connected to a subprocess (created with stuff deleted > I just hang... Does anybody use XtAddInput under VMS? Yes > Is it with a subprocess via pipes? No I did a presentation on this at DECUS six months ago... get ahold of the VAX Sig session notes from someone for the New Orleans Decus last spring. You CANN'T DO IT with PIPES... Which are ONLY SIMULATED on VMS. You need control of read completion from the mailbox that the pipe really is... You _MUST_ do this in a VMS specific way, i.e. You MUST use the VMS QIO Mechansim and you must do it asynchonously... so that XtMainEventLoop will still have control... The source argument to XtAddInput is really a VMS event flag number... THIS is the key!!!!! In your QIO read completion ast routine you must Set the event flag when you have read something... This causes Xt to calback your XtInputCallback routine... which can then process the data is "real" time as apposed to at AST level. NB: Xt on VMS is NOT AST reentrant In the simplest case: (where you let the OS buffer the IO, and you do not do internal io buffering) your Application Q's a read, and returns to the main eventloop. The AST read completion routine reads the data and sets the efn passed to XtAddInput. Xt then calls the XtInputCallback routine. The XtInputCallback routine should clear the efn. When the data is processed, it should Q the next read. The code can be ISOLATED to a small IO module that is VMS specific. Read the IO users guide on using mailboxes... this will tell you how to setup the interprocess communication using mailboxes... (which is what a pipe really is on VMS) Code fragments for reading follow... its not complete but you should get the idea... #define cleared_bit_was_clear( bp, flgs ) ( _BBCCI( (bp), (flgs) )) #define set_bit_was_set( bp, flgs ) ( _BBSSI( (bp), (flgs) )) static long int read_ast ( IOBuffer * bufferP ) { long int ret_stat; sys$synch( read_QIO_efn, &bufferP->iosb ); sys$setef ( Xt_read_efn ); put_on_Q_tail( bufferP, full_Q, ret_stat ); cleared_bit_was_clear( ReadIsPending, &IO_flags ); } long int StartReadIO() { long int ret_stat; long int io_function; IOBuffer * bufferP; if ( set_bit_was_set( ReadIsPending, &IO_flags ) ) return 0; else { GetIOBuffer( &bufferP ); ret_stat = sys$qio ( read_QIO_efn ,IO_channel ,IO$_READVBLK ,&bufferP->iosb ,&read_ast /* ast routine.r */ ,bufferP /* astprm.v */ ,bufferP->dataP ,MaximumBufferLength ,0 ,0 ,0 ,0 ); _ExitIfOSError( ret_stat, "SYS$QIO in IO:read_IO_started" ); } return 1; } #undef ROUTINE XtInputCallbackProc XtInputHandler( caddr_t userdata, int * Source, XtInputId * id ) /* we ignore the arguements, * this routine does the work in real time not ast time */ { int ret_stat; char * cp; IOBuffer * bufferP; ret_stat = sys$clref ( Xt_read_efn ); ret_stat = remove_from_Q_head( full_Q, bufferP ); switch ( ret_stat ) { case Q_INTERLOCK_FAILED : ExitWithMessage ( "Q_INTERLOCK_FAILED in XtInputHandler" ); case Q_WAS_EMPTY : return False; case REMQ_WERE_MORE_ENTRIES : sys$setef ( Xt_read_efn ); /* call me again */ } _ExitIfOSError( bufferP->iosb.condition ,"Bad iosb.condition in XtInputCallbackProc" ); /* NOW extract data from buffer and process it */ (*theProtocolDecodeProc)( bufferP->dataP, bufferP->iosb.transfer_cnt ); /* now setup the next IO */ put_on_Q_tail( bufferP, free_Q, ret_stat ); StartReadIO(); return False; } /* ---------- */