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:
might look like the following to a shell programmer:
A sequence of struct X might be:
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:
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:
then the command attempts to find the appropriate signature (perhaps using the interface repository).
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.
-
-
tk_null
tk_void
tk_short
tk_long
tk_ushort
tk_ulong
tk_float
tk_double
tk_boolean
tk_char
tk_octet
tk_string
tk_any
tk_TypeCode
tk_Principal
{tk_objref interface-id}
{tk_struct struct-name member-name TypeCode, ... (repeat pairs)}
{tk_exception exception-name member-name TypeCode, ... (repeat pairs)}
{tk_union union-name switch-TypeCode label-value member-name
TypeCode, ... (repeat triples)}
{tk_enum enum-name enum-id ...}
{tk_sequence typecode maxlen-integer}
{tk_array typecode length-integer}
-
-
{tk_long 10}
{{tk_struct X a tk_long b tk_string} {10 "hello world"}}
-
-
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:
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.
-
-
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:
Signatures may be specified explicitly or may be obtained via
idllookup
(see
If a signature has the form:
then the actual signature will be supplied by the command (possibly using an interface repository).
-
-
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:
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.
-
-
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.
-
-
idlresults signature [results]
This command returns the results of the method specified by
the
signature,
whose format is defined in
-
-
idlexception results-as-any
This command extracts the string form of the exception data from results, and writes this information to standard output.
-
-
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.
Contents | Next section | Index |