Operating System - OpenVMS
Showing results for 
Search instead for 
Did you mean: 

modifying logical name value using a Cobol program

Occasional Visitor

modifying logical name value using a Cobol program

Hi all,

as the tittle says I am trying to modify the value of a defined logical name, I have been trying to find the solution to this and I have found on a lot of urls...

"Call SYS$TRNLNM to retrieve the current equivalence names, modify them, and... blahblahblah "

but I cannot find how to use it to modify the value...


Can you help me, please?


Thanks a lot.

Duncan Morris
Honored Contributor

Re: modifying logical name value using a Cobol program

Welcome to the OpenVMS forum!


SYS$TRNLNM is used to translate (i.e. read) the logical names.


You would want to use SYS$CRELNM to create/modify logical names.

You can also use the equivalent LIB$SET_LOGICAL routine for supervisor mode logical names.


Details can be found in the the Programming Concepts manual







Respected Contributor

Re: modifying logical name value using a Cobol program

Duncan has it correct.


Please realize as well that all the usual rules apply in regards to privs.  If the logical name is in the group or system table, the appropriate privs are required for the process.  Also, there are qualifiers to the CRELNM service to indicate the table etc that must be defined.



Honored Contributor

Re: modifying logical name value using a Cobol program

The LIB$GET_LOGICAL routine is easier to code and call than are the sys$trnlnm and related system services, when calling from non-pointer languages.    (Some of the lib$ calls will parallel the sys$ calls, and use APIs that are easier to access from COBOL, BASIC or older (pre-pointer) Fortran.


There are various examples of calling system routines available from HP.  Some have been published, but I'd expect HP has additional examples available.


Here are the names of some of the old support articles for system services with APIs similar to sys$trnlnm and sys$crelnm and related, and the HP support center folks may (will?) be able to get you copies of these articles and other calls:


    Example-COBOL Using $SNDJBCW To Enter A File In A Print Queue

    Example-COBOL Using $SNDJBCW To Start And Stop A Batch Queue

    Example-COBOL Using $SNDJBCW To Submit A Batch Job With Parameters

    Example-COBOL Using SYS$SNDJBCW To Alter A Print Queue

    Example-COBOL Putting >1 Wildcard Files Into Single Print Job


Published COBOL examples include these:






The lib$set_symbol call in that second example is comparatively similar to the lib$set_logical call.


You will not find examples of everything posted, so (in general) you will need to learn the argument-passing rules from COBOL applications for some of the core system service calls (which do have examples in the COBOL manuals or posted at HP), and then generalize and work outward from there. 


Bob Blunt
Respected Contributor

Re: modifying logical name value using a Cobol program

This might be helpful, too?




It looks like some of the example programs that were available from STARS/EIRS/DSN may be available at that URL from Philippe Vouters.



John Gillings
Honored Contributor

Re: modifying logical name value using a Cobol program



   The logical name interfaces provide for "lookup" and "create" operations only. There is no separate "modify" operation. To modify an existing logical name, just create it again. The new value will replace the old.


   SYS$TRNLNM and SYS$CRELNM are the low level interface to logical name tables. They have the broadest level of functionality, but are a bit complex to code (system service item lists are especially ugly in COBOL), and typically require privilege to do anything really useful (see belog)


  LIB$GET_LOGICAL and LIB$SET_LOGICAL are limited to the most common operations and are much simpler and obvious to code and do not require privilege for those operations which are unprivileged from DCL.


  Two words of warning...


1) Logical names are case sensitive and can be mixed case. It's relatively uncommon to see mixed case logical names since DCL automatically upcases unquoted parameters. When using the system service or LIBRTL interface it's easy to inadvertently define a mixed or lower case logical name and then be confused as to why it's apparently not used from DCL. Before V4.0 it wasn't possible to access lower case logical names from DCL at all!


2) "Normal" logical names defined from DCL are SUPERVISOR mode. Your code runs in USER mode. Logical names in the process table defined in USER mode are automatically DEASSIGNED at image exit. If you code a call to $CRELNM to define a process logical name from a user mode program it will succeed, and the logical name will exist for the duration of that image, but will be deleted when you exit to DCL. This can be very confusing! What's worse, even if you specify mode PSL$C_SUPER to $CRELNM, it will be maximised against your current mode (PSL$C_USER), which means it's silently changed back to USER, and again your logical name is deleted at image exit. You need SYSNAM privilege to override this behaviour and define a SUPERVISOR mode logical name from a USER mode program.


LIB$SET_LOGICAL has a kind of special dispensation to define SUPERVISOR mode logical names on behalf of USER mode processes. If you want to manipulate logical names which will persist beyond the execution of your image, you should use LIB$SET_LOGICAL to define them. (but, that means LIB$SET_LOGICAL only works from processes which a CLI, thus not in a detached process without a CLI).

A crucible of informative mistakes
Richard J Maher
Trusted Contributor

Re: modifying logical name value using a Cobol program

Here are some snippets: -
01  lnm_mbx_list.
    03  item_string.
        05                          pic s9(4)       comp    value   10.
        05                          pic s9(4)       comp    value   external        lnm$_string.
        05                                          pointer value   reference       lnm_system.
        05                          pic s9(9)       comp.
    03                              pic s9(9)       comp.
01  lnm_system                      pic x(10)               value   "LNM$SYSTEM".
    call "sys$crelnm"
        using   by value 0
                by descriptor "LNM$PROCESS_DIRECTORY", "LNM$TEMPORARY_MAILBOX"
                by value 0
                by reference  lnm_mbx_list
        giving  sys_status.
    if sys_status not = ss$_normal and ss$_supersede
        call "lib$stop" using by value sys_status.

Respected Contributor

Re: modifying logical name value using a Cobol program



Shouldn't the statement:  "if sys_status not = ss$_normal and ss$_supersede "  actually be "OR".


In the case of creating the logical name that does not exist, the SS$_SUPERCEDE will not be returned.  Only on subsequent logical name updates.  For you sepcific example, the code will work as described.



Honored Contributor

Re: modifying logical name value using a Cobol program

I'd implement a low-bit test there, given that the code shown is only testing for failure.


In general: Low Bit Clear (LBC) for generic error tests.   Low-bit Set (LBS) for success.  (It's also possible to process conditions by error severity, though that's not as commonly needed nor implemented.)


The low-bit test can simplify and clarify the code, and the intent of the programmer, and it would also correctly process any other condition values that might also happen to be returned.


While it's unlikely that this OpenVMS routine will see additional condition codes added, there's no extra cost in correctly contending with that possibility here using LBS or LBC testing.  (And who knows, there may be a corner case within the existing code that kicks back an undocumented successful/LBS or error/LBC code, too.)

Richard J Maher
Trusted Contributor

Re: modifying logical name value using a Cobol program

@abrsvc: You're wrong or you misunderstand the COBOL condition check. The NOT mandating the AND. (It's always not going to be equal to one of them so and OR wouldn't be much use.)


@steve: But you would say that wouldn't you; and have done on countless occasions. I certainly use the BLBx convention when coding MACRO-32 and don't really have a problem with it in HLLs but (for readability and deterministic[ability?]) it never hurts to be explicit. There are also many occasions when one would like to branch logic around whether or not the logical already existed (or whether a string was truncated or any other alternate success status)

John Gillings
Honored Contributor

Re: modifying logical name value using a Cobol program



   Your code is certainly correct, and will do what you intend, but the resulting logical name will be USER mode. Since in your case, the logical name is defined in LNM$PROCESS_DIRECTORY, it will survive image run down. But, if the code were modified for the more common usage of logical names, defined in the LNM$PROCESS table, the logical name would be deleted at image run down, which is probably not what is intended and can be very confusing to debug.


I'd guess that since you're redirecting temporary mailboxes to the system table (interesting concept...) you must have fairly high privilege, which you could use to override user mode.


Wouldn't it be much simpler to say:


  GIVING sys_status.

 Of course, it would be more interesting go the other way and use SYS$CMEXEC to get the logical name defined in SUPER mode, but maybe not a good recommendation for Juda.


I'm also curious about your status check. You're saying that in Cobol the expression:


   sys_status not = ss$_normal and ss$_supersede


is equivalent to:


  (sys_status not = ss$_normal) and (sys_status not = ss$_supersede)


rather than:


  sys_status not = (ss$_normal and ss$_supersede)


I can see why many folk would find that confusing. Cobol has some rather unique syntax.


A crucible of informative mistakes
Dennis Handly
Acclaimed Contributor

Re: modifying logical name value using a Cobol program

>COBOL has some rather unique syntax.


Yes.  :-)  You also have level 88s where you can test a variable for a whole list of values and ranges.