Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

To:       Distribution

From:     Douglas Howe

Date:     16 May 1986

Subject:  Changes Required to the Command Processor by C

1.  Abstract

This MTB  describes the changes to the  command_processor_ and to
cu_  required  by  C  in  order  to  obtain  the command name for
Argv[0].

Changes will be marked with change bars.

Revision 3                                                        |
The changes made reflect the amendments to MCR 7375 (P612).       |

Comments should be sent to the authors:

     via Multics mail to:

        DGHowe.Multics

     via posted mail to:

        Douglas G.  Howe
        Advanced Computing Technology Centre
        Foothills Professional Building
        1620 29th St., N.W.
        Calgary Alberta Canada   T2N-4L7

     via telephone to:

        (403)-284-6400
        (403)-284-6432 (Howe)

     via forum on System-M to:

        >udd>m>DGHowe>mtgs_dir>c>c_imp (c)

_________________________________________________________________

Multics project  internal documentation; not to  be reproduced or
distributed outside the Multics project.


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

                        TABLE OF CONTENTS

Section    Page  Subject
=======    ====  =======

1          i     Abstract
2          1     Preface
3          2     Introduction
3.1        3     . . References For This Document
4          4     Background
5          5     Requirements
6          6     Changes to cu_
7          7     Changes to command_processor_
8          8     Documentation Changes
9          9     Appendix A
10         33    Appendix B


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

2.  Preface

This document in  addition to the other related  MTBs is intended
to fully explain how C will execute under Multics.


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

3.  Introduction

This MTB  will describe a solution  to a problem that  has arisen
with  the  command  processor  structure  as  it currently stands
concerning the implementation of C.


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

3.1.  References For This Document

1) MTB-647 created by Greg Baryza.

2) The C Programming Language
   Kernighan, Brian W.  & Ritchie, Dennis M.
   Prentice-Hall (1978)
   Englewood Cliffs, New Jersey

3) Multics Programmers Reference Manual (10.2 AG91-03A)
   (hereafter referred to as MPRM)

4) MTB 688  titled The Multics C  Implementation Specification by
   Doug Howe.


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

4.  Background

The entrypoint  main in a C  program is passed an  argument count
called Argc  and a pointer to  an array of pointers  called Argv.
The value of Argv[0] is expected  to be the command name that was
used on the command line.  The  other values of Argv point to the
command line arguments.

Argv[0] is used  by C programmers to determine the  name that was
used to invoke the current execution unit.  As all C programs are
entered  via the  entrypoint main  this allows  C programmers  to
check how they were invoked.

The  current command  processor structure  generates an  argument
list consisting  of the arguments contained on  the command line.
These  arguments  are  accessable  via  entrypoints  in cu_.  The
command name however, is not accessable to any routine beyond the
command  processor.   The  command  name  must  be  accessable by
`main_'(1) so that it can generate a correct Argv structure.

There are various  possible solutions that would allow  a user to
obtain the command name from the command line.  The one described
here involves changes to cu_, command_processor_ and the argument
list structure.

_________________________________________________________________

(1) see MTB 691 Section 6 and MTB 688 Section 6


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

5.  Requirements

Any solution will have to ensure that the normal execution of the
command processor does not change.   This means that the proposed
solution will have to function with the following restrictions.

Note:  It is not required that  a user's own command processor be
changed but they  should be informed that access  to Argv[0] will
return  null if their  command processor does  not set the  saved
value.

1) user   defined  command    processors  can   function  without
   modifications.
2) the   abbrev   processor   will   have   to  function  without
   modifications.
3) subsystems will function without modifications.
4) changes to cu_ do not alter its normal operation.
5) changes  to the  command_processor_  do  not alter  its normal
   operation.
6) users can use the changes to obtain the command name.

C also has a restriction that must be considered.

1) the  command name  retrieved must   be the  name given  on the
   command line and not a name used in a function call.


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

   Unix returns the following for the command line given.

    Command Line                 Result
    ------------                 ------

    name                         name
    path/name                    path/name

   For Multics the following is proposed:

    Command Line                 Result
    ------------                 ------

    name                         name
    name$entrypoint              name$entrypoint
    path>name                    path>name
    path>name$entrypoint         path>name$entrypoint

6.  Changes to cu_

The changes  to cu_ will  be in the  form of two  new entrypoints
defined as follows:

declare cu_$get_command_name entry
          (pointer,fixed bin (21),fixed bin(35));

call cu_$get_command_name
          (command_name_ptr, command_name_length, code);          |

declare cu_$get_command_name_rel entry
          (pointer, fixed bin (21), fixed bin(35), pointer);

call cu_$get_command_name_rel
          (command_name_ptr,      command_name_length,      code, |
          arglist_ptr);                                           |

where:
command_name_ptr                                                  |
          is a pointer to the  returned command name found on the
          command line.  (Output)

command_name_length                                               |
          is the length of the returned command name.  (Output)


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

code
          is a  standard system error code.  If  the command name
          is       not       found       then       this       is
          error_table_$command_name_not_available.  (Output)

arglist_ptr
          is  a  pointer  to  the  argument  list  from which the
          command name is to be retrieved.  (Input)

7.  Changes to command_processor_

The command_processor_  must be altered  to set the  command name
field of a new argument list structure as follows:

     dcl     1 command_name_arg_list          aligned based,
               2 header,
                 3 arg_count        fixed bin (17) unsigned unal,
                 3 pad1             bit (1) unal,
                 3 call_type        fixed bin (18) unsigned unal,
                 3 desc_count       fixed bin (17) unsigned unal,
                 3 mbz              bit(1) unal,
                 3 has_command_name bit(1) unal,
                 3 pad2             bit (17) unal,
               2 arg_ptrs           (arg_list_arg_count refer
                                    (arg_list.arg_count)) ptr,
               2 desc_ptrs          (arg_list_arg_count refer
                                    (arg_list.arg_count)) ptr,
               2 name,
                    3 command_name_ptr     pointer,               |
                    3 command_name_length  fixed bin(21);         |

The  command processor  will set  the has_command_name  bit if it
sets the  command_name.  If the  function is not  entered via the
command processor then the  standard argument list structure will
still be valid.

The  command name  returned will  be the  full name  given on the
command  line, thus leaving  the responsibility of  acquiring the
entrypoint name  to the user via existing  Multics software.  The
name returned  must also be  the name obtained  after any command
line expansion has taken place (ie.  active functions).


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

With the above changes in place it will be possible for a routine
to access the name that was  used on the command line.  This does
not guarantee that the name will  be set if a user installs their
own  command  processor  but  should  allow  a  simple  method of
obtaining   the  required   result  with   the  standard  command
processor.

8.  Documentation Changes

The following manuals or info segs will require changes:
1) cu_.info (see appendix A).
2) Manual AG91 (see appendix B).
3) Manual AG93.  The changes to  this manual can be obtained from
the description given  for cu_.info.  The changes will  be in the
form of a description of the entrypoints cu_$get_command_name and
cu_$get_command_name_rel.


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

9.  Appendix A

03/05/85  cu_

Entry points in cu_:
   (List is generated by the help command)

:Entry:  af_arg_count:  03/05/85 cu_$af_arg_count

Function: This entry point should be called by an active function.
It returns to its caller the number of arguments passed to the
caller by its caller, not including the active function return
argument.  If the caller has not been invoked as an active
function, a standard status code is returned, and, if the code is
error_table_$not_act_fnc, nargs is the number of arguments in the
call (similar to the cu_$arg_count entry point described below).

Syntax:
declare cu_$af_arg_count entry (fixed bin, fixed bin(35));
call cu_$af_arg_count (nargs, code);

Arguments:
nargs
   is the number of input arguments passed to the caller.  (Output)
code
   is a standard status code.  (Output)
   error_table_$nodescr
        no argument descriptors were passed to the caller or an
        incorrect argument list header was encountered.
   error_table_$not_act_fnc
        the caller was not invoked as an active function.

Notes:  This entry point and the five following entry points beginning
with $af_ have been provided so that active functions need not have
knowledge of the mechanism for returning arguments.


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

The entry points cu_$af_arg_count and cu_$af_arg_count_rel are retained
for historical reasons; active function procedures should call
cu_$af_return_arg and cu_$af_return_arg_rel instead to obtain the
location and maximum length of the return argument as well as the
arg_count.  This information will be needed for the active function to
return a value.  When the procedure is invoked as an active function,
the value of arg_count returned by cu_$af_arg_count will be one less
than the value returned by cu_$arg_count, otherwise they will be the
same.

:Entry:  af_arg_count_rel:  03/05/85 cu_$af_arg_count_rel

Function: This entry point is similar to cu_$af_arg_count, but
instead of looking in the argument list of its caller, it is given
a pointer to the argument list.

Syntax:
declare cu_$af_arg_count_rel entry (fixed bin, ptr, fixed bin(35));
call cu_$af_arg_count_rel (nargs, arg_list_ptr, code);

Arguments:
nargs
   is the number of input arguments passed to the caller.  (Output)
arg_list_ptr
   is a pointer to an argument list.  (Input)
code
   is a standard status code.  (Output)
   error_table_$nodescr
        no argument descriptors were passed to the caller or an
        incorrect argument list header was encountered
   error_table_$not_act_fnc
        the caller was not invoked as an active function

:Entry:  af_arg_ptr:  03/05/85 cu_$af_arg_ptr


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

Function: This entry point assumes it has been called by an active
function.  It operates in the same fashion as cu_$arg_ptr
(described below), except that it verifies that the caller was
invoked as an active function, and does not allow the return
argument to be accessed.  If the (i+1)st argument does not exist,
the code error_table_$noarg is returned.  The return argument is
always the last one; thus, use of this entry point and
cu_$af_return_arg allows the active function to be independent of
the position of the return argument in the argument list (see
"Notes" under cu_$af_arg_count above).

Syntax:
declare cu_$af_arg_ptr entry (fixed bin, ptr, fixed bin(21),
     fixed bin(35));
call cu_$af_arg_ptr (arg_no, arg_ptr, arg_len, code);

Arguments:
arg_no
   is the number of the desired argument.  (Input)
arg_ptr
   is a pointer to the unaligned character-string argument specified by
   arg_no.  (Output) It is set to the null value if any error is
   encountered.
arg_len
   is the length (in characters) of the argument specified by arg_no.
   (Output) It is set to 0 if any error is encountered.

code
   is a standard status code.  (Output)
   error_table_$nodescr
        the argument list does not contain descriptors.  In this case,
        arg_len is set to zero.
   error_table_$not_act_fnc
        the caller was not invoked as an active function.
   error_table_$noarg
        the program does not have an arg_no'th argument.  In this case,
        arg_ptr is set to null and arg_len is set to zero.

:Entry:  af_arg_ptr_rel:  03/05/85 cu_$af_arg_ptr_rel

Function: This entry point is similar to cu_$af_arg_ptr but
instead of looking in the argument list of its caller, it is given
a pointer to the argument list.


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

Syntax:
declare cu_$af_arg_ptr_rel entry (fixed bin, ptr, fixed bin(21),
     fixed bin(35), ptr);
call cu_$af_arg_ptr_rel (arg_no, arg_ptr, arg_len, code, arg_list_ptr);

Arguments:
arg_no
   is the number of the desired argument.  (Input)
arg_ptr
   is a pointer to the unaligned character-string argument specified by
   arg_no.  (Output) It is set to the null value if any error is
   encountered.
arg_len
   is the length (in characters) of the argument specified by arg_no.
   (Output) It is set to 0 if any error is encountered.
arg_list_ptr
   is a pointer to an argument list.  (Input)

code
   is a standard status code.  (Output)
   error_table_$nodescr
        the argument list does not contain descriptors.  In this case,
        arg_len is set to zero.
   error_table_$not_act_fnc
        the caller was not invoked as an active function.
   error_table_$noarg
        the program does not have an arg_no'th argument.  In this case,
        arg_ptr is set to null and arg_len is set to zero.

:Entry:  af_return_arg:  03/05/85 cu_$af_return_arg

Function: This entry point assumes it has been called by an active
function.  It makes the active function's return argument
available as described in "Notes" below.  It is provided to permit
writing of active functions that accept an arbitrary number of
arguments (see "Notes" under cu_$af_arg_count above).

Syntax:
declare cu_$af_return_arg entry (fixed bin, ptr, fixed bin(21),
     fixed bin(35));
declare return_string char (max_length) varying based (rtn_string_ptr);
call cu_$af_return_arg (nargs, rtn_string_ptr, max_length, code);


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

Arguments:
nargs
   is the number of input arguments passed to the caller.  (Output)
rtn_string_ptr
   is a pointer to the varying return argument of the active function.
   (Output)
max_length
   is the maximum length of the varying string pointed to by
   rtn_string_ptr.  (Output)
code
   is a standard status code.  (Output)
   error_table_$nodescr
        no argument descriptors were passed to the caller or an
        incorrect argument list header was encountered.
   error_table_$not_act_fnc
        the caller was not invoked as an active function.

Notes:  An active function that takes an arbitrary number of arguments
uses this entry point to return a value.  It calls the entry point to
get a pointer to the return argument and to get its maximum length.  It
declares the based varying string, return_string, as described above.
It then assigns its return value to return_string.  Even if
error_table_$not_act_fnc is returned, nargs will be set to the proper
value.

:Entry:  af_return_arg_rel:  03/05/85 cu_$af_return_arg_rel

Function: This entry point is similar to cu_$af_return_arg, but
instead of looking in the argument list of its caller, it is given
a pointer to the argument list.

Syntax:
declare cu_$af_return_arg_rel entry (fixed bin, ptr, fixed bin(21),
     fixed bin(35), ptr);
call cu_$af_return_arg_rel (nargs, rtn_string_ptr, max_length, code,
     arg_list_ptr);


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

Arguments:
nargs
   is the number of input arguments passed to the caller.  (Output)
arg_list_ptr
   is a pointer to an argument list.  (Input)
rtn_string_ptr
   is a pointer to the varying return argument of the active function.
   (Output)
max_len
   is the maximum length of the varying string pointed to by
   rtn_string_ptr.  (Output)

code
   is a standard status code.  (Output)
   error_table_$nodescr
        no argument descriptors were passed to the caller or an
        incorrect argument list header was encountered.
   error_table_$not_act_fnc
        the caller was not invoked as an active function.

:Entry:  arg_count:  03/05/85 cu_$arg_count

Function: The cu_$arg_count entry point can be used by any
procedure to determine the number of arguments with which it was
called.

Syntax:
declare cu_$arg_count entry (fixed bin, fixed bin (35));
call cu_$arg_count (arg_count, code);

Arguments:
arg_count
   is the number of arguments.  (Output)
code
   is a standard status code.  (Output)
   error_table_$nodescr
        no argument descriptors were passed to the caller or an
        incorrect argument list header was encountered.
   error_table_$active_function
        the caller was invoked as an active function.


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

Notes:  Even if the code is nonzero, arg_count may still be valid.  If
error_table_$active_function is returned, the arg_count will be the
total number of arguments, including the active function return
argument.  This number may differ from that returned by
cu_$af_return_arg, described below.  This entry point is intended for
use with command procedures that may not be used as active functions.

For compatibility with old programs, the code argument may be omitted.

:Entry:  arg_count_rel:  03/05/85 cu_$arg_count_rel

Function: This entry point returns the number of arguments in any
specified argument list.

Syntax:
declare cu_$arg_count_rel entry (fixed bin, ptr, fixed bin (35));
call cu_$arg_count_rel (arg_count, arg_list_ptr, code);

Arguments:
arg_count
   is the number of arguments.  (Output)
arg_list_ptr
   is a pointer to an argument list.  (Input) This pointer can be
   obtained by calling cu_$arg_list_ptr, described below.
code
   is a standard status code.  (Output)
   error_table_$nodescr
        no argument descriptors were passed to the owner of the
        argument list or an incorrect argument list header was
        encountered.
   error_table_$active_function
        the owner of the argument list was invoked as an active
        function.

:Entry:  arg_list_ptr:  03/05/85 cu_$arg_list_ptr

Function: It is sometimes desirable to design a PL/I procedure to
accept a variable number of arguments of varying data types (e.g.,
the ioa_ subroutine).  In these cases, the PL/I procedure must be
able to interrogate its argument list directly to determine the
number, type, and location of each argument.  The cu_$arg_list_ptr
entry point is designed for use in such cases and returns a
pointer to the argument list of its caller.


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

Syntax:
declare cu_$arg_list_ptr entry (ptr);
call cu_$arg_list_ptr (arg_list_ptr);

Arguments:
arg_list_ptr
   is a pointer to the argument list of the caller.  (Output)

:Entry:  arg_ptr:  03/05/85 cu_$arg_ptr

Function: The cu_$arg_ptr entry point is used by a command or
subroutine that can be called with a varying number of arguments,
each of which is a variable-length unaligned character string
(i.e., declared char(*)).  This entry point returns a pointer to
the character-string argument specified by the argument number and
also returns the length of the argument.

Syntax:
declare cu_$arg_ptr entry (fixed bin, ptr, fixed bin(21), fixed
     bin(35));
call cu_$arg_ptr (arg_no, arg_ptr, arg_len, code);

Arguments:
arg_no
   is an integer specifying the number of the desired argument.
   (Input)
arg_ptr
   is a pointer to the unaligned character-string argument specified by
   arg_no.  (Output)
arg_len
   is the length (in characters) of the argument specified by arg_no.
   (Output)

code
   is a standard status code.  (Output)
   error_table_$nodescr
        the argument list does not contain descriptors.  In this case,
        argl_len set is to zero.
   error_table_$noarg
        the program does not have an arg_no'th argument.  In this case,
        arg_ptr is set to null and arg_len is set to zero.


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

Notes:  The command or subroutine that uses this entry point must be
called with data descriptors for its arguments.  Otherwise, the
returned value of arg_len is 0.  If the argument specified by arg_no is
not a character string, arg_len is the value of the "size" field of the
descriptor (the rightmost 24 bits).  This entry point must not be
called from an internal procedure that has its own stack frame or from
within a begin block (because cu_$arg_ptr does not check for a display
pointer).

:Entry:  arg_ptr_rel:  03/05/85 cu_$arg_ptr_rel

Function: Some PL/I procedures may need to reference arguments
passed to other procedures.  This entry point permits a procedure
to reference arguments in any specified argument list.

Syntax:
declare cu_$arg_ptr_rel entry (fixed bin, ptr, fixed bin(21),
     fixed bin(35), ptr);
call cu_$arg_ptr_rel (arg_no, arg_ptr, arg_len, code, arg_list_ptr);

Arguments:
arg_no
   is an integer specifying the number of the desired argument.
   (Input)
arg_ptr
   is a pointer to the unaligned character-string argument specified by
   arg_no.  (Output)
arg_len
   is the length (in characters) of the argument specified by arg_no.
   (Output)

code
   is a standard status code.  (Output)
   error_table_$nodescr
        the argument list does not contain descriptors.  In this case,
        argl_len is set to zero.
   error_table_$noarg
        the program does not have an arg_no'th argument.  In this case,
        arg_ptr is set to null and arg_len is set to zero.
  arg_list_ptr
     is a pointer to the argument list from which this argument is
     being extracted.  (Input) This pointer can be determined by
     calling cu_$arg_list_ptr in the program whose argument list is to
     be processed and then passing it to the program requesting
     reference to the argument list.


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

:Entry: get_command_name: 01/07/86 cu_$get_command_name

Function: This entrypoint allows a routine entered via the command
processor to obtain the name used on the command line to invoke
the procedure.  The values returned are as follows:

Name used on command line               Returned Value
-------------------------               --------------

name                                    name
path>name                               path>name
name$entrypoint                         name$entrypoint
path>name$entrypoint                    path>name$entrypoint

Syntax:
declare cu_$get_command_name entry (ptr, fixed bin (21),
        fixed bin(35));
call cu_$get_command_name (command_name_ptr,                      |
     command_name_length, error_code);                            |

Arguments:
command_name_ptr                                                  |
   Is a pointer to the command name of length name_length.  If
   null, the command name is unavailable for the current
   routine.  (Output)

command_name_length                                               |
   Is the length of the returned command name.  If zero the
   command name is unavailable for the current routine.
   (Output)

error_code
   Is a standard status code.  If the command name is
   unavailable its value is equal to
   error_table_$no_command_name_available.  (Output)

:Entry: get_command_name_rel: 01/07/86 cu_$get_command_name_rel

Function: This entrypoint allows a routine entered via the command
processor to obtain the name used on the command line to invoke
the procedure.  The values returned are as follows:

Name used on command line               Returned Value
-------------------------               --------------


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

name                                    name
path>name                               path>name
name$entrypoint                         name$entrypoint
path>name$entrypoint                    path>name$entrypoint

Syntax:
declare cu_$get_command_name_rel entry (ptr, fixed bin (21),
        fixed bin(35), ptr);
call cu_$get_command_name_rel (command_name_ptr,                  |
     command_name_length, error_code, arglist_ptr);               |

Arguments:
command_name_ptr                                                  |
   Is a pointer to the command name of length name_length.  If
   null, the command name is unavailable for the current
   routine.  (Output)

command_name_length                                               |
   Is the length of the returned command name.  If zero the
   command name is unavailable for the current routine.
   (Output)

error_code
   Is a standard status code.  If the command name is
   unavailable its value is equal to
   error_table_$no_command_name_available.  (Output)

arglist_ptr:
   Is a pointer to the argument list from which this argument
   is being extracted.  This pointer can be determined by
   calling cu_$arg_list_ptr in the program whose argument list
   is to be processed and then passing it to the program
   requesting reference to the argument list.  (Input)

:Entry:  caller_ptr:  03/05/85 cu_$caller_ptr

Function: This entry point allows a routine to obtain a pointer to
its caller.  The pointer that is returned points to the
instruction within the text section after the instruction that
called out.

Syntax:
declare cu_$caller_ptr entry (ptr);
call cu_$caller_ptr (caller_ptr);


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

Arguments:
caller_ptr
   is a pointer into the text section of the caller.  (Output) If null,
   the invoker of the cu_ subroutine has no caller.

:Entry:  cl:  03/05/85 cu_$cl

Function: The cu_$cl entry point is called by all standard error
handlers after printing a diagnostic message.  This entry point
passes control to the procedure specified by the last call to
cu_$set_cl_intermediary.  It takes an optional argument which is
passed directly to that procedure.  If no such procedure has been
specified (the norm), control is passed to the standard procedure,
which establishes a new command level (see Notes below).

Syntax:
declare cu_$cl entry (1 aligned, 2 bit(1) unaligned, 2 bit(35)
     unaligned);
dcl 1 flags         aligned,
      2 reset_sw  bit (1) unaligned,
      2 mbz       bit (35) unaligned;
call cu_$cl (flags);

Arguments:
flags.reset_sw
   specifies whether the intermediary procedure should perform a
   "resetread" control order on the standard "user_i/o" I/O switch.
   (Input)
   "1"b do a "resetread" operation,
   "0"b do not perform a "resetread" operation.
flags.mbz
   is reserved for future use and must be "0"b.  (Input)

Notes:  If no argument is given, cu_$cl passes a static argument with
flags.reset_sw set to "1"b.

Establishing a new command level consists of saving the attachments of
the standard I/O switches (user_input, user_output, and error_output),
restoring these attachments to their default state, and entering a new
loop of reading and executing command lines.  If the "start" command is
issued, the attachments of the standard I/O switches are restored to
the state saved above and control is returned to the caller of cu_$cl
to continue from the interrupted exection.  If the "release" command is
issued, the interrupted execution is aborted, the I/O switches are not
restored, and control is returned to the previous command level.


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

:Entry:  cp:  03/05/85 cu_$cp

Function: The cu_$cp entry point, called when a Multics command
line is recognized, passes the command line to the currently
defined command processor for processing.  Some standard Multics
commands (e.g., qedx) permit the user to escape from them to
execute other commands.  In this case, the escapable command
passes the line to be executed to the command processor.  The
cu_$cp entry point is called by any standard command that
recognizes other Multics command lines.

Syntax:
declare cu_$cp entry (ptr, fixed bin(21), fixed bin(35));
call cu_$cp (line_ptr, line_len, code);

Arguments:
line_ptr
   is a pointer to the beginning of a character string containing a
   command line to be processed.  (Input)
line_len
   is the length of the command line in characters.  (Input)
code
   is a standard status code or the nonstandard code 100.  (Output) If
   an error has been detected, the caller of the cu_$cp entry point is
   not expected to print a diagnostic at this time since it can be
   expected that the command processor has already done so.  A returned
   code of 100 indicates that the command line is blank and no ready
   message should be printed.

:Entry:  evaluate_active_string:  03/05/85 cu_$evaluate_active_string

Function: This entry point evaluates an active string.  An active
string consists of one or more active function invocations and
their arguments.  Other entries are provided for subsystem writers
to specify the procedure to be called by this entry.

Syntax:
declare cu_$evaluate_active_string entry (ptr, char(*), fixed bin,
     char(*) varying, fixed bin (35));
call cu_$evaluate_active_string (info_ptr, active_string, string_type,
     return_value, code);


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

Arguments:
info_ptr
   is reserved for future expansion and must be null.  (Input)
active_string
   is the active string to be evaluated.  (Input) It should not include
   the outermost brackets.

string_type
   specifies the type of active string to be evaluated.  (Input) Its
   possible values are:
     NORMAL_ACTIVE_STRING
        the active string return value should be rescanned for all
        command processor constructs.  ([...])
     TOKENS_ONLY_ACTIVE_STRING
        the active string return value should be rescanned only for
        whitespace and quotes.  (|[...])
     ATOMIC_ACTIVE_STRING
        the active string return value should not be rescanned.
        (||[...])

return_value
   is the result of the evaluation.  (Output)
code
   is a standard system status code.  (Output) If its value is
   error_table_$command_line_overflow, the maximum length of the
   return_value argument was not large enough to hold the result of the
   evaluation.  In this case, the result will be truncated.

Notes:  The constants used above for string_type are defined in the
cp_active_string_types.incl.pl1 include file.  The active string should
not be enclosed in brackets.

:Entry:  generate_call:  03/05/85 cu_$generate_call

Function: The cu_$generate_call entry point is used to generate a
standard call to a specified procedure with a specified argument
list.  This call is designed for cases in which a PL/I procedure
has explicitly built an argument list from its input data.  The
principal use of this entry is by command processors that call a
command with an argument list built from a command line input from
a terminal.


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

Syntax:
declare cu_$generate_call entry (entry, ptr);
call cu_$generate_call (proc_entry, a_ptr);

Arguments:
proc_entry
   is the procedure entry point to be called.  (Input)
a_ptr
   is a pointer to the argument list to be passed to the called
   procedure.  (Input)

:Entry:  get_cl_intermediary:  03/05/85 cu_$get_cl_intermediary

Function: This entry point returns to the caller the procedure
entry currently being invoked by a call to cu_$cl.

Syntax:
declare cu_$get_cl_intermediary entry (entry);
call cu_$get_cl_intermediary (proc_entry);

Arguments:
proc_entry
   is the procedure entry being called by the standard error handlers
   after printing a diagnostic message.  (Output)

:Entry:  get_command_processor:  03/05/85 cu_$get_command_processor

Function: This entry point returns to the caller the entry value
of the procedure currently being invoked by a call to cu_$cp.

Syntax:
declare cu_$get_command_processor entry (entry);
call cu_$get_command_processor (proc_entry);

Arguments:
proc_entry
   is the procedure entry point to which control is passed upon
   receiving a call to cu_$cp.  (Output)

:Entry:  get_evaluate_active_string: 03/05/85 cu_$get_evaluate_active_string


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

Function: This entry point returns to the caller the entry value
of the procedure currently being invoked by a call to
cu_$evaluate_active_string.

Syntax:
declare cu_$get_evaluate_active_string entry (entry);
call cu_$get_evaluate_active_string (active_string_procedure);

Arguments:
active_string_procedure
   is the procedure entry point to which control is passed upon
   receiving a call to cu_$evaluate_active_string.  (Output)

:Entry:  get_ready_mode:  03/05/85 cu_$get_ready_mode

Function: This entry point returns the value of the internal
static ready flags.

Syntax:
declare cu_$get_ready_mode entry (1 aligned, 2 bit(1) unaligned,
     2 bit(35) unaligned);
dcl 1 mode aligned,
      2 ready_sw bit(1) unaligned,
      2 mbz bit(35) unaligned;
call cu_$get_ready_mode (mode)

Arguments:
mode.ready_sw
   is the current value of the static ready switch.  (Output)
   "1"b print ready message.
   "0"b do not print ready message.
mode.mbz
   is reserved for future use and must be "0"b.  (Output)

:Entry:  get_ready_procedure:  03/05/85 cu_$get_ready_procedure

Function: This entry point returns the entry value of the current
ready procedure of the process.


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

Syntax:
declare cu_$get_ready_procedure entry (entry);
call cu_$get_ready_procedure (ready_entry);

Arguments:
ready_entry
   is the current ready procedure.  (Output)

:Entry:  grow_stack_frame:  03/05/85 cu_$grow_stack_frame

Function: This entry point allows its caller to allocate temporary
storage by extending the caller's current stack frame.

Syntax:
declare cu_$grow_stack_frame entry (fixed bin, ptr, fixed bin(35));
call cu_$grow_stack_frame (len, data_ptr, code);

Arguments:
len
   is the length (in words) by which the caller's stack frame is to be
   extended.  (Input) The standard Multics call, push, and return
   discipline requires that stack frames begin on mod 16 word
   boundaries.  Therefore, if len is not a mod 16 number, the stack
   frame is grown by the next mod 16 quantity greater than len.
data_ptr
   is a pointer to the first location of len words allocated in the
   caller's stack frame.  (Output)
code
   is a standard status code.  (Output)

Notes:  The cu_$grow_stack_frame and cu_$shrink_stack_frame entry
points are for advanced subsystems writers only and should be used only
when absolutely necessary.  Most PL/I programs can be written to use
begin blocks to allocate extra storage in the current stack frame.  The
entry points rely on internal workings of the PL/I compiler that are
not guaranteed to continue working forever.

:Entry:  level_get:  03/05/85 cu_$level_get


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

Function: The cu_$level_get entry point is used to obtain the
current ring validation level.  This entry point is normally used
prior to a call to cu_$level_set to save the current validation
level.

Syntax:
declare cu_$level_get entry (fixed bin);
call cu_$level_get (level);

Arguments:
level
   is the current ring validation level.  (Output)

:Entry:  level_set:  03/05/85 cu_$level_set

Function: The cu_$level_set entry point is used to change the
current protection ring validation level.  This entry point is
useful for procedures that must distinguish the periods of time
when the procedure is acting in behalf of itself (i.e., its own
ring) and when it is acting in behalf of another procedure that
can be in an outer (i.e., less privileged) protection ring.

Syntax:
declare cu_$level_set entry (fixed bin);
call cu_$level_set (level);

Arguments:
level
   specifies the new protection validation level and must be greater
   than or equal to the current ring number.  (Input) The current ring
   number can be determined by the get_ring_ subroutine.

:Entry:  make_entry_value:  03/05/85 cu_$make_entry_value

Function: The cu_$make_entry_value entry point constructs a PL/I
entry value from a pointer to an entry point.  The environment
pointer of the entry value will be null, so the entry point
pointer must point to an external procedure.


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

Syntax:
declare cu_$make_entry_value entry (pointer, entry);
call cu_$make_entry_value (ep_ptr, entry_value);

Arguments:
ep_ptr
   is the entry point pointer.  (Input)
entry_value
   is the entry value.  (Output)

:Entry:  ready_proc:  03/05/85 cu_$ready_proc

Function: The ready_proc entry point is used to call the current
ready procedure of the process.  It takes an optional argument,
which it passes to the ready procedure.  The ready procedure is
automatically invoked by the listener after each command line is
processed.  The ready procedure of the standard command
environment prints the ready message.  The cu_$set_ready_procedure
subroutine can be called to change the ready procedure.

Syntax:
declare cu_$ready_proc entry;
call cu_$ready_proc ();
or:
dcl cu_$ready_proc entry (1 aligned, 2 bit(1) unaligned,
     2 bit(35) unaligned);
dcl 1 mode       aligned,
      2 ready_sw bit(1) unaligned,
      2 mbz      bit(35) unaligned;
call cu_$ready_proc (mode);

Arguments:
mode.ready_sw
   specifies whether the ready procedure should print a ready message.
   (Input)
   "1"b print ready message
   "0"b do not print ready message
mode.mbz
   is reserved for future use and must be "0"b.  (Input)


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

Notes:  If no argument is given, a static ready switch is passed to the
ready procedure.  The default value of the static ready switch is "1"b.
The value of the static ready switch can be obtained using the
cu_$get_ready_mode entry point and changed using the cu_$set_ready_mode
entry point.  The listener invokes the cu_$ready_proc entry point
without an argument.  The ready_off command turns off the static ready
switch, the ready_on command turns it on, and the ready command calls
the cu_$ready_proc entry point with an argument whose ready_sw
component is "1"b.  Thus, if a user-written ready procedure honors the
ready switch, its printing of the ready message can be controlled by
the standard ready, ready_on, and ready_off commands.

:Entry:  reset_cl_intermediary:  03/05/85 cu_$reset_cl_intermediary

Function: This entry point resets the procedure invoked by calls
to cu_$cl to the standard system supplied procedure.

Syntax:
declare cu_$reset_cl_intermediary entry ();
call cu_$reset_cl_intermediary ();

:Entry:  reset_command_processor:  03/05/85 cu_$reset_command_processor

Function: This entry point resets the procedure invoked by calls
to cu_$cp to the standard system supplied procedure.

Syntax:
declare cu_$reset_command_processor entry ();
call cu_$reset_command_processor ();

:Entry:  reset_evaluate_active_string: 03/05/85 cu_$reset_evaluate_active_string

Function: This entry point resets the procedure invoked by calls
to cu_$evaluate_active_string to the standard system supplied
procedure.

Syntax:
declare cu_$reset_evaluate_active_string entry ();
call cu_$reset_evaluate_active_string ();


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

:Entry:  reset_ready_procedure:  03/05/85 cu_$reset_ready_procedure

Function: This entry point resets the procedure invoked by calls
to cu_$ready_proc to the standard system supplied procedure.

Syntax:
declare cu_$reset_ready_procedure entry ();
call cu_$reset_ready_procedure ();

:Entry:  set_cl_intermediary:  03/05/85 cu_$set_cl_intermediary

Function: The Multics system provides a set of procedures to
handle any error conditions that can be signalled within a process
(see the description of the signal_ subroutine).  The standard
error handlers attempt to print an understandable diagnostic and
call a procedure to reenter command level.  However, in order to
allow use of the standard error handling procedures in a closed
subsystem environment, the error handlers do not call the standard
error handlers directly but call the cu_$cl entry point.  This
entry point passes control to the procedure entry point currently
defined by the last call to cu_$set_cl_intermediary.  If
cu_$set_cl_intermediary has never been called in the process,
control is passed to the standard error handlers on a call to
cu_$cl.

Syntax:
declare cu_$set_cl_intermediary entry (entry);
call cu_$set_cl_intermediary (proc_entry);

Arguments:
proc_entry
   is the procedure entry to be called by the standard error handlers
   after printing a diagnostic message.  (Input)

:Entry:  set_command_processor:  03/05/85 cu_$set_command_processor

Function: Some standard Multics commands permit the user to escape
from them to execute other commands.  In this case, the escapable
command passes the line to be executed to the command processor.
To allow use of these escapable standard commands in a closed
subsystem environment, instead of calling the command processor
directly, the cu_$cp entry point is called.  The latter passes


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

control to the procedure entry point defined as the current
command processor.  The cu_$set_command_processor entry point
allows a subsystem developer to replace the standard command
processor with a different procedure.  This mechanism can be used
to ensure that the subsystem remains in full control and still
allow subsystem users the use of many standard commands.

Syntax:
declare cu_$set_command_processor entry (entry);
call cu_$set_command_processor (proc_entry);

Arguments:
proc_entry
   is the procedure entry point to which control is passed upon
   receiving a call to cu_$cp.  (Input)

:Entry:  set_evaluate_active_string: 03/05/85 cu_$set_evaluate_active_string

Function: Some standard Multics commands (e.g., compose and
exec_com) permit the user to evaluate active strings which are a
sequence of one or more active function invocations with their
arguments.  To allow the use of these commands in a closed
subsystem, instead of calling the command processor directly to
evaluate the active string, the cu_$evaluate_active_string entry
is called.  The latter passes control to the procedure entry point
defined as the current active string evaluator.  The
cu_$set_evaluate_active_string entry point allows a subsystem
developer to replace the standard active string evaluator with a
different procedure.  This mechanism can be used to insure that
the subsystem remains in full control and still allow subsystem
users the use of many standard commands.

Syntax:
declare cu_$set_evaluate_active_string entry (entry);
call cu_$set_evaluate_active_string (active_string_procedure);

Arguments:
active_string_procedure
   is the procedure entry point to which control is passed upon
   receiving a call to cu_$evaluate_active_string.  (Input)

:Entry:  set_ready_mode:  03/05/85 cu_$set_ready_mode


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

Function: This entry point allows the user to change the value of
the static ready mode.

Syntax:
declare cu_$set_ready_mode entry (1 aligned, 2 bit(1) unaligned,
     2 bit(35) unaligned);
dcl 1 mode       aligned,
      2 ready_sw bit(1) unaligned,
      2 mbz      bit(35) unaligned;
call cu_$set_ready_mode (mode);

Arguments:
mode.ready_sw
   is the new value of the static ready switch.  (Input)
   "1"b print ready message
   "0"b do not print ready message
mode.mbz
   is reserved for future use and must be "0"b.  (Input)

:Entry:  set_ready_procedure:  03/05/85 cu_$set_ready_procedure

Function: This entry point allows the user to change the ready
procedure invoked by cu_$ready_proc.

Syntax:
declare cu_$set_ready_procedure entry (entry);
call cu_$set_ready_procedure (ready_entry);

Arguments:
ready_entry
   is the procedure entry point that is to become the new ready
   procedure of the process.  (Input)

:Entry:  shrink_stack_frame:  03/05/85 cu_$shrink_stack_frame

Function: This entry point allows its caller to deallocate
temporary storage by reducing the caller's current stack frame.
Such storage must have been allocated via a call to
cu_$grow_stack_frame.


MTB-733-03                             Multics Technical Bulletin
                                 Changes to the Command Processor

Syntax:
declare cu_$shrink_stack_frame entry (ptr, fixed bin(35));
call cu_$shrink_stack_frame (ptr, code);

Arguments:
ptr
   is a pointer to the first word of the storage to be deallocated.
   (Input) It must point to a mod 16 word boundary.  The stack frame
   from the word indicated by ptr to the end of the frame is
   deallocated.
code
   is a standard status code.  (Output)

:Entry:  stack_frame_ptr:  03/05/85 cu_$stack_frame_ptr

Function: The cu_$stack_frame_ptr entry point returns a pointer to
the stack frame of its caller.  The stackframeptr builtin function
should be used to get this information in PL/I programs, since it
is more efficient.

Syntax:
declare cu_$stack_frame_ptr entry (ptr);
call cu_$stack_frame_ptr (stack_ptr);

Arguments:
stack_ptr
   is a pointer to the stack frame of its caller.  (Output)

:Entry:  stack_frame_size:  03/05/85 cu_$stack_frame_size

Function: The cu_$stack_frame_size entry point returns the size
(in words) of the stack frame of its caller.

Syntax:
declare cu_$stack_frame_size entry (fixed bin);
call cu_$stack_frame_size (size);

Arguments:
size
   is the size (in words) of the caller's stack frame.  (Output)


Multics Technical Bulletin                             MTB-733-03
Changes to the Command Processor

10.  Appendix B

page H-16

Under the heading "Argument List Format" add

     dcl     1 command_name_arglist           aligned based,
               2 header,
                 3 arg_count        fixed bin (17) unsigned unal,
                 3 pad1             bit (1) unal,
                 3 call_type        fixed bin (18) unsigned unal,
                 3 desc_count       fixed bin (17) unsigned unal,
                 3 mbz              bit(1) unal,
                 3 has_command_name bit(1) unal,
                 3 pad2             bit (17) unal,
               2 arg_ptrs           (arg_list_arg_count refer
                          (command_name_arglist.arg_count)) ptr,
               2 desc_ptrs          (arg_list_arg_count refer
                          (command_name_arglist.arg_count)) ptr,
               2 name,
                 3 command_name_ptr         pointer,              |
                 3 command_name_length      fixed bin (21);       |

has_command_name
          if "1"b this specifies that the command name has been
          stored in name_ptr and its length has been stored in
          name_length.

command_name_ptr                                                  |
          is a pointer to the expanded command name given on the
          command line.

command_name_length                                               |
          is the length of the expanded command name pointed to
          by name_ptr.