/*#define TESTING */ /* * k b i n . c * * Read tt: one byte at a time without echo, with or without waiting if there * is no typeahead. * * Synopsis * * int * _kbin(wait) * int wait; * * int * kbin() * * int * kbinr_() * * Description * * Returns the next character. Returns EOF on error, or if there is no * typeahead and "no wait" was requested. * * _kbin(wait) waits if wait is TRUE, returns EOF if there is no * typeahead and wait is FALSE. kbin() is the same as _kbin(TRUE); * kbinr() is the same as _kbin(FALSE). * * Note -- this routine does not prevent CTRL/C or CTRL/Y aborts * from occurring. * * Revision History * 0.0 19-Jun-79 SB Original version due to Stoney Ballard. * 0.1 19-Oct-79 MM "Munged". * 0.2 31-Aug-81 MM Name changed to kbin(). * 1.0 ??-???-?? MM Made part of VAXLIB. * 1.1 22-Jul-83 JSL Old kbin() ==> _kbin() and gets the "wait" argument; * kbin(), kbinr() in terms of _kbin(). */ #include #include #include #include #define FALSE 0 #define TRUE 1 #define EOS 0 #define BUFFLEN 10 /* Size of typeahead buffer */ /* * Local static database: */ static $DESCRIPTOR(inpdev, "TT"); /* Terminal to use for input */ static long termset[2] = { 0, 0 }; /* No terminator */ /* * Local variables */ static long ichan; /* Gets channel number for TT: */ static char opened = FALSE; /* TRUE when opened */ static char ibuff[BUFFLEN]; /* Input buffer -- one byte */ static char *buffptr = ibuff; /* For typeahead processing */ static char *buffend = ibuff; /* For typeahead processing */ int _kbin(wait) int wait; /* * Get one byte without echoing, with or without waiting. */ { register int errorcode; struct IOSTAB { short int status; short int offset_to_terminator; short int terminator; short int terminator_size; } iostab; if (buffptr < buffend) return (*buffptr++ & 0377); /* Empty our typeahead buffer */ if (!opened) { if ((errorcode = sys$assign(&inpdev, &ichan, 0, 0)) != SS$_NORMAL) { fprintf(stderr, "KBIN assign failed. code = %X\n", errorcode); exit(errorcode); } else opened = TRUE; } /* * See if there's something in the system typeahead buffer * Read up to BUFLEN bytes with "zero" timeout. This will return * whatever's in the timeout buffer. The iostab.offset_to_terminator * and iostab.terminator_size will yield the number of bytes read. */ errorcode = sys$qiow(1, /* Event flag */ ichan, /* Input channel */ IO$_READLBLK | IO$M_NOECHO | IO$M_NOFILTR | IO$M_TIMED, /* Timed read with zero wait */ &iostab, /* I/O status block */ NULL, /* AST block (none) */ 0, /* AST parameter */ &ibuff, /* P1 - input buffer */ BUFFLEN, /* P2 - buffer length */ 0, /* P3 - ignored (timeout) */ &termset, /* P4 - terminator set */ NULL, /* P5 - ignored (prompt buffer) */ 0); /* P6 - ignored (prompt size) */ #ifdef TESTING printf("timed read code = %X, ", errorcode); printf("status = %d, offset = %d, terminator = %d, size = %d\n", iostab.status, iostab.offset_to_terminator, iostab.terminator, iostab.terminator_size); #endif buffend = &ibuff[iostab.offset_to_terminator + iostab.terminator_size]; if (buffend > ibuff) { buffptr = &ibuff[1]; /* Setup typeahead pointer and */ return (ibuff[0] & 0377); /* Return the first character */ } /* * Nothing in typeahead buffer, nothing read. If the user doesn't * want us to wait, just return EOF; else read one character. */ if (!wait) return (EOF); errorcode = sys$qiow(1, /* Event flag */ ichan, /* Input channel */ IO$_READLBLK | IO$M_NOECHO | IO$M_NOFILTR, /* Read, no echo, no translate */ &iostab, /* I/O status block */ NULL, /* AST block (none) */ 0, /* AST parameter */ &ibuff, /* P1 - input buffer */ 1, /* P2 - buffer length */ 0, /* P3 - ignored (timeout) */ &termset, /* P4 - terminator set */ NULL, /* P5 - ignored (prompt buffer) */ 0); /* P6 - ignored (prompt size) */ #ifdef TESTING printf("read one byte, code = %X, ", errorcode); printf("status = %d, offset = %d, terminator = %d, size = %d\n", iostab.status, iostab.offset_to_terminator, iostab.terminator, iostab.terminator_size); #endif if (errorcode == SS$_NORMAL) { return (ibuff[0] & 0377); } else { return (EOF); } } int kbin() /* * Get one byte without echoing, with waiting. */ { return (_kbin(TRUE)); } int kbinr() /* * Get one byte without echoing, without waiting. */ { return (_kbin(FALSE)); } #ifdef TESTING main() { register int datum; printf("kbin() testing - CTRL/Z to exit\n"); while ((datum = kbin()) != EOF) { printf("%03o '", datum); dumpc(datum); printf("'\n"); if (datum == ('Z' - 0100)) break; } printf("EOF\n"); printf("kbinr() testing - CTRL/Z to exit\n"); while (1) { datum = kbinr(); if (datum == EOF) { printf("EOF - sleeping..."); sleep(2); printf("\n"); continue; } printf("%03o '", datum); dumpc(datum); printf("'\n"); if (datum == ('Z' - 0100)) break; } printf("EOF\n"); } dumpc(datum) int datum; /* * Dump a character readably */ { datum &= 0377; if ((datum & 0200) != 0) { putchar('~'); datum &= 0177; } if (datum < ' ') { putchar('^'); putchar(datum + '@'); } else if (datum > 0176) { printf(""); } else putchar(datum); } #endif