This topic includes the following sections:
Oracle Tuxedo TxRPC supports the IDL grammar and associated functionality as described in Chapter 3 ("Interface Definition Language") of DCE: REMOTE PROCEDURE CALL (Doc Code: P312 ISBN 1-872630-95-2). This book is available from the following.
X/OPEN Company Ltd (Publications)
P O Box 109
Penn
High Wycombe
Bucks HP10 8NP
United Kingdom
Tel: +44 (0) 494 813844
Fax: +44 (0) 494 814989
The X/OPEN document is the ultimate authority on the language and rules adhered to for the Oracle Tuxedo product in an ATMI environment. Note that the X/OPEN TxRPC IDL-only interface is supported (parts of the document concerning the DCE binding and run time do not apply). The X/OPEN document is based on the OSF DCE AES/RPC document. There are several books containing tutorials and programmer's guides that can be used, although most will not contain the latest features. The programmer's guide available from OSF is OSF DCE Application Development Guide, published by Prentice-Hall (Englewood Cliffs, New Jersey, 07632).
The X/OPEN Preliminary Specification for TxRPC Communication Application Programming Interface is also available from X/OPEN (see above). TxRPC adds transaction support for RPCs to the original X/OPEN RPC interface.
A Universal Unique Identifier (UUID) is used to uniquely identify an interface. The uuidgen
command is used to generate UUIDs. The output might look something like the following:
$ uuidgen -i > simp.idl $ cat simp.idl [uuid(816A4780-A76B-110F-9B3F-930269220000)] interface INTERFACE { }
This template is then used to create the IDL input file for the application (adding type definitions, constants, and operations).
If both the ATMI and DCE uuidgen(1)
commands are available, the DCE command can and should be used to generate the template (the DCE version will most likely have a machine-specific approach to getting the node address, as described below).
The ATMI uuidgen
command is similar to the DCE command with the exception that the -s
option (which generates a UUID string as an initialized C structure), and the -t
option (which translates an old style UUID string to the new format) are not supported. See the uuidgen(1)
reference page for details of the interface.
The uuidgen
command requires a 48-bit node address as described in ISO/IEC 8802-3 (ANSI/IEEE 802.3). There is no platform-independent way to determine this value, and it may not be available at all on some machines (a workstation, for example). The following approach is used for the ATMI uuidgen
command:
If the NADDR
environment variable is set to a value of the form num.num.num.num.num.num
where num
is between 0 and 255, inclusive, it is taken to be an Internet-style address and converted to a 48-bit node address. This allows conformance with the use of the 8802-3 node address. It also allows users who do not have access to this address to use another value, most likely the Internet address (which is not the same as the 8802-3 address). If the Internet address is used, the last num.num
should be 0.0 (because Internet addresses are only 32-bit addresses).
If the NADDR
environment variable is not set and if the WSNADDR
environment variable is set to a value of the form 0xnnnnnnnnnnnnnnnn
it is taken to be a hexadecimal network address, as used in Workstation. Again note that this is not the 8802-3 address, and the last 16 bits will be treated as zeros.
If neither the NADDR
nor the WSNADDR
environment variable is set (and if not Windows), the uname
for the machine is used to look up the machine entry in /etc/hosts
to get the Internet-style address.
If the first three choices are not available, a warning is printed and 00.00.00.00.00.00 is used. This is not desirable because it reduces the chance of generating a unique UUID.
The IDL compiler recognizes the IDL grammar and generates stub functions based on the input. The grammar and its semantics are fully described in both the X/OPEN and OSF/DCE references listed earlier in this chapter. The grammar will be recognized in its entirety with some changes as described in the following sections.
The following are changes to the base X/OPEN RPC specification that are defined by the X/OPEN TxRPC specification:
The most important enhancement from the TxRPC specification is the addition of the [transaction_optional]
and [transaction_mandatory]
attributes in the interface and operation attributes in the IDL file. [transaction_optional]
indicates that if the RPC is done while in a transaction, the remote service is done as part of the transaction. The [transaction_mandatory]
attribute requires that the RPC be done within a transaction. Without these attributes, the remote service is not part of any transaction of which the client may be part.
Binding types and attributes are not required by X/OPEN TxRPC IDL-only. The binding attributes are [handle]
, [endpoint]
, [auto_handle]
, [implicit_handle]
, and [explicit_handle]
. They are recognized by tidl(1)
but not supported (these attributes are ignored). Also the handle_t
type is not treated specially (it is transmitted as any other defined type is transmitted, without treatment as a handle).
Pipes are not required by X/OPEN TxRPC IDL-only. tidl
supports pipes only in [local]
mode; that is, they can be specified for header file, but not stub, generation.
The [idempotent]
, [maybe]
, and [broadcast]
attributes are not required by X/OPEN TxRPC IDL-only. They are ignored by tidl(1)
.
The following are enhancements to the X/OPEN RPC specification. In most cases, the language has been enhanced to more closely follow the C language, simplifying the porting of existing interfaces (converting from ANSI C to IDL prototypes).
In the X/OPEN specification, character constants and character strings are limited to the portable set, that is space
(0x20) through tilde
(0x7e). Other characters in the character set (0x01 through 0xff) are allowed, as in OSF DCE RPC.
As in C, the following operators are treated as punctuators.
││ && ? │ & _ == != = << >> <= >= < > + - % ! ~
This means that white space need not follow or precede identifiers or numbers if preceded or followed by one of these tokens. (The IDL specification requires white space, as in a = b + 3
, instead of allowing a=b+3
.) This also seems to be the behavior of the OSF DCE IDL compiler.
The published X/OPEN specification restricts field and parameter names from matching type names. This restriction effectively puts all names in a single name space. This restriction does not match C, C++, or the OSF IDL compiler, and is not enforced.
The X/OPEN specification does not allow anonymous enumerations as parameter or function results and does not allow anonymous structures or unions as the targets of pointers. Each of these is allowed by the OSF DCE IDL compiler. These restrictions are not enforced; in each case, a name, based on the interface name and version, is generated for use during marshalling.
Enumeration values (constants) may be used in integer constant expressions (as in C). This also seems to be the behavior of the DCE IDL compiler.
As currently defined in the X/OPEN RPC specification, the grammar does not allow for a pointer in front of an operation declaration, for example:
long *op(void);
nor does it allow for structure or union returns. While this could be considered correct (everything could be hidden in a defined type), the DCE IDL compiler and, of course, C compiler allow a much richer operation return. The supported grammar will be the following:
[operation_attributes] <type_spec> <declarator>
where <declarator>
must contain a <function_declarator>
. (If a <function_declarator>
does not exist, then a variable is declared, which results in an error.) Declaring an array of operations or an operation returning an array (both allowed by this grammar) will be detected and flagged as an error.
The <ACS_type_declaration>
takes <ACS_named_type>
values, just as the IDL <type_declaration>
takes a list of declarators. This seems to be the behavior of the DCE IDL compiler.
Fielded buffers created and manipulated with the Field Manipulation Language (FML) are an integral part of many Oracle Tuxedo ATMI applications. Fielded buffers are supported as a new base type in the IDL. They are indicated by the keywords FBFR
for 16-bit buffers and FBFR32
for 32-bit buffers and must always be defined as a pointer (for example, FBFR *
or FBFR32 *
). A fielded buffer cannot be defined as the base type in a typedef
. They can be used in structure fields and as parameters. They can be used as the base type in an array or pointer (either full or reference pointer). However, conformant and varying arrays of fielded buffers are not supported.
There are several restrictions in the OSF IDL compiler that are not documented in the AES or X/OPEN RPC specification. These are enforced in the Oracle Tuxedo IDL compiler:
A transmitted type used in [transmit_as()
] cannot have the [represent_as
] attribute.
A union arm may not be or contain a [ref
] pointer.
If a conformant and/or varying array appears in a structure, the array size attribute variable may not be a pointer (that is, it must be a non-pointer, integer element within the structure).
There are four additional Oracle Tuxedo ATMI enhancements to the X/OPEN RPC specification that, while making the specification more C-like, are not supported in the OSF DCE IDL compiler and thus have the effect of limiting portability of the IDL file:
String concatenation is supported (as in ANSI C). That is:
const char *str = "abc" "def";
is treated the same as
const char *str = "abcdef";
Escaped newlines are allowed in string constants. That is:
const char *str = "abc\ def";
is treated the same as
const char *str = "abcdef";
Enumeration values may also be used in union cases and are treated as integers (that is, automatic conversion is provided as in C).
The restriction that the type of each <union_case_label>
must be that specified by the <switch_type_spec>
will not be enforced. Instead, the type will be coerced as is done with case statements in a C switch statement.
The following seven features are not supported in the tidl
compiler:
The migration attributes [v1_struct]
, [v1_enum]
, [v1_string]
, and [v1_array]
are recognized but not supported (these appear in the OSF IDL specification but not the X/OPEN specification).
Function pointers (defined in the OSF/DCE document) are supported only in [local]
mode (as in OSF/DCE).
An exact match is required on interface version minor between the client and the server (the X/OPEN RPC specification allows for the server version minor to be greater than or equal to the version minor specified by the client).
On machines with 32-bit longs, integer literal values are limited to -2**31 to 2**31. This means that unsigned long integer values in the range 2**31+1 to 2**32-1 are not supported. This also seems to be the behavior of the DCE IDL compiler.
Context handles are supported only in [local]
mode. Interfaces cannot be written that use context handles to maintain state across operations.
The [out-of-line]
ACS attribute is ignored. This feature is not defined in a way that will support interoperation between different implementations (e.g., with the OSF IDL compiler).
The [heap]
ACS attribute is ignored.
The interface for the IDL compiler is not specified in any X/OPEN specification.
For DCE application portability, the Oracle Tuxedo ATMI IDL compiler has a similar interface to the DCE IDL compiler, with the following exceptions:
The command name is tidl
instead of idl
so an application can easily reference either when both appear in the same environment.
The -bug
option, which generates buggy behavior for interoperability with earlier versions of the software, has no effect. The -no_bug
option also has no effect.
The -space_opt
option, which optimizes the code for space, is ignored. Space is always optimized.
A new option, -use_const
, is supported. -use_const
generates ANSI C const
statements instead of #define
statements for constant definitions. This gets around an annoying problem where a constant defined in the IDL file collides with another name in the file using a C-preprocessor definition, but is properly in another name space when defined as a C constant. Use of this feature will limit portability of the IDL file.
By default, /lib/cpp
, /usr/ccs/lib/cpp
, or /usr/lib/cpp
(whichever is found first) is the command used to preprocess the input IDL and ACF files.
By default, the IDL compiler takes an input IDL file and generates the client and server stub object files. The -keep c_source
option generates only the C source files, and the -keep all
option keeps both the C source and object files. The sample RPC application, listed in Appendix A, "A Sample Application," uses the -keep object
option to generate the object files.
By default, at most 50 errors are printed by tidl
. If you want to see them all (and have more than 50 errors), use the -error all
option. The error output is printed to the stderr
.
See tidl(1)
in the Oracle Tuxedo Command Reference for details on the many other options that are available.