@X @~
~V7 56 2 -5
~D10
~H                 MUSS
~
~
~H     VOLUME        2
~
~
~
~
~
~
~
~
~
~
~M~OBASIC SYSTEM LIBRARY~
~BThis volume contains the implementation of the basic MUSS library. The
reader is recommended to read the description of LIB02 first since this
describes the interface into the library from both the compiler and the
command language interpreter.~
~D9
~MUNIVERSITY OF MANCHESTER~
~V9 -1
~P
~V9 1
~S1~MVolume 2  CONTENTS
~T% 15
~
~
%LIB011  -  Job Organisation~
%LIB022  -  Library Organisation~
%LIB031  -  Job Control Facilities~
%LIB042A -  Basic Input/Output Operations~
%LIB042B -  Stream Management~
%LIB042C -  Document Name Procedures~
%LIB042D -  Document Section Management~
%LIB042E -  Positioning Operations~
%LIB042F -  Character and Binary Input/Output Operations~
%LIB051  -  Error Handling~
%LIB061  -  Advanced Input/Output Operations~
%LIB071  -  File and Current File Handling~
%LIB081  -  Performance Monitoring~
%LIB091  -  Peripheral Utilities~
%LIB101  -  Peripheral Utilities~
%LIB121  -  File Procedure Facilities~
%LIB131  -~
%SUP011  -  Job Supervisor~
%SUP021  -  File Manager~
%SUP022  -  File Manager~
%SUP023  -  File Manager~
~S1~MVolume 2 UTILITIES
~
~
%LIB111  -  User Management Utilities~
%EDT031  -  Screen Editor~
%EDT041  -~
~V9 -1
~P
~D10
~H                    MUSS
~
~
~D10
~H             LIB011
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                           ISSUE 11~
~V9 -1
~P
~V9 1
~YLIB011
~M~OLIB IMPLEMENTATION DESCRIPTION
~
~M~OSection 1 Version 1
~S1~OSection 1.1 Job Organisation
~S1~O1. General Description
~BThis module is responsible for the initialisation and
termination of normal user jobs. It provides interface procedures
for: starting a batch job; starting an interactive job; stopping a
job normally; aborting a job in the event of an irrecoverable error.
~S1~O2. Interfaces
~
Interface procedures~
   START.BATCH ()~
   START.INTERACTIVE ()~
   ABORT (CLASS, CODE)~
Library procedures~
   STOP (REASON)~
~S11) START.BATCH ()
~BUser processes corresponding to batch jobs are started
in this procedure by the JOB supervisor (SUP01). It simply
initialises the required input and output streams, and then
calls the command interpreter.
~S12) START.INTERACTIVE ()
~BUser processes corresponding to interactive jobs are started
in this procedure by the JOB supervisor (SUP01). It simply
initialises the required input and output streams, and then
calls the command interpreter.
~S13) ABORT (TRAP, REASON)
~BThis procedure is used to intercept all traps which occur
during the process of stopping or trapping, and has the effect of
terminating the process immediately, losing all of its output streams.
~S1~O3. Implementation
~S1~O3.1 Outline of Operation
~BThe operation of this module is entirely straightforward.
~S1~O3.2 Data Structures
~BNone
~S1~O3.3 Special Notes
~BNone
~Y
~V9 -1
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H                LIB011
~V9 -1
~F
@TITLE LIB01(1,8)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
JOB ORGANISATION
@BOX 4.0
PROCEDURES IN MODULE:
   1 START BATCH
   2 START INTERACTIVE
   3 STOP
   4 ABORT
@BOX 6.0
END
@BOX 1.1
#LIB01/1
MODULE (START.BATCH, START.INTERACTIVE, ABORT, stOp, rUN.jOB);
@BOX 4.1
*CODE 1;
LSPEC START.BATCH ();
LSPEC START.INTERACTIVE ();
LSPEC STOP (INTEGER);
LSPEC ABORT (INTEGER, INTEGER);
LSPEC RUN.JOB (ADDR [LOGICAL8], ADDR [LOGICAL8], ADDR [LOGICAL8]);
   #LIB01.1
   #LIB01.2
   #LIB01.3
   #LIB01.4
   #LIB01.5
@BOX 6.1
*END
@END
@TITLE LIB01/1(1,11)
@COL 1S-2R-3R-4R
@FLOW 1-2-3-4
@BOX 1.0
OTHER MODULES REFERENCED
@BOX 4.0
SECTION 4 BASIC I/O OPERATIONS
SECTION 5 ERROR HANDLING
@BOX 1.1
::EXTERNAL ENVIRONMENT
@BOX 4.1
IMPORT LITERAL LIB04.MAX.STREAM.NO;
IMPORT LITERAL LIB05.NO.OF.TRAPS;
LSPEC READ.TIMER ();
LSPEC TERMINATE.PROCESS (INTEGER);
LSPEC NAMES ();
LSPEC LOOK.UP.PROCESS (LOGICAL64, LOGICAL64);
LSPEC SET.CH.STATUS (INTEGER, INTEGER, INTEGER, INTEGER);
PSPEC INIT.LIB ();
PSPEC PPC.SEQ (INTEGER);
PSPEC INIT.IO ();
PSPEC DEFINE.INPUT (INTEGER, ADDR [LOGICAL8], INTEGER32) / INTEGER;
PSPEC DEFINE.OUTPUT (INTEGER, ADDR [LOGICAL8], INTEGER32, INTEGER32) / INTEGER;
PSPEC BREAK.INPUT (INTEGER);
PSPEC END.INPUT (INTEGER, INTEGER);
PSPEC END.OUTPUT (INTEGER, INTEGER);
PSPEC BREAK.OUTPUT (INTEGER);
PSPEC SELECT.INPUT (INTEGER);
PSPEC SELECT.OUTPUT (INTEGER);
PSPEC CURRENT.INPUT () / INTEGER;
PSPEC CURRENT.OUTPUT () / INTEGER;
PSPEC I.SOURCE (ADDR [INTEGER]);
PSPEC TPROC (INTEGER, INTEGER);
PSPEC SET.TRAP (INTEGER, ADDR TPROC);
PSPEC SET.RECOVERY.STATUS (INTEGER, INTEGER);
PSPEC CAPTION (ADDR [LOGICAL8]);
PSPEC NEW.LINES (INTEGER);
PSPEC OUT.TIME ();
PSPEC SPACES (INTEGER);
PSPEC OUT.DATE ();
PSPEC OUT.I (INTEGER32, INTEGER);
PSPEC IN.CH () / INTEGER;
PSPEC OUT.CH (INTEGER);
PSPEC NEXT.CH () / INTEGER;
PSPEC PROCESS.NAME (ADDR [LOGICAL8])/ ADDR [LOGICAL8];
PSPEC PROMPT (ADDR [LOGICAL8]);
PSPEC I.ENQ () / INTEGER;
PSPEC OUT.HDR (ADDR [LOGICAL8]);
PSPEC SKIP.LINE ();
ADDR PW0, PW1;
LOGICAL64 PWW1, PWW2, PWW3;
@END
@TITLE LIB01.1(1,11)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
START BATCH
@BOX 2.0
INITIALISE INPUT / OUTPUT
AND LIBRARY
@BOX 3.0
DEFINE DEFAULT INPUT
AND OUTPUT STREAMS
FOR BATCH JOB
@BOX 4.0
CALL COMMAND INTERPRETER
@BOX 5.0
END
@BOX 1.1
PROC START.BATCH;
@BOX 2.1
INIT.IO ();
INIT.LIB ();
@BOX 3.1
DEFINE.INPUT (0, %"CH0*", 0);
DEFINE.OUTPUT (0, %"LPT*", 0, 0);
@BOX 4.1
PPC.SEQ (0);
@BOX 5.1
END
@END
@TITLE LIB01.2(1,11)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
START INTERACTIVE
@BOX 2.0
INITIALISE INPUT / OUTPUT
AND LIBRARY
@BOX 3.0
DEFINE DEFAULT INPUT
AND OUTPUT STREAMS
FOR INTERACTIVE JOB
@BOX 4.0
DEDICATE INPUT CHANNEL 0
TO INTERACTIVE TERMINAL
@BOX 5.0
CALL COMMAND INTERPRETER
@BOX 6.0
END
@BOX 1.1
PROC START.INTERACTIVE;
INTEGER [4] SOURCE;
@BOX 2.1
INIT.IO ();
INIT.LIB ();
@BOX 3.1
DEFINE.INPUT (0, %"CH0*", %180);
DEFINE.OUTPUT (0, %"REP0*", %8100, 0);
@BOX 4.1
SET.CH.STATUS (0, 1, 0, 0);
BREAK.INPUT (0);
I.SOURCE (^SOURCE);
SET.CH.STATUS (0, 2, SOURCE [1], 0);
@BOX 5.1
PPC.SEQ (1);
@BOX 6.1
END
@END
@TITLE LIB01.3(1,9)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
STOP (REASON);
@BOX 2.0
SET ALL TRAPS TO 'ABORT'
@BOX 3.0
END OR RELEASE ALL
OUTPUT STREAMS
@BOX 4.0
OUTPUT STOP INFORMATION
ON STREAM ZERO
@BOX 5.0
TERMINATE PROCESS
@BOX 6.0
END
@BOX 1.1
PROC STOP (REASON);
INTEGER I;
@BOX 2.1
FOR I < LIB05.NO.OF.TRAPS DO
   SET.TRAP (I, ^ABORT);
   SET.RECOVERY.STATUS (I, 0);
OD
@BOX 3.1
0 => I;
WHILE 1 +> I < LIB04.MAX.STREAM.NO DO
   END.OUTPUT (I, REASON);
OD
@BOX 4.1
SELECT.OUTPUT (0);
NEWLINES (0);
OUT.TIME ();
SPACES (1);
OUT.DATE ();
CAPTION (%" CPU USED ");
READ.TIMER ();
OUT.I (PW1,0);
CAPTION (%" STOP REASON ");
OUT.I (REASON, 0);
NEWLINES (1);
END.OUTPUT (0, REASON);
@BOX 5.1
TERMINATE.PROCESS (REASON);
@BOX 6.1
END
@END
@TITLE LIB01.4(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ABORT (TRAP, REASON)
@BOX 2.0
END OUTPUT ZERO AND
TERMINATE PROCESS IMMEDIATELY
@BOX 3.0
END
@BOX 1.1
PROC ABORT (TRAP, REASON);

PSPEC FINAL.ABORT (INTEGER, INTEGER);
PROC FINAL.ABORT (P1, P2);
TERMINATE.PROCESS (-1);
END
@BOX 2.1
SET.TRAP (TRAP, ^FINAL.ABORT);
END.OUTPUT (0, -1);
TERMINATE.PROCESS (-1);
@BOX 3.1
END
@END



@TITLE LIB01.5(1,11)
@COL 1S-2R-3R-4T-5R-6R-8R-10F
@FLOW 1-2-3-4NO-5-6-8-10
@FLOW 4YES-8

@BOX 1.0
RUN JOB (DOCUMENT, SUPERVISOR, HEADER)
@BOX 2.0
INITIALISE HEADER MESSAGE
@BOX 3.0
GENERATE DEFAULT FOR SUPERVISOR
IF NONE SPECIFIED
@BOX 4.0
IS HEADER PROVIDED?
@BOX 5.0
INSERT USERNAME AND PASSWORD
INTO DEFAULT HEADER STRING
@BOX 6.0
FIND A JOBNAME FOR
THE NEW PROCESS
@BOX 8.0
COPY OUTPUT DOCUMENT TO
SPECIFIED SUPERVISOR
@BOX 10.0
END
@BOX 1.1
PROC RUN.JOB (DOC, SUP, HDR);
LOGICAL64 MACH.NAME, JOB.NAME;
INTEGER I, I.STR.NO, O.STR.NO, OLD.I, OLD.O, HEADER.SIZE, CH, JOB.NUM;
LOGICAL8 [80] HDR.A;

DATAVEC JOB.SUP (LOGICAL8)
   "JOB*"
END

PSPEC COPY (ADDR [LOGICAL8], LOGICAL64);
PROC COPY (TO, FRM);
INTEGER I;
FOR I < 8 DO
   IF FRM & %FF => TO^ [7 - I] = 0 THEN
      " " => TO^ [7 - I];
   FI
   FRM ->> 8 => FRM;
OD
END

@BOX 2.1
FOR I < 4 DO
   0 => HDR.A [I];
OD
FOR I < 75 DO
   " " => HDR.A [I + 4];
OD
IF SIZE (HDR) => HEADER.SIZE > 75 THEN
   75 => HEADER.SIZE;
FI
FOR I < HEADER.SIZE DO
   HDR^ [I] => HDR.A [I + 4];
OD
@BOX 3.1
PROCESS.NAME (SUP);
PWW2 => MACH.NAME;
IF PWW1 = 0 THEN
   ^JOB.SUP => SUP;
FI
@BOX 4.1
IF HEADER.SIZE /= 0
@BOX 5.1
26 => HEADER.SIZE;
NAMES ();
COPY (PART (^HDR.A, 4, 11), PWW1);
COPY (PART (^HDR.A, 13, 20), PWW2);
PWW3 <<- 16 ! "00" => JOB.NAME;
@BOX 6.1
0 => JOB.NUM;
WHILE PW0 = 0 DO
   IF 1 +> JOB.NUM & %F = 10 THEN
      JOB.NUM + %100 & %F00 => JOB.NUM;
   FI
   LOOK.UP.PROCESS (JOB.NUM ! JOB.NAME, MACH.NAME);
OD
COPY (PART (^HDR.A, 22, 29), JOB.NUM ! JOB.NAME);
@BOX 8.1
DEFINE.INPUT (-1, DOC, 0) => I.STR.NO;
DEFINE.OUTPUT (-1, SUP, 0, 0) => O.STR.NO;
CURRENT.INPUT () => OLD.I;
CURRENT.OUTPUT () => OLD.O;
SELECT.INPUT (I.STR.NO);
SELECT.OUTPUT (O.STR.NO);
PROMPT (%"/");
"$L" => CH;
WHILE [I.ENQ () =< 0 OR I.STR.NO = 0] AND
   [CH /= "$L" OR NEXT.CH () /= "/" OR [I.STR.NO /= 0 /= OLD.I]] DO
   OUT.CH (IN.CH() => CH);
OD
0 => HDR.A [1] => HDR.A [2] => HDR.A [3];
1 +> HEADER.SIZE => HDR.A [0];
"$L" => HDR.A [HEADER.SIZE + 3];
OUT.HDR (PART(^HDR.A, 0, HEADER.SIZE + 3));
IF I.STR.NO = 0 OR I.STR.NO = OLD.I THEN
   IN.CH ();
   SKIP.LINE ();
FI
SELECT.INPUT (OLD.I);
SELECT.OUTPUT (OLD.O);
END.INPUT (I.STR.NO, 1);
END.OUTPUT (O.STR.NO, 1);
@BOX 10.1
END
@END




