Speeding up your login processing under OpenVMS

Introduction

Back in the good old days of VAX computers, it could take significant time to log a process in to an OpenVMS system (or, as they were known then, a VMS system). More modern architectures have seen order-of-magnitude increases in processing power, rendering some of the techniques in this article redundant for their originally designed purposes. However, the code presented is a good example of accomplishing things usually performed at DCL with a compiled language.

Back in the days of the VAX 11/780, two hundred lines of DCL living in a user's login command procedure could slow things down remarkably. Tools like DCL_DIET made a significant difference to execution speed. As an example, have a look at SYS$UPDATE:AUTOGEN.COM, which has certainly been put on a diet.

However, some DCL command procedures were slow enough (or executed enough) to warrant recoding them in a compiled language. Large login command procedures fell under this category, and as far as I know, the first person to publish such a beast was Hunter Goatley, back in 1988. However, I suspect a lot of people came up with this idea at the same time. I wrote a VAX MACRO-32 version in 1986.

The general idea behind these procedures was to remove image activation from often executed command procedures, as this is where most time was spent.

This article presents a modern version of LOGIN.EXE written in the C language, and the small LOGIN.COM that goes along with it.

The command procedure

Here is my current LOGIN.COM. All important processing is accomplished via the executable image. My directory structure uses a concealed rooted logical name called MY_DISK that effectively makes my environment look the same no matter where you install my directory on a system:


$set noon
$os=f$env("symbol_scope")
$set symb/scop=nolocal
$if f$mode().eqs."INTERACTIVE"
$then
$n=f$edit(f$gets("nodename"),"lowercase")
$set promp="''n'ยป "
$set term/inq
$endif
$sl="sys$login"
$nc="no_conceal"
$de=f$pars(sl,,,"device",nc)
$di=f$pars(sl,,,"directory",nc)-"]["-"]"+".]"
$defi/job/trans=conc/nolog my_disk 'de''di'
$defi/nolog exe my_disk:[exe.'f$gets("arch_name")']
$mc exe:login my_disk:[int]
$set disp/cre/node=pc.domain/trans=tcpip
$set symb/scop=('os)
$exit

The data file

The data file that goes along with this allows you to perform a number of functions, including system and logical name definition, deletion of symbols, setting default protection, setting your preferred process name, and setting the process's file parsing style. Here is an example of LOGIN.DAT


R|DIR
F|E
D|S:RWED,O:RWED,G:RE,W
P|Jim Duff
S|DEL*ETE|DELETE/LOG
L|COM|MY_DISK:[COM]

This data file defines actions for LOGIN.EXE to perform. The data causes the code to perform the following actions:

LOGIN.EXE also formats another data file name for input, and if it is found, processes it in exactly the same way as LOGIN.DAT. This file is called SYMBOLS_nodename.DAT, where nodename is the name of the node the code is executing on. This allows node specific adaptions of the environment. In particular, I use this for persistant storage of the file I was last editing by getting my LOGOUT.COM command procedure to write it, but you can use it for anything you want.

Note that the LOGIN.EXE program locates both data files by prepending the argument passed on the command line to the filenames. In my case, I invoke LOGIN.EXE like so:


$ mc exe:login.com my_disk:[int]

after defining EXE to be an architecture specific directory. The datafiles are then called [.INT]LOGIN.DAT and [.INT]SYMBOLS_nodename.DAT.

The C program

The C code that makes up LOGIN.EXE is available via downloading this zip file.

Enjoy.