Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!decvax!decwrl!ucbvax!brspyr1.UUCP!sam From: sam@brspyr1.UUCP.UUCP Newsgroups: mod.computers.vax Subject: Re: VAX C problem (?) Message-ID: <8607161700.AA04387@brspyr1.UUCP> Date: Wed, 16-Jul-86 13:00:39 EDT Article-I.D.: brspyr1.8607161700.AA04387 Posted: Wed Jul 16 13:00:39 1986 Date-Received: Fri, 18-Jul-86 18:32:01 EDT References: <8607031156.AA07330@ucbvax.Berkeley.EDU> Sender: daemon@ucbvax.BERKELEY.EDU Organization: The ARPA Internet Lines: 273 Approved: info-vax@sri-kl.arpa > Mike Hickey writes ... > > ... When I was working with the CURSES package, I found that > getch() wasn't breaking on a character. Instead, it would block until > a RETURN was hit... > Doug Gwyn writes ... > > ... This behavior is permitted only in raw > (non-canonicalizing) mode, which is not supposed to be enabled by > default. Sounds like VAX-C ver 2.2 is doing this right. Take a look in the VAX-11 C manual. Hmmm ... CRMODE(): provided for link compatibility only, no function performed. Hmmm ... RAW(): same story. So what is a Unix hack supposed to do? Grab those dozen orange binders and ... We discovered that the following reasonably simple routines emulate grabbing a single character off the VMS terminal, similar to UNIX raw mode. Efficiency? No promises here, but they work. For good measure, I threw in a VMS "getpass()" (now why doesn't the C RTL have one of these?) /* ** The following code segment is likely copyrighted by my employer, but ** since I originally wrote it and hacked it before posting it and you ** WILL hack it more before even THINKING about using it, well ... ** ** Okay, okay, whatever you do don't make any money on it, huh? But ** then again, what are we doing reading this net and asking these ** question if we didn't (ultimately) want to make money for someone or ** something. Hmmmmm. What a dilemma. ** ** Okay, you and me, we'll just pretend this should have been published ** in one of those twenty or so orange books DEC calls documentation, ** right? And anyway, it is all in there if you look long enough. So it ** must be _almost_ PD. ** ** No flames, dammit. I was only trying to help. */ #include #include #include #include #define VMS$IOKFLGS (IO$_READVBLK | IO$M_NOECHO | IO$M_NOFILTR) #define VMS$IOPFLGS (IO$_READVBLK | IO$M_NOECHO ) #define VMS$INTR '\003' /* ^C */ #define VMS$TTYDEV "TT" #define MAX$PASSWD 8 static int kb_chan; /* hold keyboard channel here */ /* ** Assigns 'kb_chan' to the terminal I/O channel for later use. The ** system logical "TT" is used as the terminal device. */ void initialize() /* call me once at program start */ { static $DESCRIPTOR(name,VMS$TTYDEV); if (sys$assign(&name,&kb_chan,0,0) != SS$_NORMAL) perror("sys$assign(TT) failed"); return; } /* ** This subroutine performs the opposite of initialize(): it deassigns ** the channel. This should be done before the application is exited. */ void de_initialize() /* call me once at program end */ { if (sys$dassgn(kb_chan) != SS$_NORMAL) perror("sys$dassgn(TT) failed"); return; } /* ** This subroutine recovers a single byte from the user's keyboard. ** This subroutine may not be used unless initialize() has been called, ** but no enforcement of this is made. ** ** Returns one of: ** (char) - byte retrieved ** NULL - interrupt encountered */ char get_key_stroke() { int i; /* for catching return value */ char c; /* place for char */ /* sys$qiow() ignores EOF's and does not modify 'c' if interrupt. */ /* better handling here is probably more than possible; VMS$IOKFLGS */ /* (defined at top) has impact on special char handling. */ do { c = VMS$INTR; i = sys$qiow(0,kb_chan,VMS$IOKFLGS,0,0,0,&c,1,0,0,0,0); } while (i != SS$_NORMAL); return(c == VMS$INTR ? NULL : c); } /* ** As in getpass(3), basically. Very minimum; probably should check for ** EOF or INTR. Dependent on a prior call to initialize(). */ char *getpass(p) char *p; { static char passwd[MAX$PASSWD+1]; fputs(p,stdout); fflush(stdout); *passwd = NULL; sys$qiow(0,kb_chan,VMS$IOPFLGS,0,0,0,passwd,MAX$PASSWD,0,0,0,0); for (p = passwd; p - passwd < MAX$PASSWD; p++) if (*p == '\n' || *p == '\r' || *p == NULL) break; *p = NULL; return(passwd); } From postnews Wed Jul 16 01:02:28 1986 Subject: Re: getch for VAX C (was: VAX C problem) Newsgroups: mod.computers.vax To: info-vax@sri-kl.arpa References: <8607031156.AA07330@ucbvax.Berkeley.EDU> > Mike Hickey writes ... > > ... When I was working with the CURSES package, I found that > getch() wasn't breaking on a character. Instead, it would block until > a RETURN was hit... > Doug Gwyn writes ... > > ... This behavior is permitted only in raw > (non-canonicalizing) mode, which is not supposed to be enabled by > default. Sounds like VAX-C ver 2.2 is doing this right. Take a look in the VAX-11 C manual. Hmmm ... CRMODE(): provided for link compatibility only, no function performed. Hmmm ... RAW(): same story. So what is a Unix hack supposed to do? Grab those dozen orange binders and ... We discovered that the following reasonably simple routines emulate grabbing a single character off the VMS terminal, similar to UNIX raw mode. Efficiency? No promises here, but they work. For good measure, I threw in a VMS "getpass()" (now why doesn't the C RTL have one of these?) /* ** The following code segment is likely copyrighted by my employer, but ** since I originally wrote it and hacked it before posting it and you ** WILL hack it more before even THINKING about using it, well ... ** ** Okay, okay, whatever you do don't make any money on it, huh? But ** then again, what are we doing reading this net and asking these ** question if we didn't (ultimately) want to make money for someone or ** something. Hmmmmm. What a dilemma. ** ** Okay, you and me, we'll just pretend this should have been published ** in one of those twenty or so orange books DEC calls documentation, ** right? And anyway, it is all in there if you look long enough. So it ** must be _almost_ PD. ** ** No flames, dammit. I was only trying to help. */ #include #include #include #include #define VMS$IOKFLGS (IO$_READVBLK | IO$M_NOECHO | IO$M_NOFILTR) #define VMS$IOPFLGS (IO$_READVBLK | IO$M_NOECHO ) #define VMS$INTR '\003' /* ^C */ #define VMS$TTYDEV "TT" #define MAX$PASSWD 8 static int kb_chan; /* hold keyboard channel here */ /* ** Assigns 'kb_chan' to the terminal I/O channel for later use. The ** system logical "TT" is used as the terminal device. */ void initialize() /* call me once at program start */ { static $DESCRIPTOR(name,VMS$TTYDEV); if (sys$assign(&name,&kb_chan,0,0) != SS$_NORMAL) perror("sys$assign(TT) failed"); return; } /* ** This subroutine performs the opposite of initialize(): it deassigns ** the channel. This should be done before the application is exited. */ void de_initialize() /* call me once at program end */ { if (sys$dassgn(kb_chan) != SS$_NORMAL) perror("sys$dassgn(TT) failed"); return; } /* ** This subroutine recovers a single byte from the user's keyboard. ** This subroutine may not be used unless initialize() has been called, ** but no enforcement of this is made. ** ** Returns one of: ** (char) - byte retrieved ** NULL - interrupt encountered */ char get_key_stroke() { int i; /* for catching return value */ char c; /* place for char */ /* sys$qiow() ignores EOF's and does not modify 'c' if interrupt. */ /* better handling here is probably more than possible; VMS$IOKFLGS */ /* (defined at top) has impact on special char handling. */ do { c = VMS$INTR; i = sys$qiow(0,kb_chan,VMS$IOKFLGS,0,0,0,&c,1,0,0,0,0); } while (i != SS$_NORMAL); return(c == VMS$INTR ? NULL : c); } /* ** As in getpass(3), basically. Very minimum; probably should check for ** EOF or INTR. Dependent on a prior call to initialize(). */ char *getpass(p) char *p; { static char passwd[MAX$PASSWD+1]; fputs(p,stdout); fflush(stdout); *passwd = NULL; sys$qiow(0,kb_chan,VMS$IOPFLGS,0,0,0,passwd,MAX$PASSWD,0,0,0,0); for (p = passwd; p - passwd < MAX$PASSWD; p++) if (*p == '\n' || *p == '\r' || *p == NULL) break; *p = NULL; return(passwd); }