Previous section.

Systems Management: Common Management Facilities (XCMF)
Copyright © 1997 The Open Group

Command Line Interface

In order to provide the developer and the end-user system administrator with the ability to write implementations of methods and client programs in shell or other interpreted languages, several general purpose commands are defined. This effectively specifies a shell binding to OMG IDL.

One goal of a means to invoke operations defined in IDL using a shell script is to provide access to as many IDL operations as possible. Initially client programs are written for each IDL operation desired. This has the unfortunate side effect of requiring many executables in an environment, and requiring system administration environment providers to anticipate what an end user of the environment would like to do from the command line. Another goal of the effort is to provide a general purpose mapping that is easily parsed by a shell script and was natural for a shell programmer. The shell model of interacting with an ORB is to present ORB methods as programs that communicate using standard input and standard output. A consequence of this idiom is that any shell script that has side effects on standard input or standard output will break the linkage between the callee and the caller. Thus it is part of the IDL contract that standard input and standard output are not affected by side effects arising from the method being called.

The shell programmer should deal naturally with the data being used. For example, an instance of an IDL struct:

struct X { long a; string b; short c; };

might look like the following to a shell programmer:

{ 100000 "now is the time to do something" 20 }

A sequence of struct X might be:

{2 {100000 "now is the time ..." 20} {900000 "now it is too late" 40}}

To do this, a program is needed that can turn a client's input into this format. Conversely, a program is also needed that can take this as input and generate the appropriate "idl" invocation. The program will use the operation's type signature (possibly from an interface repository) to get rules for parsing the input and output.

If the needs of a shell script writer are examined, one can see how a script might be organized to provide the necessary functionality. First, the shell script writer needs access to the input arguments in some kind of native format. In the previous example, if a struct X is the input argument, the writer needs the struct in a string-like format that can be used and manipulated. Shells work with strings and shell variables - this is what is needed. If there are multiple arguments, the shell script writer needs to be able to get to each argument individually or as a group - much like $0 or $n in awk. Secondly, the shell script writer needs to pass values to other methods and receive their results. Thirdly, the shell script writers needs to return output arguments in a similar fashion to receiving input arguments. To do this requires some order on how results are returned.

Presume the signatures:

interface Intf1 { long foo( in Object tgt, in X x, inout string y, out X z ); }; interface Intf2 { long bar( inout X x, out string y ); };

The following script shows how operation foo is implemented using a shell script, and how the shell implementation can use bar.

#!/bin/sh
#
# interface Intf1 {
#	long foo (
#		in Object tgt,
#		in X x,
#		inout string y,
#		out X z
#	);
# }

# Get all of the idl input arguments into a shell variable
my_sigs = `idllookup Intf1`

# Alternatively, the signature could have been defined in an
# included file generated by an idl compiler.

inargs=`idlinput $my_sigs`

oper=`idlarg 1 $inargs`
self=`idlarg 2 $inargs`
if [ $oper -ne "Intf1::foo" ]; then
	idlexception {{tk_struct BAD_OPERATION}}
	exit 1
fi

tgt=`idlarg 3 $inargs`
x=`idlarg 4 $inargs`
y=`idlarg 5 $inargs`

# Call the bar method
# The target signature could be defined (perhaps in a file
# generated by an idl compiler) as
# 
#  tgt_sig = "tk_long Intf2::bar {
#		inout   x $X_tc
#		out     x tk_string
#	}"
# 
# or it could be retrieved from the interface repository via
# 
#	tgt_sig=`idllookup Intf2::bar`
# 
# See section 4.3.1 for the format of signatures.

bar_results=`idlcall $tgt $tgt_sig <<!EOF
$x
!EOF
`
if [ $? -ne 0 ]; then
# if an exception, the results have the stringified exception data
	idlexception $bar_results
	exit 1
fi

# now fetch the result arguments from bar's result string.
bar_long=`idlarg 3 $bar_results`
x=`idlarg 1 $bar_results`
bar_str=`idlarg 2 $bar_results`

# Pass the bar output back as the result to the caller.  Note
# that the order of the results is important (first the
# out/inout arguments in the same order as the IDL signature, 
# then the result (if any).
out_args=`idlresult ${mysig[0]} << !EOF
$bar_str
$x
$bar_long
!EOF
`
echo $out_args

exit 0

In the above script, the typecodes are directly supplied for the idlinput, idlcall and idlresult calls. If a signature passed into a command has the form:

{tk_indirect op-name}

then the command attempts to find the appropriate signature (perhaps using the interface repository).

Type Mappings

All types in the string-based binding must be represented by strings. The same rules that apply to manipulating strings in the Bourne shell apply here. The strings are delimited by spaces, not commas.

All scalar types will be represented by a string. Boolean true is represented by TRUE and false is represented by FALSE. All constructed types (array, sequence, struct, union) are described by listing their members enclosed within a pair of {}. The following are more explicit rules.

Argument Ordering

When an IDL interface is mapped to this binding, on invocation only the in and inout arguments are placed in the input stream to the command. Thus, all out parameters are omitted during the invocation. When results are returned, the out and inout parameters and then return value are placed in the results stream. The out and inout parameters are in the same order of appearance as the IDL definition of the operation. As an example, if the IDL definition of an operation is as follows:
long op1(in long a1, out long a2, inout long a3, out long a4);

and $A1 is the string version of a1, and $A2 the string version of a2, etc., then to call op1 from a shell the command would be:

# target signature obtained directly (or via compiler generated code): # # tgt_sig = "tk_long Intf3::op1 { # in a1 tk_long # out a2 tk_long # inout a3 tk_long # out a4 tk_long # }" # # or via the interface repository: # # tgt_sig = `idllookup Intf3::op1` $op1_results=idlcall $tgt $tgt_sig << !EOF $A1 $A3 !EOF T

The results stream, contained in op1_results, will have the string version of a2, a3 and a4, then the long specified by the return value of operation op1.

Defined Commands

This section defines the commands necessary for the invocation of operations, receipt of input, output and exceptions in natural shell style, and the parsing of arguments in a shell variable.

The idlcall Command

The idlcall command has the following syntax:
idlcall target signature [arg1 [arg2 ...]]

This command may accept arguments either from the command line or from standard input. If any arguments (that is, those items marked arg[n] in the above syntax) are specified on the command line, then standard input will be ignored. This command will invoke the IDL defined operation described by signature on the object represented by target: target is a stringified object reference. An IDL attribute X is mapped to the methods "_get_X" and "_set_X". The initial "_" ensures that these methods will not collide with method names that may be explicitly declared in the interface. Read-only attributes do not have a "_set_X" method. The arguments passed will be converted into the proper in-memory format, as defined in the IDL interface, in their order in the argument list. Only in and inout parameters should be present in the parameter list. The results will be returned with the return parameter of the operation as the first element in the results and the remainder in the order of their position in the parameter list. Only inout and out parameters are returned in addition to results. The resulting strings are written to standard output.

If the invocation of the operation results in the raising of an exception, only exception information will be contained in the results passed to standard out. When an exception is raised, the idlcall command exits non-zero. An exception is returned in the result parameter as an Any (that is, {type-code value} ).

The signature used in the call has the following form:

{return-typecode operation-name {direction param-name parm-typecode ... (repeat triple)} {exception-typecode ... (list all exceptions)}}

Signatures may be specified explicitly or may be obtained via idllookup (see The idllookup Command . It is expected that explicitly specified signatures will be obtained from included files emitted by idl compilers.

If a signature has the form:

{"tk_indirect" operation-name},

then the actual signature will be supplied by the command (possibly using an interface repository).

The idlinput Command

The idlinput command has the following syntax:
idlinput signature-list

This command returns the input passed to an operation implemented in shell and converts it to string form for processing/parsing in the shell implementation. The results of the conversion are written to standard output.

The signature-list is a list of method signatures (including "_get_X "and "_set_X" methods associated with attributes) that the shell script implements. The result of this call will be of the form:

{operation-name object-id in-arg1 in-arg2 ...}

arg 1 of the results that appear on stdout will be the stringified object reference for the current shell; arg 2 of the results will be the the method actually being invoked.

The idlarg Command

The idlarg command has the following syntax:
idlarg op_name parameter_num arg

This command accepts the operation name, op_name, the numeric 1-based position of the desired attribute and the parameters. The position is the number of the parameter in the argument list, that is, the first parameter is in position 1, the second in position 2, etc., parameters contains the formatted string of parameters. Please note that the operation_name and the object_id are returned as the first 2 parameters from the idl_input command.

This command is also capable of extracting particular items or elements of structures, sequences, etc. This is achieved by extracting the complex type using idlarg and then using idlarg to extract components of the complex type.

The idlresults Command

The idlresults command has the following syntax:
idlresults signature [results]

This command returns the results of the method specified by the signature, whose format is defined in The idlcall Command , to a shell implementation. The format of the results is the string representation of the return value and the inout/out parameters of the IDL operation. The results strings are read from standard input or are provided in an argument list on the command line.

The idlexception Command

The idlexception command has the following syntax:
idlexception results-as-any

This command extracts the string form of the exception data from results, and writes this information to standard output.

The idllookup Command

The idllookup command has the following syntax:
idllookup -s name idllookup -t name

The first form returns the signature of name, which may be a fully-qualified interface name, operation name, or attribute name. For an interface name, the result of the call is a signature list for the interface, suitable for passing to idlinput. For an operation name, the result of the call is the signature of the operation, suitable for passing to idlcall or idlresult. For an operation name, the result is the two operation signatures describing the attribute's "get" and "set" methods. A read-only attribute will return a single signature, for the "get" method.

The second form returns the typecode associated with name, which may be a fully-qualified type (including interface) name or interface name.

The two forms are needed to resolve the ambiguity in the case of interfaces and attributes.

The operation is undefined when called with the fully-qualified name of a module.


Why not acquire a nicely bound hard copy?
Click here to return to the publication details or order a copy of this publication.

Contents Next section Index