Trailing-Edge - PDP-10 Archives - bb-k345a-sb - kill.doc
There are 5 other files named kill.doc in the archive. Click here to see a list.

Last revised:  June 30, 1976.

	It is assumed that you know the general actions which
KILL can perform.  This documentation will describe how to perform
those actions (and others) by way of a CCL file.  This allows the
user's own program to seem to be able to do the killing, sending of
messages and other things, all by itself.  In addition, some of the
internal workings of KILL are explained so that you can know what
certain combinations of commands are going to do.  There are three
things to be discussed in this documentation:

A)	The format of a CCL file and the functions available.

B)	How to find out what errors KILL found when it
	attemped to execute a given CCL file.

C)	The order of execution of commands to KILL and
	a general discussion of the methods of action.
	A.	The format of KILL's CCL file

	If KILL is run with a runoffset of 1, it will look for a CCL
file to be executed.  If run with a runoffset of 0, or if no CCL file
is found, it will then get commands from the TTY.  KILL first looks for
a TMPCOR file by the name of 'KIL'.  If not found, it will then look for
the file  ALL:nnnKIL.TMP[PPN]  where nnn is three digits representing
the current job's job number.  The LOOKUP for the file is done only
on the user's own UFD (not his path) and is done physical only.  This
minimizes the chances of the wrong file being found.

The CCL file can be no longer than 128 decimal words.  If it is any
longer than that (1 block) then the rest of the file is ignored.
The data in the CCL file is in binary, and is arranged as a series
of "function blocks" which follow right after each other.  Each
function block is a function (command) to perform, together with
all the arguments necessary for that function.  Most function blocks
have a constant length, the only exception at present being the
function to send a message.  The CCL file is ended when a function
block starts with a null word (this is function fn.end).  So the
CCL file is arranged as in the following diagram:

	/                               /
	/       FUNCTION BLOCK 1        /
	/                               /
	/                               /
	/       FUNCTION BLOCK 2        /       128 words maximum
	/                               /
	/                               /
	/           . . . .             /
	/                               /
	/                               /
	/       FUNCTION BLOCK N        /
	/                               /
	!              0                !

On the next few pages is a description of each type of function
block in detail.
FUNCTIONS:	FN.STP	   2		[Two words needed]
		FN.DET	   3
		FN.KIL	   4
		FN.ATT	   6
		FN.LST	   7

	!  FUNCTION CODE   !     ARGUMENT     !

	where ARGUMENT is one of the following quantities:

	   n		If n is small the argument is for job n.
	   200000+n	If n is larger than .uxtrm than it is TTYn.
	   -1		If n is -1 then the argument is all of the
			jobs which have the indicated PPN.

	PROJECT-PROGRAMMER NUMBER is the PPN of the job(s) that are
	indicated.  If either (or both) half is zero, that half is
	defaulted to that of your own PPN.  So that leaving this
	zero implies the job has the same PPN as your own job.

FUNCTIONS:	FN.ZAP	   5		[One word needed]
		FN.NOT	   9

	!  FUNCTION CODE   !     ARGUMENT     !

	where ARGUMENT is identical to that given for the format
	on the previous page for the functions FN.STP, FN.KIL etc.
	The difference is only that there is no PPN argument for these
	functions, because it is not necessary.  The zap function has
	no use for a PPN argument, for it just kills off detached, not-
	logged in jobs, and the not function doesn't need them because
	it would be redundant.
FUNCTION:	FN.FLG	   1		[One word needed]

	!  FUNCTION CODE   !    FLAG BITS     !

	where FLAG BITS are quantities set by the user to specify
	how certain actions are to be carried out.  All bits not
	mentioned in the following list should always be kept zero,
	to allow for future expansion.  The default value of all
	bits is always 0.

	Name	Value	  Description

	FL.SUP	  1	Suppress all output to the TTY, even errors.
	FL.PHS	  2	When a RUN uuo is done, do it PHYSICAL-ONLY.
	FL.UMA	  4	Attach user's job to my TTY in USER mode.
	FL.NTC	  10	Do not ever write a TMPCOR error file.
	FL.DOT	  20	End text send to other TTYs with "monitor dots"
			if the other TTYs are in monitor mode.
	FL.IMP	  40	Suppress all non-error messages.

	Note that the flags are not set until this function is found
	when searching the CCL file, so if it is important to have a
	flag set very soon after KILL begins, this function should be
	one of the first function blocks.
FUNCTION:	FN.RUN	   11		[Seven words needed]

	!        DEVICE FOR RUN UUO           !
	!           PROGRAM NAME              !
	!      EXTENSION FOR .LOW FILE        !
	!                 0                   !
	!          CORE ARGUMENT              !

	where RUN-OFFSET is the offset to use for the RUN uuo.

	The other arguments are a standard run block.  Nothing
	is assumed about the arguments, if you do not supply an
	important argument (such as the device) then the RUN uuo
	is bound to fail.

	An error file will not be written at all unless you have
	specified this function.  Also, to make sure that your own
	program is run on almost any error that can occur, this
	function should be one of the first function blocks in the
	CCL file, so that KILL can store what to run before an
	error occurs.
FUNCTION:	FN.MSG	   13		[Three or more words needed]

	!  FUNCTION CODE   !     ARGUMENT     !
	/                                     /
	/                                     /

	where ARGUMENT is similar to the argument for stopping,
	killing, zapping, etc.  However, there is one more possible
	form of the argument and that is:

	   -2	 The text is to be sent not only to the jobs's
		 controlling terminal, but to ALL ttys which are
		 in use by the given PPN.  So if a TTY is just
		 INITed or ASSIGNed to a job of the given PPN, then
		 the message will be sent to it also.

	The length of the text is determined by the first NULL character
	found.  The next function block will then start with the next
	word after the word containing the NULL.
FUNCTIONS:	FN.END	   0		[One word needed]
		FN.XIT	   12
		FN.RET	   10

	!  FUNCTION CODE   !        0         !

	These functions are very simple and no arguments are required
	for them.  The function FN.END has already been explained.
	It is simply a zero word, and ends the CCL file.

	The function fn.xit will cause KILL to exit when all actions
	have been finished.  This is true even if we have attached
	A JOB TO our TTY with the FN.ATT function; we will exit
	instead of logging out.  Furthermore, if we should do a RUN uuo,
	we will exit if it fails, whereas we would normally log out on
	a RUN uuo failure.

	The function FN.RET simply returns the user to the TTY that he
	last detached from.  If he is already on a TTY, then no action
	is taken.  The return function will fail if we had beed detached
	from a PTY, or if the TTY is now in use by another job.
	To help illustrate the use of the function blocks for making
an actual CCL file, the following code is an example of a legal and
useful CCL file data for KILL.  It will tell all of my jobs that they
are about to be logged off, log them all out, and then exit.  There
is to be no output to the terminal, unless an error occurs:

[Your job is being killed]
	The following table is a summary of all the available functions
and some of the characteristics of them.  The decimal function code is
given along with its mnemonic.  The order value of the function is
given, which determines when each function is processed.  The length
of the function blocks which were explained above is listed.  The
command which the function is similar to is listed (and is actually
the same, since the command is converted to the same format.)
Finally, a short description of the action of the function is given.

 Function     Order   Length   Command     Short Description

0   FN.END	0	1	 --	    End list of functions
1   FN.FLG	0	1	 --	    Set user flags
2   FN.STP	3	2	STOP	    Stop a job
3   FN.DET	3	2	DETACH	    Detach a job
4   FN.KIL	3	2	KILL	    Log out a job
5   FN.ZAP	3	1	ZAP	    Kill a useless job
6   FN.ATT	6	2	ATTACH	    Attach a job to our TTY
7   FN.LST	5	2	LIST	    Type a "systat" of a job
8   FN.HLP	1	1	HELP	    Type out the help text
9   FN.NOT	3	1	NOT	    Exempt a job from an action
10  FN.RET	4	1	 --	    Return to our old TTY
11  FN.RUN	0	7	 --	    Set up program to be run
12  FN.XIT	0	1	EXIT	    Exit from KILL when done
13  FN.MSG	2	3+N	 --	    Send a message to a job
	B.	Finding out the errors that KILL finds

	There are two types of errors which can occur in running KILL.
The first kind of error only affects the action which was occurring at
the time.  The other actions which were happening at the same time (if
some killing, stopping etc. was taking place) are not affected and they
proceed with no ill effects.  If there are any future actions which were
supposed to have been done, they will still be processed.

	The second type of error, which should never occur, is a fatal
error which affects all of KILL and prevents KILL from running normally.
In this case, all actions occurring at the time are stopped, and no other
action will occur.  The only exception to this if if a RUN uuo was set
up to be done, that will still occur and the fatal error will still be
written in the error file.

	To see if an error occurred look at the right half of location
.JBERR to see if it is nonzero.  The right half of .JBERR will contain
the total error count that KILL had, so that if it is now zero there
were no errors.  If nonzero, though, some error has occurred and you
should then read the TMPCOR file 'kil' which contains a list of errors.
The TMPCOR file has the following format:

	!                 -1                  !
	!         ERROR CODE # 1              !
	!           ARGUMENT # 1              !
	!         ERROR CODE # 2              !
	!           ARGUMENT # 2              !
	/                                     /
	/             . . . .                 /
	/                                     /
	!         ERROR CODE # N              !
	!           ARGUMENT # N              !
	!                 0                   !
	The first word of the error file is always -1.  This helps
insure that you are really looking at the error file, and not an
old CCL file that was not deleted somehow (they have the same name).
Each error that is stored comes in the form of a pair of words.
The first word is the error code, and determines what the particular
error was.  The second word contains the job number associated with
that error.  Notice that this "job" number is sometimes useless and
then should be ignored.  An example of such an error is if an illegal
TTY number is given as an argument to a function.  It should be clear
which errors are those where the job number returned has meaning.

	The error codes for the two types of errors start at
different values, and do not overlap so that it is possible to
tell them apart.  The non-fatal errors start at the number 101
decimal, while the fatal errors start at 1.  If you ever write
a program which tries to interpret the error codes, make sure you
are ready to handle an error code which is larger than the maximum
ones which exist at the present time.  This will ensure that your
program will still work if more error codes are added later when
the need arises.

If there are more errors than will fit in a TMPCOR file, you lose.
All of the error codes which did not fit in TMPCOR are lost.  But
hopefully you will never have that many errors in one run to KILL,
and you can see how many errors you missed by comparing the number
of the errors received with the number in .JBERR.
The following table lists all the non-fatal errors at present:

Error 		description of error

101	KILL was unable to allocate core to set up buffers
	for a PTY to use for killing, stopping, etc. a job.

102	KILL had waited for a minute for a PTY to become free
	so that it could be used, but none became free.

103	An ATTACH uuo failed to detach a job, or put a job
	on a PTY, or attach a job to our TTY.

104	In attempting to find out the TTY number connected to
	a PTY, an IONDX. uuo failed.

105	A GETTAB uuo failed in checking the status of a job,
	or in finding out information about a job, etc.

106	A JOBSTS uuo failed while finding the status of a PTY
	or the status of a job.

107	When trying to log out a job, it wasn't running the proper
	program (LOGOUT or KILL).

108	While trying to log out a job, the job stopped running
	and so couldn't be logged out.

109	While trying to log out a job, the job went into a TI
	wait and so couldn't be logged out.

110	While waiting for a job to log out, KILL noticed that
	it was no longer on our PTY and had been moved somehow.

111	We waited for one minute for a job to be logged out, but
	it never did log out.

112	The job which we are trying to kill, stop, etc. is
	not logged in and so we can't hurt it.

113	While performing some action on a job, and waiting for that
	action to be done, a check on the job noticed that the job
	had changed PPNS.
114	The job we are trying to kill, stop, etc. is running a program
	which is JACCT'd, and we are not allowed to hurt it.

115	We tried to zap a job which was logged in, and this is
	not allowed.

116	We tried to zap a job which was not detached, and this is
	not allowed.

117	We tried to stop, kill, etc. my own job which is not allowed.

118	The job number which was given for some action was out of
	bounds and is illegal.

119	The job number which was given is not presently in use.

120	An action was given for a job whose PPN did not match that of
	the PPN given by the user.  This helps prevent the wrong
	job from being killed, etc.

121	We tried to stop, kill, etc. a job but we were not privileged
	to do so.

122	In creating a process to take care of the action of stopping,
	etc. a job, we failed to get enough core to handle the process.

123	A tty argument was given for some action, but it is not a
	legal TTY number.

124	In trying to find out what job was connected to a given TTY,
	a DEVTYP uuo failed so we can't tell what job ownes the TTY.

125	A tty number was given for some function, but no job is
	on the TTY.

126	We tried to zap a not logged in and detached job, but
	we failed to do so.

127	We were told to stop a job, but we failed to do so.
128	We were given more than one job to be attached to
	our TTY, but only one such job can be given.

129	We were detached and trying to attach back to our old TTY,
	but that TTY happened to be a PTY, and we are not allowed
	to attach back to a PTY.

130	We tried to attach back to a TTY but the OPEN uuo for that
	TTY failed.  It is probably in use by another job.

131	We were told to output a message to a job which we are not
	privileged to send to.

132	We can't attach a job to our TTY because we are in monitor
	mode, and we can't detach unless we are in user mode.

133	We can't attach a job to our TTY because we are a BATCH
	job, which we are not allowed to detach ourself from.

134	We can't attach a job to our TTY because we are detached.

135	We can't stop, kill, etc. a job which happens to be a
	BATCH job (this error might never occur, depending if
	KILL was assembled to allow it or not).

136	In trying to send a message to a given tty, the TRMOP.
	uuo to send the message failed.
The following table lists all the fatal errors at present:

Error		Description of error

1	KILL has found some internal error, in that an illegal
	LUUO was executed.

2	KILL tried to find out if it was being controlled by a
	job, but the CTLJOB uuo failed.

3	Some GETTAB failed which we must have work in order
	to continue.

4	KILL tried to find the I/O index of PTY0, but the IONDX.
	uuo failed.

5	While scanning the CCL file given by a user, a function
	code was found which was not legal.

6	KILL tried to OPEN disk in order to read the CCL file
	given by a user, but the OPEN uuo failed.

7	KILL found a CCL file but in attempting to read it
	into core the IN uuo failed.

8	In looking for a CCL file, a LOOKUP error was gotten
	which was different than file not found.

9	The number of jobs possible on the system exceeds the
	size of internal tables.  KILL must be reassembled
	with the size of tables made large enough.

10	While waiting for some process to want to run, the
	HIBER uuo failed.
	C.	Description of the actions of KILL

	When TTY commands are interpreted by KILL, it first converts
them to binary codes, in exactly the same format which users give
when they write a CCL file for KILL.  The order of the function blocks
exactly corresponds with the order that the commands were typed in.
So in what follows, there is no distinction between actions occurring
from typed-in commands, and those obtained from a CCL file.

	Each different function code has associated with it a number
which is its "priority" , or its "order".  This number determines in
what order the functions will be processed.  The first functions to be
processed have the order number 0, and the other functions have order
numbers which form an ascending sequence.  What happens is that KILL
scans the binary data (CCL file or converted TTY commands) a number of
times, one scan for each order number.  When a function block is found
which matches the current priority number, it is processed.  Note that
processing a function block does not imply that the action is carried
out right then, just that it has been recognized and is "set up".
As an example, the exit or run runctions do not take effect when seen,
but simply are used to set up internal variables for the later actions.

	Now it is important to notice that some functions have the same
ordering number.  In this case, those functions are processed together
and the last function block found will supercede any previous function
block which it conflicts with.  This is how the not function works:
It simply zeroes an internal variable for a job, thereby clearing any
action for the job that a previous function may have set.  And the
other superceeding actions are similar.  Note that the not function
has no effect on the attach function, for they have separate priorities
and so are never processed together.  This is reasonable since the
attach function has to be handled at a different time that the stop,
kill, etc. functions, and it only applies to one job anyway.  Note also
that since the attach function does not have the same ordering number
and therefore does not conflict with the stop function, THEN BOTH OF

	The main point of all this is that the order that functions
are placed in the CCL file (or typed in) is irrelevant when the
functions have different ordering numbers, and relevant if they have
the same ordering numbers, and conflict.  Hopefully you can see what
any combination of commands will do now.

	The order of the functions is given in the table of functions
which was shown earlier in this file.
In stopping, detaching, killing, or attaching a job, the main worry
is that the program to be crumped must have some warning.  This comes
about because some programs assume that they cannot be stopped except
when they wish to be stopped.  This is so that they can finish up some
important business before exiting, such as write some data to a file,
unload a magtape, print out some final statistics to the TTY, and such
things.  If KILL was to rip off the job with no warning, all of these
things would not be possible, and the programs whould not work as they
should.  So, to help in this cause, but still allow KILL to carry out
its own functions, which is to stop the program, it warns the job that
it is about to die, and waits for a while until the program should have
had time to finish and exit.  This is done by forcing .HALT commands
on the job, which is equivalent to the user typing ^C's to the TTY.
The .HALT will work even if the user's terminal is slaved, but not
when the job is detached.  If a certain amount of time goes by and
the job has not been nice and exited, then KILL will be impatient and
will force HALT commands to the job, which are not able to be trapped.
It takes about one minute for KILL to start to get mean.  While waiting
for the job to be stopped, the following actions are done every
one-half second:

	TTY's input buffer is cleared
	The job's program-to-run word is cleared
	.HALT or HALT is forced

Finally, after the job has been stopped, the terminal is unslaved so
that the TTY can be used again.  If the job was originally detached,
KILL has no choice but to attach it to a PTY so that it can be stopped
and in this case, no wait is made.  The reason for this is that a mean
user could attach the job himself, and stop it with no waiting period.
So we don't have to wait either.
If our goal is to log off a job (or zap a not-logged-in job) we must
use a PTY so that we can type the proper commands to the job.  KILL
gets the PTY first, before any other actin is taken on the job.  This
will prevent a half-done action to be started if no PTYs become free,
and also gives the user less time to start up another program before
the job is ripped off of his TTY.

	Kill will only use a set number of PTYs at any time, no matter
hom many jobs are to be killed.  This number is currently 5.  The
reason for this is that PTYs are a finite resource, and we don't want
to use up all the PTYs for ourself, and leave none for another job
which also wants one.  KILL will run happily if only one PTY is
available to it, but it might run slower.

	If KILL ever tries to output any text to the terminal, because
of an error message, or because of some status report, it makes a check
first to see if KILL is detached, or on a TTY in monitor mode.  If
this is true, no message is output and KILL just proceedes as if
it was output.  This allows KILL to run detached without ever hanging
in a TO state.

	While KILL is running, and a couple of ^C's are typed to it,
it just traps them and exits.  All actions that were occurring are
terminated immediately, and if any jobs were on a PTY at the time,
they will be detached as KILL lets go of the PTYs it was using.

	One final remark, and that is not concerned with KILL in
particular, is that if you are logging out a job, and LOGOUT gets
stopped in the middle, the job's UFD interlock may be messed up
and this will cause a long wait the next time that user logs in or
out.  So it is recommended that you not ^C KILL while it is busy
logging out some job unless you really have to.