RSX "@" for VMS Users Abstract The RSX Indirect Command Processor (ICP) is in general (and with specific exceptions) equivalent in functionality to VMS DCL. However, the implementation philosophy of the two is totally different, and specific experience with VAX DCL command procedures generally does NOT transfer to RSX in the manner that VAX DCL experience transfers to RSX RSX "@" for VMS Users DCL. The purpose of this talk is to try to match RSX ICP concepts to VAX DCL concepts to give the new RSX programmer or system manager a jump start. 1 INTRODUCTION - DA020 - Any operating system worthy of the name (and a few that aren't) has a facility for "canning" system commands in a file, and executing them from the file in sequence. Generally, some sort of logic is included, and the indirect command facility of many operating systems is equivalent in Thomas R. Wyant, III functionality to a general purpose programming language. E. I. DuPont de Nemours Richmond, Virginia The RSX Indirect Command Processor (ICP) is no exception to the above remarks, but its implementation provides a unique "feel" versus the equivalent facility in other operating systems. Generally, indirect commands are implemented as part of the Command Line Interpreter (CLI - eg: VAX DCL, RT-11 KMON, Unix sh, csh, and so on). This May 6, 1992 frequently results in certain "batch-like" features, such as input redirection to the command procedure itself. RSX, on the other hand, implements the ICP as a separate executable which passes commands to the CLI one at a time, and (usually) waits for their completion. There is no input redirection, and no implicit status checking (the ICP predates the concept of an exit status in RSX). There is also a dichotomy between ICP directives (the symbol and logic statements, which ALWAYS start with a period) and CLI commands; they simply LOOK different. In fact, the first impressions of a VMS person looking at the RSX command processor would probably be all negative: * No inline data. * Symbol substitution doesn't work. RSX "@" for VMS Users RSX "@" for VMS Users * Arithmetic works funny. * Symbol substitution takes place before any other processing. One way to conditionally bypass a * No foreign commands. command is to comment it out using symbol substitution: * No lexical functions. 'FOO'DELETE *.*;* Generally, the above are "paper" problems: the where FOO is "" if you want the command to execute, functionality is there, but different; sometimes more and ".;" if you don't. This also means that convenient, sometimes less. My personal opinion is that user interaction, debugging, and task (= sub- or detached .IFDF FOO 'FOO' process) synchronization are better (or at least easier) under RSX, but that system interaction and arithmetic are won't work, as the symbol substitution occurs better under VMS. before the ICP parses the directive. * The ICP generally does not like extraneous blanks or tabs in ICP directives - except before the 2 GENERAL CONSIDERATIONS directive name itself. A single blank or tab should separate the directive name from its first There are several things needful to know, but which do argument, and the arguments themselves from each not really fit in any of the specific topics. Because some other. Embedded blanks in arithmetic expressions, of them are rather important, they are covered here, rather for example, are not tolerated. than in a "Miscellany" section at the end. * Commands that do NOT represent ICP directives are * The default file type is .CMD, not .COM. DEC seems displayed by default. You can cause them not to be to have established the convention that .COM is the displayed using .ENABLE QUIET. .DISABLE QUIET default when the indirect command facility is reverses this effect. The .IFENABLED QUIET embedded in the CLI, and .CMD otherwise. conditional is if .ENABLE QUIET is in effect and otherwise; .IFDISABLED QUIET is just * The maximum line length is 132 characters. the opposite. * The maximum nesting depth is four, not eight. This * The left side of a relational test (".IF") MUST be is partially compensated for by the .CHAIN a symbol. The right side may be a symbol, literal, directive, which transfers control to another substring, or expression of the appropriate type. command file at the same nesting level. * The ICP tends to die on syntax errors, as opposed to the VMS DCL, which typically makes an assumption and trucks on. 3 SYMBOLS * An attempt to substitute an undefined symbol is ICP symbols are the same in spirit as VMS DCL symbols, also fatal. but somewhat different in implementation. RSX ICP symbols come in three types (logical, numeric, and string), rather * There is no "-" operation for strings. than VMS' two. The types of the ICP's symbols are rigidly defined; once a string symbol (for example), always a string * The comment operator is ";" or ".;", not "!". The symbol. Symbols take their type from the directive that difference between the two is that comments creates them: .SETL or .ASK create logical symbols, .SETN preceded by ";" are normally displayed, but or .ASKN create numeric symbols, and .SETS, .ASKS, and .READ comments preceded by ".;" are normally not. create string symbols. The .ERASE directive destroys symbols, or they die a natural death when control transfers out of their scope. RSX "@" for VMS Users RSX "@" for VMS Users 3.1 Symbol Names * .SETN symbol expression Symbol names are limited to six alphanumerics, plus the Creates a numeric symbol and sets its value dollar sign. Symbol names may officially begin with numeric equal to the arithmetic expression. The logical characters, but there have been some bugs in this area. operators mentioned above are recognized, and perform bitwise operations. In addition, the normal arithmetic operators (+, -, *, and /) are recognized, though again without precedence. The 3.2 Symbol Values section on "Arithmetic" gives more detail. Logical symbols, of course, are simply or * .SETS symbol expression . "" and "", by the way, are predefined symbols that have those values. Creates a string symbol and sets its value equal to the string expression. The only string Numeric symbols take the values 0 to 65535 unless the operator is +, which does concatenation. String .ENABLE OVERFLOW directive has been issued. This directive literals can be quoted with either the '"' or '#' changes the range to -32768 to 32767. Numeric symbols and character, which is a good thing as there is no expressions will be discussed at greater length under convention for embedding the quoting character "Arithmetic". within a literal. String symbols take strings from zero to 132 bytes in * Bit strings length. RSX lacks the VMS bit string operator represented by the example 3.3 Symbol Assignment $ ESC[0,8] = 27 RSX does not recognize VMS' "symbol = expression" to create a symbol whose value is an escape syntax for assigning symbol values. Instead, it employs a character. However, an effect equivalent to the set of directives that specify the type of symbol being above (though NOT to the general case) can be had created, as well as computing and assigning its value: by using the %V symbol substitution operator, as follows: * .SETT symbol .SETN N$JUNK 27. Creates a logical symbol and sets it . .SETS ESC "'N$JUNK%V'" * .SETF symbol Creates a logical symbol and sets it . * .SETL symbol expression 3.4 Standard Symbols Creates a logical symbol and sets its value On entry to any command procedure, the string symbols equal to the logical expression. The logical P1 through P9 are defined in exactly the same way that VMS operators & (and), ! (or), and # (not) are defines P1 through P8. In addition, P0 represents the recognized, but & and ! have the same precedence. command file name as specified in the command (ie - it's NOT However, expressions in parentheses are evaluated the same as F$ENVIRONMENT ("PROCEDURE") -- more on that before expressions outside parentheses. later). Also, COMMAN contains the entire command line; that is, it is equivalent to the concatenation of P0 through P9, separated by spaces. RSX "@" for VMS Users RSX "@" for VMS Users In addition, there is a plethora of predefined symbols * There is no "&" substitution operator. enclosed in angle brackets. These will be discussed where appropriate (generally under lexical functions). * The VMS "Foreign Command" facility (implicit substitution on the first token on the line) is not implemented. This is NOT to say custom commands are unavailable; more on this under "Foreign 3.5 Symbol Scope Commands". Symbol scoping in the ICP is similar but not identical * The symbol name MUST be enclosed in "'" characters; to VMS DCL. Both local and global symbols exist, but global the VMS practice of making (in most cases) the symbols are not recognized unless the ".ENABLE GLOBAL" trailing "'" optional is not supported. directive has been issued. If this directive is in effect, any symbol whose name begins with a dollar sign is a global * The rules for symbol substitution DO NOT CHANGE symbol. inside string literals; it is not necessary to double up the "'" characters. Instead, "''" By default, the scope of local symbols is the command inserts a literal "'" in the string. Note, procedure in which they are defined. Unlike VMS DCL, they however, that "''" is interpreted as a double "'" are not visible in procedures invoked by the procedure that only in a context where a leading "'" is expected. defines them. The string "'P1''P2'" is interpreted as equivalent to the VMS DCL string "''P1'''P2'" The default scope of local symbols can be changed in two ways: * The .BEGIN directive creates a local symbol block. Symbols defined outside this block are still 4 ARITHMETIC visible. The .END directive terminates the block. Arithmetic in the RSX ICP is done to 16 bit (integer) * The "/LC" switch, when applied to a nested command precision. By default, it is unsigned, though signed procedure, prevents a local symbol block from being arithmetic can be had by use of the ".ENABLE OVERFLOW" created for that command procedure. Instead, the directive. Numeric constants are octal by default, though invoked and invoking command procedures share the you can specify a decimal number by appending a decimal same local symbol block, and have access to each point. You can make the default radix decimal (with no way others' symbols. of specifying octal numbers) by using the ".ENABLE DECIMAL" directive. Numeric symbols have a default display radix associated with them. This display radix is inherited from the 3.6 Symbol Substitution expression that was used to compute the value of the symbol: decimal if ANY decimal constant or symbol appears in the The ICP has symbol substitution, but the rules are expression, and octal otherwise. You can also use the slightly different from VMS: ".SETO" or ".SETD" directives to explicitly set the display radix of the symbol, and you can override the default by * You must issue the ".ENABLE SUBSTITUTION" ICP substitution control, which will be discussed under the directive before symbol substitution occurs. The lexical function F$FAO. ICP predates symbol substitution, and the RSX group has never, to my knowledge, changed the default There are six binary operators recognized: + behavior of any RSX component. Typically, 99% plus (addition), - (subtraction), * (multiplication), / of all RSX .CMD files begin with ".ENABLE (division), & (bitwise and), and ! (bitwise or). In SUBSTITUTION" addition, there are two unary operators, - (unary minus), and # (bitwise not). RSX "@" for VMS Users RSX "@" for VMS Users If you intend to do arithmetic with the ICP, you need .IFINS task Task is installed. to be aware that the ICP does NOT obey the (almost) .IFNINS task Task is not installed. universal rules for the precedence of operators; instead, .IFACT task Task is active. all operators have the same precedence. The expression .IFNACT task Task is not active. 3.+4.*5., for example, evaluates to 35., not 23. as you would expect. You can, however, group operations with Any two or more of the .IF directives can be connected parentheses: 3.+(4.*5.) in fact evaluates to 23., as does with .AND or .OR directives, which function as the expected 4.*5.+3. logical connectives. One inobvious thing about these connectives is the need to specify .IF again after .AND or .OR; this convention allows .AND and .OR to be used in conjunction with the special purpose .IF directives; for 5 LOGIC example, The ICP directive corresponding most nearly to the VMS .IFINS FOO .OR .IFINS BAR "IF" is the .IF directive. The general syntax is Parentheses can be used to group conditionals on the right .IF symbol relation expression command side of an .AND or .OR: where the command is issued only if the value of the symbol .IFINS FOO .AND (.IFINS BAR .OR .IFINS BAT) on the left has the specified relation to the expression on the right. NOTE THAT ONLY A SYMBOL IS ACCEPTABLE ON THE LEFT SIDE OF THE RELATION (no literals or expressions!), and that the expression must be the same type as the symbol. 6 INLINE DATA The following relations are recognized: Inline data is one of those things that is simply not Relation Satisfied if symbol is supported under RSX. However, almost all RSX utilities -------- ---------------------- (including COPY, LINK, FORTRAN, and so on) can be instructed = or EQ Equal to expression to read their input from a file rather than the terminal. <> or NE Not equal to expression The syntax for this is (not surprisingly) "@filename", with > or GT Greater than expression ".CMD" being the default file type. Files fed to utilities < or LT Less than expression in this way are NOT processed by the ICP. The net effect >= or GT Equal to or greater than resembles feeding an option file to the linker. <= or LT Less than or equal to Unfortunately, the GCML$ facility which supports this behavior does not have a supported interface to high-level Note the absence of dots around the alphabetic forms of the languages. relationals; given that the left side is a single symbol, spaces are sufficient punctuation. Also, there is no distinction between string and numeric relations; the type of the symbol makes this unambiguous. 7 SUBROUTINES. In addition to the "plain vanilla .IF", there are The ICP has a .GOSUB directive, which is about midway special-purpose directives: in functionality between the VMS GOSUB and CALL verbs. It is a VMS GOSUB as far as symbol scope is concerned; the Test True if: subroutine and the caller are in the same local symbol block -------------- ---------------------- (though you can create your own local symbol block using the .IFT symbol Logical symbol true. .BEGIN and .END directives). But unlike the VMS GOSUB, it .IFF symbol Logical symbol false. takes command arguments; anything on the command line after .IFDF symbol Symbol defined. the name of the called routine is passed in reserved symbol .IFNDF symbol Symbol not defined. COMMAN. .IFLOA driver Driver loaded. .IFNLOA driver Driver not loaded. RSX "@" for VMS Users RSX "@" for VMS Users You return from a subroutine using the .RETURN Writes the stuff to the designated open file. directive. The "stuff" is not quoted in any way. A SINGLE space or tab precedes "stuff"; if more than one is One thing to be cautious about is the fact that, unlike there, the subsequent ones are taken as part of the a VMS subroutine, if control flow reaches an RSX subroutine data. by "fall through", the subroutine WILL be executed. You will get an error when the ICP attempts to execute the * .ENABLE DATA [#n] .RETURN. Causes the contents of the command procedure to be copied to the output file until a ".DISABLE DATA" directive is encountered. In at least some 8 FILE I/O incarnations of the ICP, the .DISABLE DATA must start in column 1. Symbol substitution DOES take Corresponding to the OPEN, READ, WRITE, and CLOSE verbs place while you .ENABLE DATA. If you are using the in VMS are the .OPEN, .READ, .DATA, and .CLOSE directives. .ENABLE DATA block to build another command The ICP is limited (rather severely) to only four files open procedure, be aware that labels in the .ENABLE DATA simultaneously. In addition, it can only read and write block WILL be recognized while executing a GOTO. sequential files. The functionality corresponding to the VMS "READ/PROMPT/TIMEOUT" exists, but does NOT reside in * .READ [#n] symbol these directives, and discussion of it is deferred to the section on user I/O. Causes the next record in the file to be read into the symbol. If end of file is encountered, All ICP file I/O directives have generally the same the symbol (the enclosing angle brackets ARE syntax; the directive name, an optional channel number part of the symbol name) will be set to . (preceded by a pound sign, and in the range 0 to 3), and directive-specific data if any. The channel number is a * .CLOSE [#n] numeric literal (eg: 3) or a SUBSTITUTED symbol (eg: 'FOO'). Any non-fatal error causes the FCS error code to Closes the open file. be returned in . The specifics are: * .OPEN [#n] filename Opens a file for output. It is a sequential 9 USER INTERACTION file with variable length records and "List" carriage control. The square brackets are NOT part The ICP directives corresponding most nearly to INQUIRE of the syntax; they merely denote an optional (or READ/PROMPT) are the .ASK directives. These come in syntax element. three flavors, one for each type of symbol, and provide a considerable amount of validation, with hooks for you to * .OPENA [#n] filename easily do more. The general syntax is Opens an existing sequential file for .ASKx [low:high:default:timeout] symbol prompt appending. with the "x" being nothing at all for a logical query, "N" * .OPENR [#n] filename for a numeric, and "S" for a string. The prompt is not enclosed in quotes. The stuff in square brackets is Opens an existing sequential file for input. optional, but if supplied the square brackets are part of the syntax. The meanings of the optional items are: * .DATA [#n] stuff ... * low:high RSX "@" for VMS Users RSX "@" for VMS Users These items are not valid for the .ASK * is if the string contains only (logical) form of the directive; the colons that alphanumeric characters. delimit them are also omitted in this case. For .ASKN, they represent the lowest and highest valid * is if the string contains only inputs, and they must both be specified or both numeric characters. omitted; the ICP will issue a warning and repeat the prompt if the input is out of range. For * is if the string contains only octal .ASKS, they represent the minimum and maximum characters. length of the input string. * default This is the value returned if a carriage 9.2 Captive Command Procedures return is entered. It must be of the same type as the directive ( and are handy here in The normal action of a .ASKx directive on encountering .ASK). If not specified, the default is end-of-file (control/z) is to terminate the ICP on the spot. for .ASK, zero for .ASKN, and "" for .ASKS. If the However, if you .DISABLE CONTROL-Z, the control/z character user in fact takes the default, the special symbol causes the .ASKx directive to be satisfied, and special is set ; otherwise it is set symbol is . If, in addition, you issue the MCR . command SET /SLAVE=TI: (or the equivalent DCL SET TERMINAL/SLAVE), there will be no way to exit the command * timeout procedure (barring errors) except under your control. The SET /SLAVE command has no exact equivalent in VMS, but in The timeout is specified as an integer the present case has the effect of SET NOCONTROL=Y. followed by "S" (for seconds), "M" (for minutes), or "H" (for hours). If a timeout occurs, the You can have the equivalent of a captive account if you special symbol is , but in general specify that the account itself be logged in slaved, and you you should NOT assume that the default value has .DISABLE CONTROL-Z in the account's LOGIN.CMD before issuing been returned. You cannot specify more than 32767 any .ASKx directives. seconds, 1440 minutes, or 24 hours. Any validation parameters specifies will appear in the 9.3 The Great Escape prompt. Under RSX, the escape character normally acts as a terminator. However, you can if you choose field it in a couple of ways. 9.1 More On Validation If you .ENABLE ESCAPE, then special symbol is In addition to the validation provided by the .ASKx if the user responds to the query with an escape directive itself, there is supplemental information made character. This trick is used extensively in SYSGEN. available after the .ASKS directive in various special symbols: In addition, entire escape sequences can be fielded if you .ENABLE ESCSEQ and issue the MCR command SET * contains the length of the string. /ESCSEQ=TI:. For this to work smoothly, you will probably also need to .ENABLE ATTACH and .DISABLE DETACH * is if the string contains only RAD50 characters. RSX "@" for VMS Users RSX "@" for VMS Users 10 FOREIGN COMMANDS As an aside, all user-written CLIs under RSX except (of course) MCR simply take their input, reformat it into a MCR Although RSX does not support anything like the VMS command, and let MCR do the dirty work. This does involve foreign command facility (much less anything like "SET several task activations before you're done, but an RSX task COMMAND"), it is possible to define your own commands. The activation is not the big deal a VMS image activation is; ease or difficulty of this depends on which CLI you are you should be able to get an installed task under way in using, as follows: under 100 milliseconds. * MCR Foreign commands under MCR are a piece of 11 DEBUGGING cake. Just install your task with name "...xxx" (where the x's are a three character name of your The RSX equivalent of SET VERIFY is to apply the /TR choosing), and MCR will recognize it as a command. qualifier to the command that invokes the command procedure. You get the command text using GETMCR (the RSX Within the command procedure, you can .ENABLE TRACE and facility corresponding to LIB$GET_FOREIGN). GETMCR .DISABLE TRACE to turn verification on and off. The works regardless of which CLI you're using. A directive .IFENABLED TRACE will tell you whether foreign command created in this way is system-wide. verification is currently on or off. If you are running under RSX-11M+ you can In addition, the RSX ICP has a feature which causes CLI create a command valid only on terminal tTnn by commands not to be execute. The effect is more or less as installing your task as xxxtnn. The "t" is the though VMS could be made to ignore all commands that execute first character of your terminal's device name images (such as DELETE ...), while executing commands that (either "T", "R", "H", or "V"), and the "nn" is its don't (such as GOTO, IF, ...). This is a boon to those who unit number (octal). For unit numbers above 77, want to be sure what commands their procedure issues before use the letters of the alphabet in order for the turning it loose on their systems. In order to run a first "n"; for example, FOOTB6 for command "FOO" on command procedure without issuing CLI commands, invoke it terminal TT116:. Be aware that the system will NOT with the /-CLI (or /-MCR) qualifier. In order to enable or clean up tasks installed in this way when you log disable the issuing of CLI commands from within a command out. procedure, use the .ENABLE CLI or .DISABLE CLI directive. * DCL RSX lacks a SHOW SYMBOL command. This is no hardship in the case of single symbols, as the command Adding commands to DCL requires modifying ; FOO = 'FOO' DCL's command table. This is charitably considered has the same effect as the VMS DCL command SHOW SYMBOL FOO. a pain in the neck. However, DCL can be configured However, this technique is useless if you wanted to SHOW (and is configured by default under modern M+ SYMBOL/ALL. Instead, the command systems) to pass any command it doesn't recognize @LB:[1,2]INDSYS/LB:INDDMP/LC to MCR, reducing the problem to the previous case. will do the trick. * CCL CCL is a user-written CLI available from 12 SYNCHRONIZATION AND STATUS DECUS. It is a file-driven command parser, able to supply defaults, prompt, and generally handle a When the ICP runs a task, it usually but not always wide variety of command parsing tasks. Unlike MCR waits for it to complete before continuing. The rules for and DCL, CCL supports command definition on a whether or not a wait occurs are: per-user basis as well as system-wide. * CLI commands are synchronous. That is, the ICP will wait for it to exit (or emit status) before continuing. RSX "@" for VMS Users RSX "@" for VMS Users * The RUN command is synchronous provided the task On the other hand, trapping of internal error is being run is NOT installed. somewhat similar to VMS. You specify * The RUN command is asynchronous if the task being .ONERR label run is installed; RSX treats this case more or less like the VMS RUN/DETACH command. to get the ICP to transfer control to the label of your choice for error handling. Unfortunately, the only indication of what error you encountered is an error class In addition, any synchronous command can be made number, returned in ; since there are only two asynchronous by using the .XQT directive, which corresponds classes, you're pretty much on your own. What class each in effect (though not in mechanism!) to SPAWN/NOWAIT. error belongs to is covererd in the ICP manual. Unlike VMS, RSX also provides the ability to Be aware that by default only class 1 errors are resynchronize with asynchronous tasks. The .WAIT directive trapped by the .ONERR directive; class 2 errors abort the waits for an task in the system to complete. Upon ICP anyway. You can modify this behaviour by setting bits completion of this task, numeric symbol contains in corresponding to the error classes you want; the exit status of the task, or 17 (octal) if the status was not available. Status would not be available if the task .SETN 3 was not active when you issued the .WAIT, unless you ran the task with a .XQT; in this case, the ICP can buffer a limited will cause both class 1 and class 2 errors to be trapped. number of completion statuses for you. Class 2 errors are generally more severe than class 1 Timed delays (corresponding to VMS DCL WAIT) can be had errors, and the manual contains some dire words about with the .DELAY directive. The time is specified as an continuing from a class 2 error. Experience has shown, integer in the range 1-32767, followed by one of the letters however, that things aren't necessarily as bad as they are "T" (Ticks), "S" (Seconds), "M" (Minutes), or "H" (Hours). presented. One can generally continue from class 2 errors, The interval specified may not exceed 24 hours. provided one does not rely on any particular behaviour from the operation that caused the error. 13 ERROR CONTROL 14 EQUIVALENTS OF LEXICALS The RSX ICP is normally insensitive to statuses returned by executables. If you care what's going on here, RSX does not have any feature corresponding to VAX DCL you'll need to manually check the exit status, which becomes lexical functions. In general, things that are implemented available in numeric symbol upon task exit for as lexicals under VMS are either special symbols or synchronous operation, or the completion of the .WAIT directives under the ICP. This section is basically a directive otherwise. Unlike VMS, RSX exit statuses are conversion table, listing VMS lexicals and their nearest RSX almost completely ad-hoc. The only order imposed is as equivalents. follows: Lexicals whose function depends on an "item" argument * The low 4 bits are BY CONVENTION the severity code. will in general NOT be covered exhaustively; silence on a particular item will usually mean that RSX won't do the * If the application exits normally without function, as RSX functionality is generally not as rich as specifying an exit status, 1 () is VMS functionality in this area. returned. * If the application dies horribly, 4 () is returned. 14.1 F$CONTEXT RSX has neither processes, process IDs, nor contexts in RSX "@" for VMS Users RSX "@" for VMS Users which to search them. and issuing a .TESTDEVICE for each unit that exists: .SETS S$DL "DR,DU,DP,DL,DK" .DEVLP: 14.2 F$CSID .IF S$DL = "" .GOTO DEVND .PARSE S$DL "," S$DN S$DL This is irrelevant, as clustering in the DEC sense is .SETN N$DU 0 not supported under RSX. .UNTLP: .TESTDEVICE 'S$DN''N$DU': .IF = "NSD," .GOTO DEVLP 14.3 F$CVSI, F$CVUI .INC N$DU .GOTO UNTLP The ICP is capable of extracting the first byte of a .DEVND: string symbol and converting it to numeric by using %V substitution control. For example, after Note that the above code can be fooled by logical names that look like device names. To be on the safe side, look at the .SETS FOO "BAR" physical device name you get from to be sure it's .SETN ASCI 'FOO%V' what you expected. symbol ASCI has value 66. 14.6 F$DIRECTORY 14.4 F$CVTIME This lexical corresponds pretty exactly to the special symbol . However, this symbol is set to "[]" when RSX has no such "built-in" capacity. It has the you are in NONAMED mode; you'll need to check for this case capability to perform all the functions of this lexical and use the value of instead. There is an example procedurally, provided the user is sufficiently determined. under F$ENVIRONMENT ("DEFAULT"). For instance, a date (passed in COMMAN) can be converted to relative format by the following code fragment, which is called by a .GOSUB: 14.7 F$EDIT .GOSUB CVTCMP '' ; '' This is one of those "item"-dependent lexicals .EXIT mentioned above. What follows is a list of items the ICP .CVTCMP: handles, followed by the RSX command equivalent to FOO = .PARSE COMMAN "-" S$D S$M S$Y F$EDIT (BAR, item): .TEST "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC" S$M .SETN N$M (+2)/3 * "COMPRESS" .SETN N$Y 'S$Y'. .SETS BAR "'FOO%C'" .SETN N$D 'S$D'. .SETS "'N$Y%DR2Z'-'N$M%DR2Z'-'N$D%DR2Z'" * "UNCOMMENT" .RETURN .PARSE FOO "!" BAR JUNK * "UPCASE" .DISABLE LOWERCASE 14.5 F$DEVICE .SETS BAR "'FOO'" .ENABLE LOWERCASE RSX has, unfortunately, no corresponding functionality. One can "make do" by iterating over a list of device names RSX "@" for VMS Users RSX "@" for VMS Users 14.8 F$ELEMENT * "PROCEDURE" After the ICP directive .SETS FOO , provided this is done before any other file manipulation directives (such .PARSE FOO SEP E0 E1 E2 E3 ... as .TESTFILE or .OPEN) are issued. the string symbols E0, E1, ... will contain elements 0, 1, * "VERIFY_IMAGE", "VERIFY_PROCEDURE" ... as they would be returned by F$ELEMENT (0, SEP, FOO) ..., with the following differences: VERIFY_IMAGE has no real equivalent in RSX, since it does not do inline data. VERIFY_PROCEDURE * SEP can be more than one character; in this case, equates to the following pair of RSX ICP E0 will contain everything up to the first directives: character in SEP, E1 everything from there to the second character in SEP, and so on. The last .IFENABLED QUIET evaluates if commands character in SEP will be reused as often as that run tasks are not displayed, and of necessary. not. The RSX ICP has QUIET disabled by default. * If there are not as many elements in FOO as .IFENABLED TRACE evaluates if commands anticipated, the remaining E's will be null that do not run tasks are displayed, and if strings, not SEP. not. The RSX ICP has TRACE disabled by default. * If there are more elements in FOO than anticipated, Both the above tests have corresponding the last symbol in the .PARSE will contain the .IFDISABLED tests, which evaluate oppositely. entire remaining portion of FOO. 14.10 F$EXTRACT 14.9 F$ENVIRONMENT The exact equivalent of F$EXTRACT (s, n, FOO) is This is another of those "item"-dependent lexicals. FOO[s:s+n-1] -- or at least it would be if RSX tolerated Again, a list of items the ICP handles is given, followed by expressions in the substring specification. As it is, only the RSX construct equivalent to FOO = F$ENVIRONMENT (item): constants or symbols work. The frequently-encountered case * "CAPTIVE" BAT = F$EXTRACT (0, F$LOCATE (BAR, FOO), FOO) RSX does not have captive accounts as such; is better handled by however, you can find out whether you are running on a slaved terminal as follows: .PARSE FOO BAR BAT .TESTDEVICE TI: provided BAR is a single character. For the general case, .PARSE "," JUNK JUNK S$UCW2 JUNK you are forced to .SETN N$UCW2 'S$UCW2' .SETN N$ZERO 0 .TEST FOO BAR .IF N$ZERO = 'S$UCW2'&200 . .SETS BAT FOO[1:] * "DEFAULT" .TRANSLATE SY: .SETS FOO 14.11 F$FAO .IF <> "[]" .SETS FOO FOO+ .IF = "[]" .SETS FOO FOO+ The RSX feature corresponding to the SYS$FAO service is RSX "@" for VMS Users RSX "@" for VMS Users the $EDMSG subroutine. The ICP does not provide an 14.12 F$FILE_ATTR interface to this routine, but it does provide some of the same functionality. Byte, longword, and hexadecimal The RSX functionality in this area is pretty operations are not supported, but most of the rest can be rudamentary. If the information you want is available at obtained by using substitution control. all, you may have to dig it out. Specifically, the .TESTFILE directive returns a number of special symbols. Substitution control has already been encountered; it These include is specified by following the variable being substituted with a percent sign and the substitution control characters * will be 1 if the file exists. desired. These are: * contains the fully-qualified file * C specification. Blank compression (covered under F$EDIT). In addition, certain information is returned to you in * D when you open a file. This information corresponds to the first seven words of the FCS File Descriptor Block, Decimal (numerics only). documented in the back of the "Guide to I/O Operations". You'll need to parse , then (possibly) extract the * Ln information you want with bitwise operations. contains (in order, and separated by commas): Left justify in an "n" byte field. * Record type. The values represent: * O Value Meaning if set. Octal (numerics only). ----- -------------------------------- 1 Fixed-length records. * Rn 2 Variable-length records. 3 Variable woth fixed control. Right justify in an "n" byte field. * S * Record attribute. The individual bits represent: Signed value (numerics only). Mask Meaning if set. ------ -------------------------------- * V 000001 FORTRAN carriage control. 000002 List carriage control. Convert first byte of string to numeric, or 000004 Print (=COBOL) carraige control. low byte of number to character. See F$CVSI and 000010 Records don't span blocks. "Bit strings" (under "Symbol Assignment") for more details. * Record size (decimal). * X * Highest virtual block number (decimal longword). Convert number to RAD-50 string. * End-of-file block number (decimal longword). * Z * First free byte in the end-of-file block (octal Zero-fill the field. word). RSX "@" for VMS Users RSX "@" for VMS Users * Record access control. The individual bits the crash dump analyzer manual, which also has the second represent: (device-specific) word for the TT: driver. But the only guaranteed way to get the meaning of the contents of the Mask Meaning if set. second and third words is to read the driver involved. For ------ -------------------------------- disks, the low byte of the second word plus both bytes of 000001 Open in read/write mode. the third is the device size in blocks. 000002 Open in random access mode. 000004 Open in locate mode. The device-independent bits in word one are: 000010 Sequential put doesn't truncate. Symbol Mask Meaning if set. These will probably all be zero, and at any event ------ ------ -------------------------------- do not represent actual file attributes, but rather DV.REC 000001 Record oriented device the way the ICP opens the file. DV.CCL 000002 Carriage control device DV.TTY 000004 Terminal device * Device attributes (octal). This is just the DV.DIR 000010 File structured device device-independent word returned by .TESTDEVICE. DV.SDI 000020 Single directory device See below under F$GETDVI for the meanings of the DV.SQD 000040 Sequential device individual bits. DV.MSD 000100 Mass storage device DV.UMD 000200 User mode diagnostics supported DV.EXT 000400 Device on extended address ctrlr You can not determine whether a file is installed as a DV.SWL 001000 Device is software write locked task or resident library or common without writing some DV.ISP 002000 Input spooled device pretty serious (kernel-mode!) code. Discovering whether a DV.OSP 004000 Output spooled device task is installed, on the other hand, is pretty simple; DV.PSE 010000 Pseudodevice .IFINS task is true if the named task is installed, and DV.COM 020000 Mountable as comm channel false if not; .IFNINS is just the opposite. Checking for a DV.F11 040000 Mountable as Files-11 device. resident library or common can be done with the DV.MNT 100000 Mountable .TESTPARTITION directive, which returns its information in . For the TT: and related drivers, the bits in word 2 are: Symbol Mask Meaning if set. ------ ------ -------------------------------- 14.13 F$GETDVI U2.LWC 000001 Convert input to uppercase. U2.VT5 000002 VT05 terminal. The functionality here is slightly better than for file U2.L3S 000004 LA30S terminal. attributes, but not much. The implementation is similar: U2.PRV 000010 Privileged. issue the .TESTDEVICE directive, and parse . This U2.AT. 000020 Command procedure is active. variable contains "NSD," if the device does not exist, or U2.HLD 000040 Hold screen. "name,ucb1,ucb2,ucb3,ucb4,flags..." if it does. "Name" is U2.DZ1 000100 Terminal is on DZ-11. the physical device name. UCB1 through UCB4 are the device U2.SLV 000200 Slaved. attributes returned by GETLUN, and you extract the U2.LOG 000400 Not logged on. information in the same way: UCB1 is device-independent U2.ESC 001000 Escape sequences recognized. characteristics (eg: "Mass storage", "sequential", ...), U2.CRT 002000 CRT device. UCB4 contains the buffer size, and UCB2 and 3 are U2.NEC 004000 Do not echo solicited input. device-dependent. The flags are a comma-separated list of U2.HFF 010000 Handles hardware form feeds. three-character mnemonics indicating such things as whether U2.RMT 020000 Terminal is remote. and how the device is mounted. U2.DJ1 040000 Terminal is on DJ-11 U2.DH1 100000 Terminal is on multiplexer The contents of the four UCB words are documented various places. The contents of the first word are The symbols in the first column are the symbolic names of documented in the I/O drivers manual for each driver, and in the bit masks as defined in the UCBDF$ macro. RSX "@" for VMS Users RSX "@" for VMS Users The flags are three letter device status indications, * Attachment: separated by commas. they fall into a number of groups, reporting different characteristics of the device. One flag NAT, not attached. from each group will be returned: ATU, attached by this copy of the ICP. * Driver status: ATT, attached by another task. LOD, driver is loaded. UNL, driver is not loaded. * Device status: 14.14 F$GETJPI ONL, device is online. RSX functionality here is non-existent, for the simple reason that jobs and processes don't exist. OFL, device is offline. * Mount status: 14.15 F$GETQUI MTD, device is mounted. Though RSX in fact has queues, the functionality here is pretty much non-existent, also. NMT, device is not mounted. * Mount type: 14.16 F$GETSYI FOR, device is mounted foreign. This functionality is also pretty much non-existent, since RSX does not have anything corresponding to a VMS NFO, device is not mounted foreign. "SYSGEN". The major exception is special symbol , which returns the DECnet node name if DECnet has been running, or the system name specified at the SYSGEN if not. * "Publicity": There is also a string symbol which encodes the PUB, device is set public. availability of certain RSX sysgen options. It is recommended that you use INDSYS module INDSFN to test these NPU, device is not set public. options; it is invoked using: @LB:[1,2]INDSYS/LB:INDSFN opt * Allocation: and returns "" or "" in , depending on NAL, not allocated. whether the specified sysgen option was chosen. The option codes include: ALU, allocated to this terminal. * EXT - 22 bit memory support. ALO, allocated to another terminal. * MUO - Multiuser protection. Be warned that some versions of the ICP get confused whether to return ALO or ALU. RSX "@" for VMS Users RSX "@" for VMS Users * EXV - 20K Executive. than just terminating processing of the line if an illegal character is encountered. You can trap illegal characters * DRV - Loadable driver support. beforehand by * OFF - Parent/Offspring support. .TEST BAR * DAS - Kernel mode data space support. and checking (or ) to see if the string contains only numeric (or only octal) characters. * LIB - Supervisor mode library support. Alternatively, you can use the ICP's error trapping. * MP -- Multiprocessor support. * WND - Secondary pool window blocks. 14.19 F$LENGTH * EIS - Extended instruction set support. The ICP equivalent to BAR = F$LENGTH (FOO) is * XHR - External header support. .TEST FOO .SETN BAR * 11S - RSX-11S system. The symbol is implicitly set by the .ASKS and * CLI - Alternate CLI support. .READ directives. * SHF - Shuffler support. * LOG - Error logging support. 14.20 F$LOCATE * DSP - Executive level dispatching. The ICP equivalent to BAT = F$LOCATE (BAR, FOO) is Actually, there are a bunch more than this, but I have been .TEST FOO BAR unable to run all of them to earth. Beware of the fact that .SETN BAT INDSFN dies horribly if you give it an option it does not know about. 14.21 F$MESSAGE 14.17 F$IDENTIFIER Lacking a message facility, RSX also lacks this lexical. Not having identifiers in the first place, RSX dispenses with this lexical. 14.22 F$MODE 14.18 F$INTEGER RSX does not distinguish as VMS does between process modes. You can infer similar (but NOT equivalent) The VMS expression FOO = F$INTEGER (BAR) is equivalent information from the device name of your TI: device, as to the RSX follows: .SETN FOO 'BAR' * TTnn: Direct-connect (possibly with modem) or LAT; such a user would probably be interactive, but see provided BAR is a string symbol containing a valid numeric the discussion under CO0:. literal or expression. Remember that RSX errors out rather RSX "@" for VMS Users RSX "@" for VMS Users * HTnn: RMT session, using the RSX native DECnet 14.25 F$PRIVILEGE terminal protocol. Probably interactive. Privilege under RSX is attached to your terminal * RTnn: SET HOST session, using the CTERM protocol. device. The privilege bit can be extracted from the second Probably interactive. word of your unit control block by: * VTnn: Virtual terminal session. Probably batch, .TESTDEVICE TI: but the RSX VT: driver corresponds more nearly to .PARSE "," JUNK JUNK S$UCW2 JUNK the VMS pseudoterminal driver, and can be used in .SETN N$UCW2 'S$UCW2' the same ways. For example, a logging task similar .SETN N$ZERO 0 to the one that came out on the VMS tape for Fall .IF N$ZERO <> 'S$UCW2'&10 . 1990 was distributed with RSX-11M+ V1.0. A command procedure being run by such a logging task would also be active on VTnn:. 14.26 F$SEARCH * CO0: Tasks run via DECnet or out of the clock queue. There is no good way do distinguish between This case is not covered by the ICP, though it would be the two cases; use whatever heuristic is nice. You can look for a specific file using the .TESTFILE appropriate to your environment. In addition, directive. If you're doing a wildcard search, the best way .TESTDEVICE will return CO0: as the equivalent of is to get SRD off the symposium tapes, use it to build a TI: only of the console logger is running; scratch file containing the names of the files you want, and otherwise, CO: is redirected to a real terminal .READ the file. You can also read directory files directly, (normally TT0:), and .TESTDEVICE will report the but this is both slower and more complex than the SRD name of that terminal. approach. 14.27 F$SETPRV 14.23 F$PARSE Not implemented. You could, of course, SET /NOPRIV=TI: Not implemented under RSX, though the PRMS$ service to lose privilege, but there's no way to undo it. The GIN$ under M+ gives a basis for it. There is a module in INDSYS directive toggles task privilege, not terminal privilege, that will at least take a filespec and pull it apart into and the M+ ICP is unprivileged anyway. its components. If you @LB:[1,2]INDSYS/LB:INDPRF filspc 14.28 F$STRING will come back containing This function is accomplished in a manner analogous to node\dev\direct\name\type\version\quals F$INTEGER. The VMS expression $ FOO = F$STRING (BAR) is equivalent to the RSX ICP directive with missing fields null. Unlike VMS, punctuation is NOT included in the output. .SETS FOO "'BAR'" Unlike the F$INTEGER case, there isn't much that can go wrong here. 14.24 F$PID RSX has neither processes nor process IDs. RSX "@" for VMS Users RSX "@" for VMS Users 14.29 F$TIME directive to turn on a full trace, and the corresponding .DISABLE directive to turn it off. The This lexical corresponds to the two ICP special symbols (which returns the current date), and