[comp.os.vms] An Inkey Function for DCL

JSOTTILE@LOYVAX.BITNET (01/05/88)

I have been reading a few people's questions about an 'inkey' type function
for DCL.  Well, here it is.  It is too slow, but it's not too fast either.

Please excuse the poor programming in it, it was done when I first learned
C.  I'd appreciate comments and/or suggestions (constructive criticism, please).

I assume no responsibility for the performance of this program (and neither
does my employer).  If it has bugs on your system, send me mail or try
to fix it (tell me what you did to fix it too).

- John Sottile
Student Systems Programmer
(JSOTTILE@LOYVAX.BITNET)
Loyola College in Maryland
(FidoNet Address : 261/659)

The ideas expressed here are [...]*.*;*


/********************* Cut Here *********************************************/
/****************************************************************************/
/*                                                                          */
/* Programmer: John Sottile                                                 */
/*                                                                          */
/* Date: October 29, 1985                                                   */
/*                                                                          */
/* Description:  This program adds an addition command to the DCL           */
/*               library.  The call will allow a single character read      */
/*               from the keyboard to go into a local DCL variable.         */
/*                                                                          */
/*               The call is as follows:                                    */
/*                                                                          */
/*               $ getkey variable_list                                     */
/*                                                                          */
/*               The Variable List can be a multiple list of variables,     */
/*               but they must be separated by a space.                     */
/*                                                                          */
/*               The key will not be echoed to the screen.  To change this, */
/*               remove the +IO$M_NOECHO in the $qiow call.                 */
/*                                                                          */
/*               The actual symbol GETKEY should be defined globally at     */
/*               login time and the executable image (GETKEY.EXE) should    */
/*               reside in SYS$LOGIN:, unless you give a directory name     */
/*               instead.  The login line should look like this:            */
/*                                                                          */
/*               $ getkey :== $sys$login:getkey                             */
/*                                                                          */
/*               Note:  This program will only run on a VAX/VMS 3.7 or      */
/*                       higher Operating System.                           */
/*                                                                          */
/* Example (in DCL):                                                        */
/*                                                                          */
/*       $ again:                                                           */
/*       $   write sys$output "Would you Like to Exit? (Y/N)"               */
/*       $   getkey response                                                */
/*       $   if response .eqs. "Y" .or. response .eqs. "y" then exit        */
/*       $ goto again                                                       */
/*                                                                          */
/****************************************************************************/









#include iodef
#include descrip

char inkey ();

main (argc,argv)

int argc;
char *argv[];

{
  char letter[2];
  int i=1;

  deassign ();

  letter[1] = 0;

  for (;(i<argc)&&(letter[0]=inkey()); setsym (argv[i], letter), i++);
}

deassign ()

/****************************************************************************/
/*                                                                          */
/* This procedure will deassign SYS$INPUT so that the SYS$QIOW routine will */
/* get the input from the keyboard.                                         */
/*                                                                          */
/****************************************************************************/

{
  char *sysinput   = "SYS$INPUT";
  char *syscommand = "SYS$COMMAND";

  $DESCRIPTOR (inputname, sysinput);
  $DESCRIPTOR (newlog, syscommand);

  inputname.dsc$w_length = 9;            /* Dirty, but it gets the job done. */
  newlog.dsc$w_length = 11;

  LIB$SET_LOGICAL (&inputname, &newlog);

}

setsym (symbol, value)

/****************************************************************************/
/* This routine will call the lib$ function LIB$SET_SYMBOL which sets the   */
/* local DCL variable (the first parameter) to the value (the second        */
/* parameter.  For more information on the function LIB$SET_SYMBOL, consult */
/* the VAX/VMS RUNTIME LIBRARY REFERENCE MANUAL.                            */
/*                                                                          */
/****************************************************************************/

char symbol [];
char *value;

{

  $DESCRIPTOR (symname, symbol);
  $DESCRIPTOR (valname, value);

  symname.dsc$w_length = strlen (symbol) ;

  valname.dsc$w_length = 1;

  LIB$SET_SYMBOL (&symname,&valname);

}








char inkey ()

/*****************************************************************************/
/*                                                                           */
/* This routine was written by Ed Bubnis.  I would like to recognize the     */
/* head C programmer here.  Thanks a lot, Ed.                                */
/*                                                                           */
/* If you would like more (obviously) information of the SYS$QIOW ($QIOW)    */
/* function, consult the VAX/VMS SYSTEM SERVICES REFERENCE MANUAL.           */
/*                                                                           */
/*****************************************************************************/

{
struct { long length; char *address; } logical_name;
struct { short status; short length; int remainder; } iosb;

static char kb[] = { "sys$input" };
static int chan;

static char key = 0;
char new_key;
static int first = 1;
int status;

        key = 0;
        logical_name.length = strlen (kb);
        logical_name.address = kb;
        status = sys$assign (&logical_name, &chan, 0, 0);
        if (status != 1)
           {    printf ("Error assigning channel to sys$input\n\n");
                exit (1);
           }
        status = sys$qiow (0,chan,IO$_READLBLK+IO$M_NOECHO,
                           &iosb,0,0,&key,1,0,0,0,0);
        if (!key) return (0);
        else {  new_key = key;
                key = 0;
                status = sys$dassgn (chan);
                return (new_key);
             }
   }