[comp.os.vms] Dot H files #2 request

purdy@skat.usc.edu (Tim Purdy) (03/09/88)

 Hi!
   I posted recently an article about not having certain .h files on
 our VMS system, which are needed by a UNIX written C program.  I thank
 all who replied, but I think I needed to be more specific.  Mind now
 that I'll probably have to use RMS functions for the following, but I
 have NO experience programming with these!  Well, here goes:

 --  Our system does not have a times.h file in the syslib.  Does any-
     one know how to extract the user-time and system-time elapsed for
     a process?  Namely I need something that returns from the times
     structure  tms_utime and tms_stime.

 --  Is there a VMS substitute for the system() function?  I need to send
     mail from a program to a user, UNIX C handles this nicely, but is
     there someway of doing it on VMS?

 --  Is there also a substitute for the link() function, something other
     than access?  Our system doesn't seem to support create() either--
     which seems to be the closest substitute.

 --  Can vfork() substitute for fork()?

 --  Now for a real doozy:  there are a few calls made by two programs for
     the VERY UNIX dependent library function ioctl.h.  

     a)  one section of code uses ioctl to flush inputted characters from
         a buffer, heres the code:

	   char cc;
           int ic;
		do  /* if keyboard input buffer is too big, flush some of it */
		  {
		  ioctl(0,FIONREAD,&ic);
		  if (ic>5) read(0,&cc,1);
		  }
		while (ic>5);  

	 The following are the sections of code that ioctl.h references 
 	 for the above section of code:

/*
 * Ioctl's have the command encoded in the lower word,
 * and the size of any in or out parameters in the upper
 * word.  The high 2 bits of the upper word are used
 * to encode the in/out status of the parameter; for now
 * we restrict parameters to at most 128 bytes.
 */
   #define  FIONREAD     _IOR(f, 127, int)  /* get number of bytes to read */
   #define  _IOR(x,y,t)  (IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|('x'<<8)|y)
   #define  IOCPARM_MASK 0x7f   /* parameter must be < 128 bytes */
   #define  IOC_OUT      0x40000000  /* copy out parameters */

	Does anyone have any idea what might be going in the ioctl code?

     b)  The next bit of code is from another program using ioctl.h.
	 Again could anyone give me some insight as to what might be
	 going on?  Below is the pertinent code:

#ifndef BSD
#define CBREAK RAW		/* V7 has no CBREAK */
#endif

#define doraw(_a) (_a.sg_flags |= CBREAK,_a.sg_flags &= ~ECHO)
#define unraw(_a) (_a.sg_flags &= ~CBREAK,_a.sg_flags |= ECHO)

static struct sgttyb ttx;	/* storage for the tty modes */


/*
 *	scbr()		Function to set cbreak -echo for the terminal
 *
 *	like: system("stty cbreak -echo")
 */
scbr()
	{
	gtty(0,&ttx);		doraw(ttx);		stty(0,&ttx);
	}

/*
 *	sncbr()		Function to set -cbreak echo for the terminal
 *
*	like: system("stty -cbreak echo")
 */
sncbr()
	{
	gtty(0,&ttx);		unraw(ttx);		stty(0,&ttx);
	}

The ioctl.h code is:

#define		CBREAK		0x00000002	/* half-cooked mode */
#define		RAW		0x00000020	/* no i/o processing */


#define	_SGTTYB_
struct sgttyb {
	char	sg_ispeed;		/* input speed */
	char	sg_ospeed;		/* output speed */
	char	sg_erase;		/* erase character */
	char	sg_kill;		/* kill character */
	short	sg_flags;		/* mode flags */
};

     Any clues or ideas will be GREATLY appreciated, mainly 'cause
     I'm clueless.  Thanx in advance!

                                               -- Tim Purdy
*:^)

Arpa: purdy%skat.usc.edu@usc-oberon.arpa
Uucp: ihnp4!sdcrdcf!usc-oberon!skat!purdy

terry@wsccs.UUCP (terry) (03/15/88)

In article <7521@oberon.USC.EDU>, purdy@skat.usc.edu (Tim Purdy) writes:
> 
>  Hi!
>    I posted recently an article about not having certain .h files on
>  our VMS system, which are needed by a UNIX written C program.  I thank
>  all who replied, but I think I needed to be more specific.  Mind now
>  that I'll probably have to use RMS functions for the following, but I
>  have NO experience programming with these!  Well, here goes:

	It's pretty bad that you'd think that RMS (Record Management Services)
would clue you in to doing either of the following.

>  --  Our system does not have a times.h file in the syslib.  Does any-
>      one know how to extract the user-time and system-time elapsed for
>      a process?  Namely I need something that returns from the times
>      structure  tms_utime and tms_stime.

	$GETJPI.  See the system services reference manual.  It doesn't
return it how you want it, but at least it returns it.  You may have to
go to assembly calls, as the beast is bigger than G_float, as I remember,
and is accurate to at least a billionth of a second... you'll pass them
a descriptor with a pointer to a structure, thus word-aligning you data
so that the math routines don't puke.  I seem to also recall a LIB$EMUL
was necessary...

>  --  Is there a VMS substitute for the system() function?  I need to send
>      mail from a program to a user, UNIX C handles this nicely, but is
>      there someway of doing it on VMS?

	Use the LIB$SPAWN function, in the System Services reference manual.

>  --  Is there also a substitute for the link() function, something other
>      than access?  Our system doesn't seem to support create() either--
>      which seems to be the closest substitute.

	No substitute for link without directly modifying things you don't
want to modify and having grundles of priveledges.

	It supports create; if you can't figure out how to use it, use an
open call to create the file.  The create() call will sometimes fail if you
don't specify version ;1 or if you are over your version limit/accounting quota.
Either way, it's no substitute for link.

>  --  Can vfork() substitute for fork()?

	Yes, sort of.  Not all objects are passed correctly/completely.  This
should be documented in your C manual.  You will have to spawn a process, then
attach your vfork to it to have it behave asynchronously. If you are trying to
have it talk to your main program's fd's (like Kermit connect mode), you may
have to freopen() some of them.  If you need it to talk through a pipe, you
will have to declare a mailboxvia one of the myriads of methods.

>  --  Now for a real doozy:  there are a few calls made by two programs for
>      the VERY UNIX dependent library function ioctl.h.  

>      a)  one section of code uses ioctl to flush inputted characters from
>          a buffer, heres the code:

[fugly code deleted]

> 	Does anyone have any idea what might be going in the ioctl code?

	Yes.  You are checking to see if there are any characters present.  The
code, feeling that it can only deal with 5 characters at a time, throws away
all characters following it.

	Have you considered fflush()? I know it's old fashioned, but...

	Seriously, you will have to go to QIO$ routines... which meansyou'll
need channels.  Since VMSis a message-based OS, this is NOTgoing to be fast.

>      b)  The next bit of code is from another program using ioctl.h.
> 	 Again could anyone give me some insight as to what might be
> 	 going on?  Below is the pertinent code:

[more rather fugly code deleted]

	It's simply setting the terminal into "raw" mode.  This translates to
a QIOW$ (W is intentional) with an extended attribute block for extended
terminal characteristics.  All in all, you single ioctl call will probably
translate to 60 or 70 lines of VMS code to:

	1) set up descriptors
	2) set up values
	3) get around incorrect documentation of parity in the manuals
	4) get around incorrest operation of parity over terminal servers
	5) pass the 12 parameters to QIOW$
	6) get around the fact that from VMS 4.5 on, DEC has forgot 2 TT$
	   entries in ttdef.h
	7) Cancel, then re-instate, any pending I/O (QIO$ vs. QIOW$) so that
	   VMS does not try to 'sync' your I/O, thereby hanging your parameter
	   change until that read you queued completes (really screws up doing
	   async when that happens.


General:

	It sounds like you are trying to port a simplified Terminal program.
What you probably want to do is to queue several I/O's (one for each end) and
set up AST's for when they complete (before anyone flames me, realize that this
is what DEC did for SET HOST/DTE).  Realize that this can't keep up above 2400
baud on a uVAX II unless you use flow control.  There are a number of better
ways, the best of which allows 4800 baud with no flow control _AND_ emulation
via state-table of VT100, TVI925, TVI912, ADM1(7270), WYSE50, VT52, etc.  That's
what we do in our async product for VMS.

	Your best bet would be to

	1) use SET HOST/DTE
	2) use Kermit
	3) use our software(if you need emulation)

If you're totally beefed up on getting a C program you like ported (maybe a
game?), you should either ask someone to help, or you should get a copy of
the mainframe Kermit distribution tape, and look at the VMS C Kermit source.
It has a number of examples, such as a 'popen()' workalike... but again, there
are better ways; the thing seems to bog between 1200 and 2400 baud if you
don't use flow control.


| Terry Lambert           UUCP: ...{ decvax, ihnp4 }                          |
| @ Century Software          : ...utah-cs!uplherc!sp7040!obie!wsccs!terry    |
| SLC, Utah                                                                   |
|                   These opinions are not my companies, but if you find them |
|                   useful, send a $20.00 donation to Brisbane Australia...   |
| 'There are monkey boys in the facility.  Do not be alarmed; you are secure' |

darin@laic.UUCP (Darin Johnson) (03/22/88)

In article <321@wsccs.UUCP>, terry@wsccs.UUCP (terry) writes:
> In article <7521@oberon.USC.EDU>, purdy@skat.usc.edu (Tim Purdy) writes:
> > 
> >  --  Our system does not have a times.h file in the syslib.  Does any-
> >      one know how to extract the user-time and system-time elapsed for
> >      a process?  Namely I need something that returns from the times
> >      structure  tms_utime and tms_stime.
> 
> 	$GETJPI.  See the system services reference manual.  It doesn't
> return it how you want it, but at least it returns it.  You may have to
> go to assembly calls, as the beast is bigger than G_float, as I remember,
> and is accurate to at least a billionth of a second... you'll pass them
> a descriptor with a pointer to a structure, thus word-aligning you data
> so that the math routines don't puke.  I seem to also recall a LIB$EMUL
> was necessary...

This seems like overkill.  With minimal rewriting, you can do:

  #include <time.h>	/* instead of times.h */
  .
  .
  tbuffer_t ut;
  times(&ut);
  printf("user time = %d\n", ut.proc_user_time);

See the .H file for the rest of the fields.  They are most likely pretty
much identical except for name changes (on my sun, the order is even the
same).

$GETJPI has lots more information, but times() should be just as accurate
(and easier to program).

This is C version 2.3...  Earlier version may not have this.

> >  --  Is there a VMS substitute for the system() function?  I need to send
> >      mail from a program to a user, UNIX C handles this nicely, but is
> >      there someway of doing it on VMS?
> 
> 	Use the LIB$SPAWN function, in the System Services reference manual.

Version 2.3 C has a system() function.  It is just a slow and hideous
as LIB$SPAWN.  I wrote a system() myself once that actually kept around
the process from LIB$SPAWN and kept sending commands to it through a mailbox.
This alleviated the problem with 5 second spawns on a medium loaded 8600.

> >  --  Now for a real doozy:  there are a few calls made by two programs for
> >      the VERY UNIX dependent library function ioctl.h.  

Hmmn.  Seems like the person who wrote the program wasn't too concerned
with portability.  In general ioctl()'s for terminals/etc are pretty generic
but even they vary among unix's.  Ideally, these system dependent routines
should have been isolated and given names such as "turn_off_echo()", etc.,
but then I am probably flagellating a deceased equine....

-- 
Darin Johnson (...ucbvax!sun!sunncal!leadsv!laic!darin)
              (...lll-lcc.arpa!leadsv!laic!darin)
	All aboard the DOOMED express!