(PYVMS LOGO) Python on OpenVMS

(go to: table of contents, index)

This section gives some guidelines how to use the programming interface to OpenVMS routines.

functions

arguments

Some functions (e. g.: vms_lib.currency) do not have any arguments. If you provide any, then the programming interface WILL raise a Python exception. The redundant argument is not silently ignored!

Some arguments of a function might not apply in a specific situation. As keyword arguments are not implemented you have to insert 'None' instead. See the examples of vms_lib.day() or vms_lib.getdvi() to get an idea.

OpenVMS system services usually require ALL arguments be specified. The Python interface routines usually substitute 'None' with '0 passed by value' to indicate an omitted argument. They also allow trailing 'unused' arguments to be omitted.

keyword arguments

e.g.: >>> ret = routine (p1 = val1)
are not supported for OpenVMS interface routines.

functions returning no data

Some routines do not need to return any 'data' - e.g. vms_lib.attach() returns 'None' upon successful completion. If an error happens, they will still raise a Python exception.

functions returning dictionaries

Some routines like 'vms_sys.getjpiw()' need to return a variable amount of data depending on its input parameters (the item list in this case). The data is stored under different 'keys' in a dictionary.

Using a tuple or a list would raise the question of which data is stored at which position.

OpenVMS condition values

Using the native interfaces a programmer should _always_ check the returned condition value. Some routines also use the OpenVMS condition mechanism to signal errors, but a programmer should not rely on it.

Almost all routines within Python do not return the 'status' code from the underlying OpenVMS service. They use the Python model of raising a Python exception when an error happens.

There are some routines which behave differently - e.g. vms_lib.set_logical(). The reason for this is a uniform style of returning data - in this case it is a dictionary. Routines with different status values that can indicate success do not raise an exception, too.

The vms_sys.getmsg() routine allows the translation of the code into its text message:

    >>> import vms_sys
    >>> print vms_sys.getmsg(0x2c)
    ('%SYSTEM-F-ABORT, abort', (0, 0, 0, 0))
    >>>
See the 'reference manual' for details.

special OpenVMS datatypes

Python on OpenVMS does not have a builtin 64-bit or 128-bit datatype.

64-bit quadword

These are usually simulated by using Python's "long integer" datatype. See vms_sys.gettim() or vms_sys.asctim() for examples. An exception are quadwords that are used for rightslist identifiers - see the explanation more below this text.

Using a "long integer" does allow the programmer to do calculations within Python. See the next section.

Date and time values are returned as a signed long integer, however bitmasks like privileges are returned as an unsigned long integer.

date and time calculations

An OpenVMS binary date + time is internally represented by a signed quadword. A positive value (including 0) indicates an absolute date + time (e.g. 29-FEB-2000 12:34:45.78). A negative value means a delta time (12 21:56:34.91), meaning 12 days, twenty-one hours, fifty-six minutes, thirty-four seconds and 91 hundredth of a second.

Although an OpenVMS 'delta time' is represented by a negative value it does not have a "direction". If you see something like "+01:00:00" - this is a 'combination time' - it means "add one hour to the current date + time".

Let's do some examples:

    >>> import vms_lib, vms_sys
If you are like me and always forget VMS' base date:
    >>> vms_sys.asctim (0L)
    '17-NOV-1858 00:00:00.00'
    >>>
The smallest increment is 100 nanoseconds. It's easy to find out how many of these 'ticks' are in a second:
    >>> vms_sys.bintim ('17-NOV-1858 00:00:01.00')
    10000000L
    >>>
Warning! The trailing 'L' shows that this is a Python 'long integer'. This is not a delta-time! '10000000L' really indicates the 17th of November in the year 1858, one second after midnight.

Now, a one-second delta time:

    >>> vms_sys.bintim ('0 00:00:01.00')
    -10000000L
    >>>

Let's use a different date:

    >>> feb29_y2k = vms_sys.bintim ('29-FEB-2000 12:34:56.78')
    >>> feb29_y2k
    44585444967800000L
    >>>

Calculate one second.

    >>> one_second = vms_sys.bintim ('0 00:00:01.00')
    >>> one_second
    -10000000L
    >>>

To add one second, we have to subtract the delta-time:

    >>> new_time = feb29_y2k - one_second
    >>> new_time
    44585444977800000L
    >>> vms_sys.asctim (new_time)
    '29-FEB-2000 12:34:57.78'
                        *
    >>> print new_time - feb29_y2k
    10000000L
    >>>

Remember: this value does NOT represent a one-second 'delta-time'!

There are also OpenVMS RTL routines to do date + time calculations:

    >>> new_time_2 = vms_lib.add_times (feb29_y2k, one_second)
    >>> new_time_2
    44585444977800000L
    >>> vms_sys.asctim (new_time_2)
    '29-FEB-2000 12:34:57.78'
                        *
    >>>

This routine, however, has some restrictions. Please see 'REFMAN Modules, vms_lib module, vms_lib.add_times' for details.

To subtract a delta time from an absolute date + time using Python's long integer datatype you have to ADD both values. There is also an OpenVMS RTL routine for this - see 'REFMAN Modules, vms_lib module, vms_lib.sub_times()'.

128-bit octaword

These are simulated by using Python's "long integer" datatype. See vms_sys.getutc() or vms_sys.ascutc() for examples.

Using a "long integer" does allow the programmer to do calculations within Python.

processes

privileges

A Python on OpenVMS executable is not meant to be installed (via $INSTALL) with any privileges! It is possible to turn off these elevated privileges by a call to vms_sys.setprv (), but a user can always just '$RUN' the Python executable...
The user can also enable additional privileges from his authorized privilege mask or turn on any privilege if he has the SETPRV privilege by calling vms_sys.setprv().

---

Privilege bitmask values are stored in module 'vms_prvdef'. @@ Ignore the 'PRV$_NULL' item code in this module. It is a work-around to a deficy in the VMSDEF2MAR.COM procedure which currently cannot cope with a VMSDEF module that has no item codes.

A privilege bitmask is 64 bits wide. All bit definitions in 'vms_prvdef' are defined as Python long integers.

>>> import vms_prvdef
>>>
>>> # a bit in the first longword
>>> vms_prvdef.PRV_M_ALLSPOOL
16L
>>> type (vms_prvdef.PRV_M_ALLSPOOL)
<type 'long int'>
>>>
>>> # a bit in the second longword
>>> hex (vms_prvdef.PRV_M_READALL)
'0x800000000L'
>>> type (vms_prvdef.PRV_M_READALL)
<type 'long int'>
>>>

Since 14-FEB-1999 it is no longer necessary to convert the bitmasks from a Python integer (32-bit) to a Python long integer (64-bit) because a BITMASK64 structure has been implemented. The following bits are still defined in the 'vms_prvdef' module with their (32-bit) values in the second longword:

PRV_M2_UPGRADE, PRV_M2_DOWNGRADE, PRV_M2_GRPPRV, PRV_M2_READALL, PRV_M2_IMPORT, PRV_M2_AUDIT, PRV_M2_SECURITY.
(_M2_ indicates that this bit is located in the 2nd longword.)

'vms_prvdef' also includes the bits with the '_M_' code and their real 64-bit value. See the example of PRV_M_READALL above.

Privileges are used, for example, in the following routines: vms_lib.getjpi(), vms_sys.creprc(), vms_sys.getjpiw(), vms_sys.getuai(), vms_sys.process_scan() and vms_sys.setuai().

process identification (PID)

OpenVMS DCL utilities use an 8-character hex number as input and output for the PID and translate it internally because system services and run-time library routines use a binary longword.

Within Python on OpenVMS a PID must always be specified as an integer data type - it is never a hex-string. e.g.:

$ PID = F$GETJPI(0,"PID")
$ show symbol PID
PID = "0000021A"
$ NUMBER = %X'PID'
$ show symbol NUMBER
NUMBER = 538 Hex = 0000021A Octal = 00000001032
$

You have to use the number '538' within Python.

>>> ctx,data = vms_lib.getjpi("JPI$_IMAGNAME",538)
>>> print data
DKA100:[PYTHON.PYTHON-1_5_1.VMS]PYTHON_ALPHA.EXE;1
>>>

('ctx' is either the process' PID or, during wildcard lookups, a context value. Please see the description of vms_lib.getjpi() for details.)

Several system services (SYS$DELPRC, SYS$FORCEX, ...) return the target process' PID if you specifiy 0 for the PID argument and a process name.

For consistency the Python interface always returns the target process' PID - no matter if you specify an explicit PID or use the process name argument.

---
Almost all examples in this documentation use a 'low' value for the PID. This is because development happens on non-clustered OpenVMS systems.

rightslist identifiers

Identifiers (UIC and general) and their attributes are represented as Python integers (32-bit values). The 'vms_kgbdef' module contains the attribute bitmask values (KGB_M_name). Translation to / from the names can be done using the vms_sys.asctoid() and vms_sys.idtoasc() routines.

Some system services like vms_sys.add_holder() require a quadword containing the identifier in one of the longwords. The other usually is used for the attributes. In this case the interface routines do not use a single Python long integer but a tuple of 2 integers.

security related objects

ACL + ACE

An ACL (Access Control List) is made up from one or more ACEs (Access Control list Entries). They are stored inside normal Python strings.

Warning!
ACEs are a set of bytes, not a set of printable characters. You should not output a binary ACE/ACL to a terminal, because the data stream can contain control sequences that alter the terminal's settings. Using the 'repr()' builtin is safe:

    >>> print repr (acestr)
    '\014\001\000\000\020\000\000\000\004\000\003\000'
    >>>

The vms_sys.format_acl() routine accepts a binary ACE and translates it in its ASCII equivalent. The vms_sys.parse_acl() routine accepts an ASCII string and translates it to the binary representation that is used inside OpenVMS.

The vms_sys.get_security() routine and the 'vmsobj_xabpro' object can be used to retrieve ACLs or ACEs from files and other objects (not via XABPRO).


(go to: table of contents, index)

21-AUG-1999 ZE.