• Keine Ergebnisse gefunden

Passing Arguments to Invoked Programs

Managing Programs

3.3. Passing Arguments to Invoked Programs

handle, status) check_status;

{communicate with child}

{cut the child loose}

{program name}

{name length}

{no args}

{std. streams}

{default mode}

{process handle}

pgm $make orphan (handle , {process handle}

- - puid, {process uid}

status);

Example 3-5. Converting a Child Process to an Orphan Process (Cont.)

3.3. Passing Arguments to Invoked Programs

In addition to specifying the mode in which an invoked program is to run, PGM_ $INVOKE permits the passing of arguments to the. invoked program. The third and fourth parameters of the PGM _ $INVOKE call are the argument count and argument vector, respectively. The argument count is a 2-byte integer specifying the number of arguments being passed. The argument vector is an array of pointers to the arguments being passed. The argument vector is of the type PGM _ $ARGV, which is an array of UNIV _ PTR types.

A program can pass any number of arguments to a program it is invoking. However, when passing arguments to a Shell, the Shell's syntax limits the number of arguments to 10 (including program name). Each argument must be preceded by a 2-byte integer indicating the number of bytes in the argument. The first argument mu~t be the name of the program -- the simple name, not the full pathname (i.e., date, not / /deedle/com/date).

DOMAIN provides a predefined record type, PGM_ $ARG, which is a 128-byte character array preceded by a 2-byte integer. Whether you choose to use the predefined argument type, or declare a argument type of your own, will depend on the length of the passed arguments and how critical storage is to your program.

Figure 3-1 illustrates the argument vector/argument arrangement.

Returned Array of Retrieved Argument

Pointer Pointers Records

index

pointer

~

0: pointer argJen arg_text

1 : pointer argJen arg_text

n: pointer

~I

L-_ar_g ___ le_n_L--a_r_g __ t_e_x_t...J

Figure 3-1. Argument Vector/Argument Configuration

The program in Example 3-6 invokes a program (in a child process) and passes two arguments:

the invoked program name and a text string. (Remember, the name of the invoked program must be passed as the first argument.)

PROGRAM pgm_pass_args (input.output);

%include '/sys/ins/base.ins.pas';

%include '/sys/ins/pgm.ins.pas';

%include '/sys/ins/error.ins.pas';

VAR

status : status_$t;

{argument variables}

name.

argument : pgm_$arg;

{INVOKE variables}

argv pgm_$argv;

handle : pgm_$proc;

{declare and load the standard streams}

conny pgm $connv :=

[stream $stdin. stream $stdout.

stream=$errin. stream=$errout];

PROCEDURE check_status; {for error_handling}

BEGIN

END;

IF status.all <> status_$ok THEN BEGIN error $print (status);

pgm $exit;

END;

Example 3-6. Passing Arguments to an Invoked Program

BEGIN {main program}

END.

{load the arguments}

name.chars := 'pgm_passee.bin';

name. len := 14;

argument.chars := 'test';

argument. len := 4;

{load the argument vector

wi

addresses}

argv[O] := ADDR(name);

argv[l] := ADDR(argument);

pgm_$invoke('pgm_passee.bin' , 14

2.

a.rgv, 4.

connY, [J.

handle, status)

{process name}

{name length}

{arg count - name ~ arg}

{arg vector}

{stream count}

{std. streams}

{mode}

{process handle}

pgm_$proc_wait (handle, {process handle}

status);

Example 3- 6. Passing Arguments to an Invoked Program (Cont.)

3.4. Accessing Arguments from an Invoked Program

An invoked .program can access the arguments passed to it in two ways:

• Calling PGM_ $GET _ARG, which returns one argument at a time .

• Calling PGM_ $GET _ARGS, which returns a pointer to an array containing all the passed arguments.

3.4.1. Accessing Arguments with PGM_ $GET _ARG

PGM_$GET _ARG is a function that returns an argument and its length. To access an argument with it, specify the argument vector index number of the pointer to the argument, and the maximum length of the argument. For example, to index the program name, which is the first argument, specify the index number as 0 and a maximum length that will accommodate the name.

Example 3-7 shows a program that could be invoked by a program similar to the one in Example 3.3. This program accesses the second argument in the argument array. (Typically, the program name is ignored by an invoked program.)

PROGRAM pgm_passee_arg (input. output);

%include '/sys/ins/base.ins.pas';

%include '/sys/ins/error.ins.pas';

%include '/sys/ins/pgm.ins.pas';

VAR

status_$t;

pinteger; {returned argument length}

status arg_Iength arg_num argument max len

pinteger; {ordinal # of desired argument}

array [1 .. 256] of char; {argument buffer}

pinteger := 256; {maximum length of returned arg}

BEGIN

{access 2nd argument}

arg_num := 1; {2nd arg #. 0 is 1st}

pgm_$get_arg (arg_num. {arg number}

argument. {arg buffer}

status.

max_len);

writeln ('this is the second argument: ' argument:arg_Iength);

END.

IF status.all <> status_$ok THEN error_$print (status);

{process the argument}

Example 3-7. Accessing Arguments with PGM_$GET _ARG

3.4.2. Accessing Arguments with PGM_ $GET _ARGS

PGM_ $GET _ARGS returns a pointer to the argument vector, and the number of pointers in the vector (the number of arguments passed).

The program in Example 3-8 may also be invoked by. a program similar to the one in Example 3.3. It accesses both arguments passed to it.

Note that the argument vector is a PGM_ $ARGV data type. This is an array of addresses in UNN PTR format. You cannot dereference a UNN PTR. So, to access the argument you

must:

1. Declare an explicit type pointer for the arguments.

2. Typecast the UNN _PTRs to be explicit pointers.

3. Dereference the explicit pointers.

The program segment in Example 3-8 accesses arguments with PGM_ $GET _ARGS, and writes them to output.

PROGRAM pgm_passee (input, output);

%include '/sys/ins/base.ins.pas';

%include '/sys/ins/error.ins.pas';

%include '/sys/ins/pgm.ins.pas';

TYPE

{declare an explicit argument pointer}

pgm_arg_ptr

=

-pgm_$arg;

VAR

arg_count arg_vec_addr

i

pinteger; {argument count}

pgm_$argv_ptr; {argument vector}

pinteger; {index}

{declare array to hold arguments}

arguments array [0 .. 127] of pgm_arg_ptr;

BEGIN

END.

{get a pointer to the argument array}

pgm_$get_args Carg_count, {number of arguments}

arg_vec_addr); {returned pointer}

FOR i := 0 TO Carg_count - 1) DO BEGIN

{typecast the pointer and load into argument array}

arguments[i] := pgm_arg_ptrC arg_vec_addr-[i]);

{write argument to output (dereference explicit pointer)}

writeln ('Argument', i:1,' is " arguments[I]-.chars:arguments[I]-.len);

END;

Example 3-8. Accessing Arguments with PGM_ $GET _ARGS