mirror of
https://github.com/PDP-10/its.git
synced 2026-05-05 15:44:10 +00:00
KCC - C compiler.
Binary-only compiler and library, plus documentation and include files for compiling new programs.
This commit is contained in:
934
doc/kcc/libc.doc
Executable file
934
doc/kcc/libc.doc
Executable file
@@ -0,0 +1,934 @@
|
||||
KCC Runtime Library documentation
|
||||
|
||||
This file summarizes the overall contents of the KCC C
|
||||
library, and is used by implementors as a status file to determine the
|
||||
portability or availability of particular library functions. This
|
||||
file does NOT document what the functions do or how to use them, because
|
||||
this information is already available in published form (see [CARM]
|
||||
and [UPM] at the end of this page).
|
||||
|
||||
The organization of routines here follows that of the
|
||||
descriptions in Part II of [CARM]. Note that as of this writing there
|
||||
are two versions of CARM; the first (v1) appeared in 1984, and the
|
||||
second (v2) in 1987. All references here are to the most recent (v2)
|
||||
version, and the organization of this file follows sections 13-22 of
|
||||
v2 rather than section 11 of v1.
|
||||
|
||||
KCC implements all CARM routines. In addition, there are
|
||||
other routines which are part of KCC's C library, either for
|
||||
compability with Un*x systems like V7 and BSD, or to provide access to
|
||||
certain operating system functions. For the most part these have been
|
||||
listed in whichever CARM section below is most appropriate, right
|
||||
after the "official" CARM functions.
|
||||
|
||||
Additional information:
|
||||
|
||||
[CARM] Book: "C: A Reference Manual", Second edition, ISBN 0-13-109802-0
|
||||
by Samuel P. Harbison & Guy L. Steele, Jr.
|
||||
Also known as "H&S". This is a very good reference and
|
||||
describes most of the library functions.
|
||||
[UPM] Book: "Unix Programmer's Manual".
|
||||
4.2/4.3BSD version (Reference Guide) printed by the USENIX Association.
|
||||
[MAN] Files: "man foo" on most Un*x systems.
|
||||
|
||||
[TMX] File: LIBTMX.DOC - documents the extended time functions, time_*().
|
||||
[USYS] File: USYS.DOC - contains a summary of those particular
|
||||
KCC functions which simulate UN*X system calls. This is
|
||||
considerably more implementor-oriented.
|
||||
[SIGS] File: SIGNAL.DOC - contains an overview of the KCC signal
|
||||
implementation.
|
||||
[LIBC] File: LIB/CODING.DOC - describes guidelines for writing KCC library
|
||||
functions and identifies certain crucial files. This is primarily
|
||||
for implementors.
|
||||
|
||||
Contents summary:
|
||||
Section 13: Standard Language Additions
|
||||
Section 14: Character Processing (V1: Sec 11.1)
|
||||
Section 15: String Processing (V1: Sec 11.2)
|
||||
Section 16: Memory Functions
|
||||
Section 17: Input/Output Facilities (V1: Sec 11.5)
|
||||
Section 18: Storage Allocation (V1: Sec 11.4)
|
||||
Section 19: Mathematical Functions (V1: Sec 11.3)
|
||||
Section 20: Time and Date Functions
|
||||
Section 21: Control Functions
|
||||
Section 22: Miscellaneous Functions
|
||||
Section BSD(3N): BSD network functions
|
||||
Section TRM(3X): TERMCAP terminal independent functions
|
||||
Section TMX(3X): Time and Date Functions (Extended)
|
||||
Section KCC-1: KCC-specific general-purpose functions
|
||||
|
||||
|
||||
Library function listing format:
|
||||
|
||||
Name Module Port Comments
|
||||
(routine name) (source file) (see below)
|
||||
Name: Name of the function, variable, or macro.
|
||||
Module: Source file module. "XXX" means the pathname "lib/XXX.C"
|
||||
unless the section identifies a different source directory,
|
||||
such as "usys/" or "stdio/", etc.
|
||||
Header files are shown as "<xxx.h>".
|
||||
Port: A status code indicating portability, as follows:
|
||||
E = file #includes "c-env.h" for environment configuration.
|
||||
<sys> - runs on the given sys, one of: T20,10X,T10,WAITS,ITS.
|
||||
*10 = portable to all of the above PDP-10 systems.
|
||||
* = fully portable (either no OS-dependent stuff, or a
|
||||
fully-portable conditional exists)
|
||||
|
||||
Section 13: Standard Language Additions
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
NULL <stddef.h>,<stdio.h> *
|
||||
typedef ... ptrdiff_t; <stddef.h> *
|
||||
typedef ... size_t; <stddef.h> *
|
||||
int errno; usys/URT * (see USYS.DOC)
|
||||
char *strerror(errnum); STRERR E T20,10X
|
||||
void perror(s); stdio/PERROR E T20,10X
|
||||
int sys_nerr; STRERR *
|
||||
char *sys_errlist[]; STRERR *
|
||||
constant EDOM; <errno.h> *
|
||||
constant ERANGE; <errno.h> *
|
||||
__DATE__ in KCC *
|
||||
__FILE__ in KCC *
|
||||
__LINE__ in KCC *
|
||||
__TIME__ in KCC *
|
||||
__STDC__ NOT YET (in KCC)
|
||||
va_alist,va_dcl <varargs.h> * KCC Non-ANSI form
|
||||
va_list,va_start,va_arg,va_end <varargs.h> * KCC Non-ANSI form
|
||||
va_list,va_start,va_arg,va_end <stdarg.h> * KCC ANSI form
|
||||
|
||||
Notes:
|
||||
All CARM facilities are supported, but __STDC__ is not defined
|
||||
and will not be until KCC can provide full ANSI support. This of course
|
||||
must wait until the ANSI draft standard becomes more concrete.
|
||||
The standard set of UN*X error codes are provided, in particular
|
||||
EDOM and ERANGE. All others apply only to failing UN*X system call
|
||||
simulations.
|
||||
Both <vararg.h> and <stdarg.h> are provided. Since they are
|
||||
incompatible, they cannot be used together and only one of them
|
||||
can be included by any particular program.
|
||||
|
||||
Section 14: Character Processing (V1: Sec 11.1) Src: <ctype.h>, lib/ctype.c
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
int isalnum(c); CTYPE *
|
||||
int isalpha(c); CTYPE *
|
||||
int isascii(i); CTYPE * CARM/BSD
|
||||
int iscntrl(c); CTYPE *
|
||||
int iscsym(c); CTYPE * CARM only
|
||||
int iscsymf(c); CTYPE * CARM only
|
||||
int isdigit(c); CTYPE *
|
||||
int isodigit(c); CTYPE * CARM only
|
||||
int isxdigit(c); CTYPE *
|
||||
int isgraph(c); CTYPE *
|
||||
int isprint(c); CTYPE *
|
||||
int ispunct(c); CTYPE * DIFFERENT (no space!) CARM goofed.
|
||||
int islower(c); CTYPE *
|
||||
int isupper(c); CTYPE *
|
||||
int isspace(c); CTYPE *
|
||||
int iswhite(c); - - rare variant of isspace, not provided.
|
||||
int toascii(i); CTYPE * CARM/BSD
|
||||
int toint(c); CTYPE * CARM only
|
||||
int tolower(c); CTYPE * allows any case
|
||||
int toupper(c); CTYPE * allows any case
|
||||
int _tolower(c); CTYPE * CARM only
|
||||
int _toupper(c); CTYPE * CARM only
|
||||
|
||||
Tests: LIB/TEST/TCTYPE.C tests all these functions.
|
||||
|
||||
Notes:
|
||||
All CARM facilities are supported; <ctype.h> must be included.
|
||||
All work with any unsigned 9-bit character value and EOF; most are
|
||||
macros and very fast. None evaluate their argument more than once.
|
||||
The ispunct() function differs from the CARM description,
|
||||
which claims that "space" is included in the set. Neither the BSD nor
|
||||
the ANSI draft version of ispunct() does this however, so we have
|
||||
assumed that H&S made a mistake here, and the KCC version excludes
|
||||
"space".
|
||||
BSD's implementation of tolower and toupper is incorrect
|
||||
(corresponds to _tolower and _toupper). KCC's corresponds to CARM.
|
||||
|
||||
Implementation notes:
|
||||
The flag table is large enough that any unsigned 9-bit char
|
||||
value can be safely used as index. On the PDP-10 the table is an
|
||||
integer array for speed, and is fully portable, but the macro
|
||||
_CT_TABTYPE can be defined during installation if a char array is
|
||||
preferable. <ctype.h> defines all of the macros. CTYPE.C defines the
|
||||
_ctyp1 and _ctyp2 tables, plus some small auxiliary routines that the
|
||||
macros may call.
|
||||
|
||||
Section 15: String Processing (V1: Sec 11.2) Src: <string.h>, lib/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
char *strcat(s1,s2); STRING *
|
||||
char *strncat(s1,s2,n); STRING *
|
||||
int strcmp(s1,s2); STRING *
|
||||
int strncmp(s1,s2,n); STRING *
|
||||
char *strcpy(s1,s2); STRING *
|
||||
char *strncpy(s1,s2,n); STRING *
|
||||
int strlen(s); STRING *
|
||||
char *strchr(s,c); STRING *
|
||||
char *index(s,c); STRING * synonym for "strchr"
|
||||
int strpos(s,c); STRING * CARM only
|
||||
char *strrchr(s,c); STRING *
|
||||
char *rindex(s,c); STRING * synonym for "strrchr"
|
||||
int strrpos(s,c); STRING * CARM only
|
||||
int strspn(s,set); STRING *
|
||||
int strcspn(s,set); STRING *
|
||||
char *strpbrk(s,set); STRING *
|
||||
char *strrpbrk(s,set); STRING * CARM only
|
||||
char *strstr(src, sub); STRING * CARM/ANSI only
|
||||
char *strtok(str, set); STRING * ANSI/BSD/S5/CARM (not V7)
|
||||
double strtod(str, ptr); ATOI *
|
||||
long strtol(str,ptr,base); ATOI *
|
||||
unsigned long strtoul(str,p,b); ATOI *
|
||||
double atof(str); ATOI *
|
||||
int atoi(str); ATOI *
|
||||
long atol(str); ATOI *
|
||||
|
||||
Additional non-CARM functions:
|
||||
Non-case-sensitive versions of the above functions are
|
||||
provided by the STRUNG module, declared in <strung.h>:
|
||||
|
||||
int strCMP(s1, s2); STRUNG *
|
||||
int strnCMP(s1, s2, n); STRUNG *
|
||||
char *strCHR(s, c); STRUNG *
|
||||
char *strSTR(src, sub); STRUNG *
|
||||
|
||||
Tests: LIB/TEST/TSTRIN.C partially tests these functions.
|
||||
|
||||
Notes:
|
||||
All CARM facilities are supported. <string.h> must be
|
||||
included. <strings.h> also exists for BSD compatibility; it merely
|
||||
includes <string.h>.
|
||||
|
||||
Implementation notes:
|
||||
This stuff can use more conditionalizing in order to optimize for
|
||||
specific configurations. The routines are portable, but are coded to
|
||||
encourage use of the PDP-10 ILDB/IDPB instructions (opposite of the optimal
|
||||
PDP-11 order!)
|
||||
|
||||
Section 16: Memory Functions Src: lib/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
char *memchr(ptr,val,len); MEMSTR E * ANSI/BSD/CARM/S5
|
||||
int memcmp(ptr1,ptr2,len); MEMSTR E * ANSI/BSD/CARM/S5
|
||||
int bcmp(ptr1,ptr2,len); MEMSTR E * BSD/CARM (calls memcmp)
|
||||
char *memcpy(dest,src,len); MEMSTR E * ANSI/BSD/CARM/S5
|
||||
char *memccpy(dest,src,c,len); MEMSTR E * BSD/CARM/S5
|
||||
void *memmove(dest,src,len); MEMSTR E * ANSI/ CARM (needs optimiz)
|
||||
char *bcopy(src,dest,len); MEMSTR E * BSD/CARM (calls memcpy)
|
||||
char *memset(ptr,val,len); MEMSTR E * ANSI/BSD/CARM/S5
|
||||
void bzero(ptr,len); MEMSTR E * BSD/CARM (calls memset)
|
||||
|
||||
Tests: LIB/TEST/TBCOPY.C tests bcopy() and bzero().
|
||||
|
||||
Notes:
|
||||
All CARM facilities are supported. The header file for
|
||||
declaring these routines is <string.h> as per ANSI, but <memory.h>
|
||||
also exists for BSD compatibility.
|
||||
These are guaranteed to work for all valid KCC byte sizes,
|
||||
i.e. any of 6, 7, 8, 9, and 18-bit bytes. Remember that the
|
||||
arguments must be of type (char *), rather than (int *). Both
|
||||
memcpy() and memset() have special optimization built into them so
|
||||
that they are very fast for large amounts of data. memmove() is much
|
||||
slower.
|
||||
|
||||
Section 17: Input/Output Facilities (V1: Sec 11.5) Src: lib/stdio/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
constant EOF; <stdio.h> *
|
||||
struct FILE; <stdio.h> *
|
||||
FILE *fopen(path,typ); FOPEN * See notes on next page.
|
||||
int fclose(fp); FCLOSE *
|
||||
int fflush(fp); FFLUSH * also works on input streams
|
||||
FILE *freopen(path,typ,fp); FREOPE *
|
||||
int setvbuf(fp,buf,type,size); SETBUF *
|
||||
void setbuf(fp,buf); SETBUF *
|
||||
FILE *stdin; <stdio.h> (m) *
|
||||
FILE *stdout; <stdio.h> (m) *
|
||||
FILE *stderr; <stdio.h> (m) *
|
||||
int fseek(fp,off,typ); FSEEK *
|
||||
long ftell(fp); FTELL *
|
||||
void rewind(fp); REWIND *
|
||||
int fgetc(fp); FGETC *
|
||||
int getc(fp); <stdio.h> (m) *
|
||||
int getchar(); <stdio.h> (m) *
|
||||
int ungetc(c,fp); UNGETC *
|
||||
char *fgets(s,n,fp); FGETS *
|
||||
char *gets(s); GETS *
|
||||
int fscanf(fp,fmt,ptrs); SCANF *
|
||||
int scanf(fmt,ptrs); SCANF *
|
||||
int sscanf(s,fmt,ptrs); SCANF *
|
||||
int fputc(c,fp); FPUTC *
|
||||
int putc(c,fp); <stdio.h> (m) *
|
||||
int putchar(c); <stdio.h> (m) *
|
||||
int fputs(s,fp); FPUTS *
|
||||
int puts(s); PUTS *
|
||||
int fprintf(fp,fmt,args); PRINTF *
|
||||
int printf(fmt,args); PRINTF *
|
||||
int sprintf(s,fmt,args); PRINTF *
|
||||
int vfprintf(fp,fmt,arg); PRINTF *
|
||||
int vprintf(fmt,arg); PRINTF *
|
||||
int vsprintf(s,fmt,arg); PRINTF *
|
||||
int fread(ptr,siz,cnt,fp); FREAD *
|
||||
int fwrite(ptr,siz,cnt,fp); FWRITE *
|
||||
int feof(fp); <stdio.h> (m) *
|
||||
int ferror(fp); <stdio.h> (m) *
|
||||
void clearerr(fp); <stdio.h> (m) *
|
||||
int remove(filename); REMOVE * just calls unlink()
|
||||
int rename(oldnam,newnam); RENAME * null file, uses USYS rename().
|
||||
FILE *tmpfile(); TMPFIL *
|
||||
char *tmpnam(buf); TMPNAM E T20,10X
|
||||
char *mktemp(buf); MKTEMP E T20,10X uses HPTIM%, not getpid
|
||||
|
||||
These functions were recently added to the ANSI C draft (not yet implemented):
|
||||
|
||||
int fgetpos(FILE *stream, fpos_t *pos); ??
|
||||
int fsetpos(FILE *stream, const fpos_t *pos); ??
|
||||
|
||||
|
||||
Additional STDIO functions for V7/BSD compatibility:
|
||||
|
||||
constant BUFSIZ; <stdio.h> * V7/BSD
|
||||
constant NULL; <stdio.h> * V7/BSD
|
||||
FILE *fdopen(fd,type); FDOPEN * V7/BSD open w/existing FD
|
||||
int fileno(fp); <stdio.h> (m) * V7/BSD
|
||||
int getw(fp); GETW * V7/BSD Get word (int)
|
||||
int putw(w,fp); PUTW * V7/BSD Put word (int)
|
||||
void setbuffer(fp,buf,size); SETBUF * BSD
|
||||
void setlinebuf(fp); SETBUF * BSD do linebuffering
|
||||
|
||||
Additional KCC functions:
|
||||
|
||||
FILE *sopen(s,type); SOPEN * (KCC only) open string for I/O
|
||||
|
||||
Internal globals, not for user consumption:
|
||||
|
||||
FILE _sios[]; <stdio.h> * internal array
|
||||
void _cleanup(); CLEANU * called by exit() for cleanup
|
||||
|
||||
Tests: LIB/TEST/TFSEEK.C, TFTEL1.C, TFTEL2.C - tests fseek/ftell
|
||||
LIB/TEST/TPRINT.C - tests printf.
|
||||
|
||||
Notes for Section 17 (STDIO):
|
||||
|
||||
See <.LIB.STDIO>-READ-.-THIS- for implementation-specific details.
|
||||
|
||||
Note that some facilities, in particular putc and getc, are
|
||||
implemented as macros.
|
||||
|
||||
In general, the sequence CR-LF is converted to LF on 7-bit
|
||||
input, and LF converted to CR-LF on 7-bit output. This conversion is
|
||||
performed by the system call read/write functions and not by STDIO,
|
||||
however. See the notes on fopen() below for details.
|
||||
|
||||
[17.2] (V1 11.5.7) fflush():
|
||||
This should normally only be called on an output stream;
|
||||
however, if called on an input stream, fflush() flushes any buffered
|
||||
but unread data. This feature is probably not portable.
|
||||
|
||||
[17.2] (V1 11.5.10, 11.5.15) fopen(), freopen():
|
||||
These implement all the H&S type specification characters,
|
||||
with certain defaults and settings appropriate for the PDP-10 world:
|
||||
|
||||
String Mode Start Description
|
||||
"r", "rb" R 0 Open existing file for reading. Error if not found.
|
||||
"w", "wb" W 0 Create a new file for writing.
|
||||
"a", "ab" W EOF Append to existing file (create new if necessary).
|
||||
"r+","r+b" R/W 0 Open existing file for updating. Error if not found.
|
||||
"w+","w+b" R/W 0 Create a new file for updating.
|
||||
"a+","a+b" R/W EOF Append to existing file (create new if necessary).
|
||||
|
||||
Note that on TOPS-20 and TENEX, files have version numbers, and
|
||||
writing a file never truncates an existing one; "w" and "w+" always create
|
||||
new versions.
|
||||
A stream can be either "text" or "binary", as per the ANSI
|
||||
draft description; a "b" in the string specifies binary. The
|
||||
characteristics of the two types of streams are:
|
||||
Bytesize(old) Bytesize(new) LF-conversion
|
||||
TEXT <file's> or 7 7 yes if size 7
|
||||
BINARY <file's> or 9 9 no, never
|
||||
|
||||
When an OLD, existing file is opened (for reading, appending,
|
||||
or updating), normally the bytesize of the file is used as the
|
||||
bytesize of the stream. If the file bytesize is 7, 8, or 9 then that
|
||||
size is used. If the file bytesize is 0 or 36 then the default (7 or
|
||||
9) is used instead. If the file bytesize is anything other than
|
||||
0, 7, 8, 9, or 36 then the behavior is undefined.
|
||||
When a NEW file is created, its bytesize will be that of the
|
||||
stream, which is normally 7 for text, 9 for binary. Note that older
|
||||
versions of a file may have a different bytesize -- the notion of
|
||||
checking these to set the bytesize was considered, but rejected in the
|
||||
interest of simplicity.
|
||||
Whether LF conversion is performed on the stream is a little
|
||||
simpler. A text stream is only converted if the stream bytesize is 7;
|
||||
otherwise conversion does NOT happen. A binary stream is never
|
||||
converted, regardless of the bytesize.
|
||||
|
||||
The user can override either the bytesize or the conversion
|
||||
by adding explicit specification characters, which should come after
|
||||
any regular specification characters:
|
||||
"C" Force LF-conversion.
|
||||
"C-" Force NO LF-conversion.
|
||||
"7" Force 7-bit bytesize.
|
||||
"8" Force 8-bit bytesize.
|
||||
"9" Force 9-bit bytesize.
|
||||
"T" Open for thawed access (TOPS-10/TENEX only)
|
||||
|
||||
These are KCC-specific however, and are not portable to other
|
||||
systems. Note that the actual LF conversion is done by the USYS (Unix
|
||||
simulation) level calls (read() and write()) rather than STDIO.
|
||||
|
||||
[17.5] fseek(), ftell(), rewind():
|
||||
For binary streams (no LF conversion), the I/O pointer value
|
||||
returned by ftell() and used in fseek() is the same as the USYS (and
|
||||
T20) pointer value; arithmetic can be done on this pointer to derive
|
||||
new pointers as arguments to fseek(). However, for text streams when
|
||||
LF conversion is being done, the I/O pointer value is a composite which
|
||||
cannot be manipulated; the argument to fseek() can only be 0 or a
|
||||
value previously returned by ftell() for that stream. This corresponds
|
||||
to the restrictions described in H&S.
|
||||
fseek() does not yet work for "+" text streams (i.e.
|
||||
LF-converted streams open for both reading and writing).
|
||||
|
||||
[17.6] (V1 11.5.34) ungetc():
|
||||
The number of characters that can be pushed back with ungetc is
|
||||
a site-dependent option available at library compile-time. _SIO_NPBC
|
||||
in STDIO.H defaults to 1.
|
||||
|
||||
[17.8] (V1 11.5.16, 11.5.28, 11.5.30) fscanf(), scanf(), sscanf():
|
||||
Common sense was used in implementing the various conversion
|
||||
routines when there was doubt about CARM's description:
|
||||
For numeric conversions ('d', 'u', 'o', 'x', 'f'), there must
|
||||
be at least one digit present for the parse to succeed, despite CARM's
|
||||
claim that "some number" of digits, "possibly none" are allowed. For
|
||||
string scanners ('s' and '['), at least one character must be read.
|
||||
|
||||
[17.11] (V1 11.5.11, 11.5.23, 11.5.29) printf(), fprintf(), sprintf():
|
||||
An additional facility has been provided for the user to
|
||||
assign his own conversion specification character to arbitrary
|
||||
functions. This function is "prf_bind()" in module PRINTF, which should
|
||||
be seen for details. Unfortunately this is not portable.
|
||||
|
||||
[17.13] (V1 11.5.14,11.5.19) fread(), fwrite():
|
||||
These are implemented assuming that the input stream is open
|
||||
in 9-bit binary mode, such that all 36 bits of an int can be read with
|
||||
four successive bytes. No byte-size or mode checking is done, so it
|
||||
is the user's responsibility to make sure the stream is open
|
||||
correctly.
|
||||
|
||||
[17.16] tmpfile(), tmpnam(), mktemp():
|
||||
On TOPS-20/TENEX these are implemented using a time value from
|
||||
the system rather than getpid() due to the difficulty of ensuring that
|
||||
getpid() is unique. This may change.
|
||||
|
||||
Additional STDIO routines from 4.2BSD:
|
||||
See a BSD UPM section 3S for details on those routines. Some
|
||||
of them existed in V7 as well, such as fdopen(), fileno(), getw(), putw(),
|
||||
and setbuf().
|
||||
|
||||
Additional STDIO routines (KCC specific, not portable):
|
||||
|
||||
sopen(): opens a string as a source or destination for I/O.
|
||||
The first arg is a string pointer, second is a standard fopen type
|
||||
specification. The implementation of this is not yet complete: only
|
||||
"r" and "w" are implemented. "a" (append) mode does NOT do the
|
||||
obvious thing; place has been kept for "w+" to automatically expand
|
||||
the given string if the end is reached (assuming it was allocated by
|
||||
malloc). If a NULL string pointer is given, a string buffer is
|
||||
allocated starting at max_size characters. The file pointer cannot be
|
||||
repositioned (e.g. a string can be scanned only once). These things
|
||||
may be finished some day.
|
||||
|
||||
Section 18: Storage Allocation (V1: Sec 11.4) Src: lib/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
char *malloc(size); MALLOC *
|
||||
char *calloc(cnt,siz); MALLOC * (calls malloc)
|
||||
char *mlalloc(lsize); MALLOC * CARM only. (calls malloc)
|
||||
char *clalloc(lcnt,lsize); MALLOC * CARM only. (calls malloc)
|
||||
void free(ptr); MALLOC *
|
||||
void cfree(ptr); MALLOC * Not in ANSI. (calls free)
|
||||
char *realloc(ptr,size); MALLOC *
|
||||
char *relalloc(ptr,size); MALLOC * CARM only. (calls realloc)
|
||||
|
||||
--------------------
|
||||
Additional non-CARM functions:
|
||||
These are temporary only and their use in new code is not
|
||||
advisable; they will probably go away soon.
|
||||
|
||||
int _palloc(n); allocate n pages of memory
|
||||
void _pfree(page); free allocated pages
|
||||
|
||||
Tests: LIB/TEST/TMALL1.C, TMALL2.C
|
||||
|
||||
Notes:
|
||||
All CARM facilities supported. <stdlib.h> can be included.
|
||||
Since "long" is the same size as "int" for KCC, the long and int forms
|
||||
of calls are functionally identical. For portability the "long" forms
|
||||
should not be used.
|
||||
|
||||
Note that in ANSI these facilities can be declared with
|
||||
<stdlib.h>, but in non-ANSI implementations there is no associated
|
||||
header file. You should either include <stdlib.h>, or you should be
|
||||
VERY careful about pre-declaring these functions properly, and be SURE
|
||||
that routines which expect a char pointer argument are given one.
|
||||
A common mistake is failing to declare malloc(), so that the
|
||||
compiler is unaware of the proper conversions that must be applied to
|
||||
the return value (which is a PDP-10 byte pointer). This sort of type
|
||||
mismatch error can go undetected on some machines but will cause you
|
||||
all kinds of mysterious grief on the PDP-10.
|
||||
Using brk() and sbrk() is not prohibited, but doing so is
|
||||
guaranteed to confuse the storage allocator and cause problems if you
|
||||
also use malloc() and friends.
|
||||
The KCC functions conform to the ANSI/CARM descriptions of how
|
||||
they should behave, particularly when given strange arguments like
|
||||
NULL pointers. This is different from the behavior on BSD, where a
|
||||
zero size will still return something from malloc and realloc (rather
|
||||
than ignoring and freeing).
|
||||
|
||||
[18.1] (V1 11.4.1,11.4.3,11.4.5,11.4.6) calloc(),clalloc(),malloc(),mlalloc():
|
||||
clalloc() == calloc() on the PDP-10. These will return NULL
|
||||
if either argument is zero (as per ANSI).
|
||||
mlalloc() == malloc() on the PDP-10. These also return NULL
|
||||
if given a zero argument (as per ANSI).
|
||||
|
||||
[18.2] (V1 11.4.2, 11.4.4) free(), cfree():
|
||||
cfree() == free() on the PDP-10. CARM claims that for
|
||||
maximum portability it is best to use cfree() only to deallocate
|
||||
memory allocated by calloc(), and free() only to deallocate memory
|
||||
allocated by malloc(). However, the ANSI draft has flushed cfree()
|
||||
altogether.
|
||||
free() does nothing if given a NULL argument (as per ANSI).
|
||||
If given a bad pointer, free() calls abort() after sending the following
|
||||
message to stderr:
|
||||
"free(): tried to free invalid block"
|
||||
|
||||
[18.3] (V1 11.4.7, 11.4.8) realloc(), relalloc():
|
||||
relalloc() == realloc() on the PDP-10. These behave as per
|
||||
ANSI for unusual arguments: if the pointer is NULL, it acts like
|
||||
malloc(); if the size is zero, it acts like free() and returns NULL.
|
||||
If given a bad pointer, realloc() calls abort() after sending the
|
||||
following message to stderr:
|
||||
"realloc(): tried to reallocate invalid block".
|
||||
|
||||
Section 19: Mathematical Functions (V1: Sec 11.3) Src: lib/math/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
int abs(x); ABS * PRIMITIVE: C code
|
||||
double fabs(x); FABS * PRIMITIVE: C code
|
||||
long labs(x); LABS * PRIMITIVE: C code
|
||||
div_t div(n,d); DIV E * PRIMITIVE: C or PDP10 code
|
||||
ldiv_t ldiv(n,d); DIV E * PRIMITIVE: C or PDP10 code
|
||||
double ceil(x); CEIL * based on modf()
|
||||
double floor(x); FLOOR * based on modf()
|
||||
double fmod(x,y); FMOD * based on modf()
|
||||
double exp(x); EXP *10 PRIMITIVE: uses _sign,fabs,modf,ldexp
|
||||
double log(x); LOG *10 based on _xexp, _xmant, _poly
|
||||
double log10(x); LOG10 * based on log()
|
||||
double frexp(x,nptr); FREXP *10 PRIMITIVE: MACH DEP C code!
|
||||
double ldexp(x,n); LDEXP *10 PRIMITIVE: MACH DEP C code!
|
||||
double modf(x,nptr); MODF E *10 PRIMITIVE: MACH DEP asm code!
|
||||
double pow(x,y); POW * based on exp(), log(), modf()
|
||||
double sqrt(x); SQRT * based on _xexp(), _xmant(), ldexp()
|
||||
int rand(); RAND E *10 PRIMITIVE: mach dep C code
|
||||
srand(seed); RAND E *10 PRIMITIVE: C code
|
||||
double cos(x); COS *10 PRIMITIVE: uses fmod,sin,sqrt,_poly
|
||||
double sin(x); SIN *10 PRIMITIVE: uses fmod,cos,sqrt,_poly
|
||||
double tan(x); TAN * based on sin(), cos()
|
||||
double acos(x); ACOS * based on atan()
|
||||
double asin(x); ASIN * based on atan()
|
||||
double atan(x); ATAN *10 PRIMITIVE: uses _sign, _poly
|
||||
double atan2(y,x); ATAN2 * based on atan()
|
||||
double cosh(x); COSH * based on exp()
|
||||
double sinh(x); SINH * based on exp()
|
||||
double tanh(x); TANH * based on exp()
|
||||
|
||||
--------------------
|
||||
Additional support routines, NOT IN CARM:
|
||||
These exist only to support the above routines and should not
|
||||
be used by user code.
|
||||
|
||||
double _sign(x, y); SIGN * PRIMITIVE: C code
|
||||
double _poly(x, y, z); POLY * PRIMITIVE: C code
|
||||
int _xexp(x); XEXP *10 PRIMITIVE: MACH DEP C code!
|
||||
double _xmant(x); XMANT *10 PRIMITIVE: MACH DEP C code!
|
||||
|
||||
|
||||
Tests: LIB/TEST/TMATH.C
|
||||
(Why don't we have good precision for atan()?? E-9 only)
|
||||
|
||||
Notes:
|
||||
All CARM facilities are supported. <math.h> must be included.
|
||||
These are mostly derived from the Portable Math Library written by
|
||||
Fred Fish.
|
||||
|
||||
[19.8] (V1 11.3.25) tan():
|
||||
According to CARM, "If the argument is so close to an odd
|
||||
multiple of pi/2 that the correct result value is too large to be
|
||||
represented, then the largest representable positive floating-point
|
||||
number is returned and the error code ERANGE is stored into the
|
||||
external variable errno". The actual error check done is to see if
|
||||
for tan(x), cos(x) == 0. If so, the error behavior above is done.
|
||||
|
||||
[19.9] (V1 11.3.5) atan2():
|
||||
For atan2(0, 0), the value 0 is returned and errno set to EDOM.
|
||||
|
||||
[19.10] (V1 11.3.22) sinh():
|
||||
sinh() of a negative argument that is too large returns the
|
||||
largest representable negative float-point number.
|
||||
|
||||
Other notes:
|
||||
ANSI and CARM have the same functions. There are a few
|
||||
differences about domain/range error specifications which are minor.
|
||||
The BIG incompatibility is:
|
||||
ANSI modf() is incompatible with CARM and BSD, because
|
||||
the 2nd arg is (double *) instead of (int *)!!!
|
||||
|
||||
The functions abs, labs, rand, and srand are declared in <stdlib.h> by
|
||||
ANSI, in <math.h> by CARM.
|
||||
|
||||
BSD appears to have all CARM functions except labs() and fmod().
|
||||
BSD has these functions which are not in ANSI or CARM:
|
||||
(all return double unless otherwise indicated)
|
||||
Documented in UPM: gamma, hypot, cabs, j0, h1, jn, y0, y1, yn
|
||||
Undocumented: asinh, acosh, atanh, erf, erfc, expm1, log1p
|
||||
rint, lgamma, copysign, drem, logb, scalb, cbrt
|
||||
finite (returns int), infnan (VAX only)
|
||||
|
||||
Section 20: Time and Date Functions Src: lib/, lib/usys/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
clock_t clock(); CLOCK E *10
|
||||
clock_t <time.h> *
|
||||
CLK_TCK <time.h> *
|
||||
struct tms <sys/times.h> *
|
||||
void times(tmsbuf); USYS/TIMES * (see USYS.DOC)
|
||||
time_t time(tptr); USYS/TIME E *10 (see USYS.DOC)
|
||||
time_t <time.h> *
|
||||
char *asctime(ts); CTIME E *10
|
||||
char *ctime(timptr); CTIME E *10
|
||||
struct tm *gmtime(t); CTIME E *10
|
||||
struct tm *localtime(t); CTIME E *10
|
||||
time_t mktime(tmptr); CTIME E *10
|
||||
double difftime(t1,t0); CTIME E *10
|
||||
|
||||
--------------------
|
||||
Additional non-CARM functions:
|
||||
|
||||
char *timezone(mwest, dstt); CTIME E *10 For BSD/V7 compatibility (!S5)
|
||||
|
||||
typedef ... tadl_t; <sys/time.h> E *10 Type for local TAD value
|
||||
tadl_t tadl_get(); USYS/TIME E *10 Get current local TAD value
|
||||
tadl_t tadl_to_utime(time); USYS/TIME E *10 Convert time_t to tadl_t
|
||||
time_t tadl_from_utime(tadl); USYS/TIME E *10 Convert tadl_t to time_t
|
||||
|
||||
Internal globals, not for user consumption:
|
||||
|
||||
struct tm *_lbrktime(); CTIME E ITS,T10,WAITS For use by USYS/TIME
|
||||
int _tmisdst(); CTIME E ITS,T10,WAITS For use by USYS/TIME
|
||||
|
||||
The latest ANSI C draft also includes this function (not implemented yet):
|
||||
|
||||
size_t strftime(char *s, size_t maxsize, const char *format); ??
|
||||
|
||||
Tests: LIB/TEST/TTIME.C
|
||||
|
||||
Notes:
|
||||
All CARM facilities are supported.
|
||||
For additional time functions, see the TMX(3X) section.
|
||||
|
||||
[20.1] clock(), times():
|
||||
CLK_TCK is uniformly 1000 (i.e. runtime is in milliseconds). The
|
||||
BSD times() call is supported, although only crudely; it does not return
|
||||
its children's runtime. It could if this was needed.
|
||||
|
||||
[20.2] time_t, time():
|
||||
The type of time_t is "int". The value is the same as that
|
||||
for a standard UN*X implementation, i.e. the number of seconds since
|
||||
1/1/1970 GMT. This is NOT a TOPS-20 or TENEX GTAD format time and date.
|
||||
If you wish to manipulate time-and-date (TAD) values of the local operating
|
||||
system, use the (non-standard) tadl_t facilities.
|
||||
|
||||
Section 21: Control Functions Src: lib/, lib/usys/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
macro assert(); <assert.h> *
|
||||
int system(cmd); SYSTEM E T20,10X (partial implem)
|
||||
int exec*(); USYS/FORKEX E T20,10X (partial implem)
|
||||
void exit(status); USYS/URT E T20,10X
|
||||
void _exit(status); USYS/URT E T20,10X
|
||||
void abort(); ABORT *10
|
||||
typedef ... jmp_buf[]; <setjmp.h> E *10 KCC specific
|
||||
int setjmp(env); SETJMP E *10 KCC specific
|
||||
void longjmp(env,status); SETJMP E *10 KCC specific
|
||||
typedef ... onexit_t; <stdlib.h> *
|
||||
onexit_t onexit(func); ONEXIT *
|
||||
constant SIG_IGN; <signal.h> *
|
||||
constant SIG_DFL; <signal.h> *
|
||||
constant SIG_ERR; <signal.h> *
|
||||
constant SIGxxx; <signal.h> *
|
||||
void (*signal(sig,func)); USYS/SIGNAL * See USYS.DOC
|
||||
int raise(sig); USYS/SIGVEC E T20,10X See USYS.DOC
|
||||
int kill(pid,sig); USYS/SIGVEC E T20,10X See USYS.DOC
|
||||
int (*ssignal(softsig,func))(); SSIGNA *
|
||||
int gsignal(softsig); SSIGNA *
|
||||
void psignal(sig,prefix); PSIGNA *
|
||||
void sleep(secs); USYS/SLEEP E *10 See USYS.DOC
|
||||
unsigned alarm(secs); USYS/ALARM E T20 See USYS.DOC
|
||||
|
||||
--------------------
|
||||
Additional functions:
|
||||
|
||||
int _setjmp(env); SETJMP E *10 For BSD compatibility
|
||||
int _longjmp(env,val); SETJMP E *10 For BSD compatibility
|
||||
void longjmperror(); SETJMP E *10 For BSD compatibility
|
||||
int forkexec(); USYS/FORKEX E T20,10X Combines fork & exec!
|
||||
|
||||
The latest ANSI C draft has replaced onexit() with:
|
||||
|
||||
int atexit(void(*func)(void))
|
||||
|
||||
Notes:
|
||||
All CARM facilities exist, although some may not be as
|
||||
completely supported as for a real UN*X system.
|
||||
|
||||
[21.2] exec(), system():
|
||||
The various forms of exec() all exist, but none of them do
|
||||
anything with the "envp" environment pointer. For the very common
|
||||
situation where a fork() is followed by an exec(), the forkexec() call
|
||||
should be used instead; it is MUCH faster.
|
||||
system() is not a full implementation. On TOPS-20 the command
|
||||
string is parsed assuming that the first word is a system program
|
||||
name, which is then invoked (using forkexec()) with the full
|
||||
string as an RSCAN% argument. Unfortunately there is no convenient way
|
||||
to feed input directly into an inferior EXEC. This call could be changed
|
||||
to use a PTY, but this would be much slower.
|
||||
|
||||
[21.3] abort(), exit():
|
||||
abort() does no cleanup actions whatsoever. It simply
|
||||
attempts to execute a zero instruction, which generates an illegal
|
||||
instruction fault on the PDP-10. This can be ignored by the signal
|
||||
handler, but if so then the program will loop indefinitely; abort()
|
||||
NEVER returns to its caller.
|
||||
exit() cleans up by calling all functions registered with onexit().
|
||||
The STDIO buffers are the last thing cleaned up.
|
||||
|
||||
[21.4] setjmp(), longjmp():
|
||||
In addition to the above, KCC also implements the BSD
|
||||
facilities of _setjmp(), _longjmp(), and longjmperror(). A checksum
|
||||
is stored in jmp_buf, and longjmp() checks this as well as
|
||||
other things; if anything looks bad, it calls longjmperror().
|
||||
longjmperror() can be defined by the user (the default routine
|
||||
simply prints "longjmp botch"). If it returns, abort() is called.
|
||||
|
||||
[21.5] onexit():
|
||||
Up to 32 functions can be registered, as per CARM.
|
||||
|
||||
[21.6] signal(), raise(), kill(), gsignal(), ssignal(), psignal():
|
||||
The implementation of signals is more complete than you might
|
||||
expect.
|
||||
The software signal functions gsignal() and ssignal() operate as
|
||||
described in CARM, as does the signal description function psignal().
|
||||
Note that psignal() outputs to the STDIO stream "stderr" rather than the
|
||||
UN*X file descriptor 2.
|
||||
raise(sig) is implemented simply as kill(getpid(),sig).
|
||||
The signal() and kill() functions are "UN*X system calls" and
|
||||
as such are treated specially. What KCC actually implements corresponds
|
||||
to the 4.3BSD signal handling mechanism, using the sigvec() call and
|
||||
a signal block mask. The main difference from standard UN*X is that
|
||||
when a signal is caught, its handler is NOT reset to SIG_DFL; also,
|
||||
most system calls are resumed rather than forced to fail with EINTR.
|
||||
For a fuller description the file SIGNAL.DOC should be consulted.
|
||||
|
||||
[21.7] sleep(), alarm():
|
||||
alarm() is implemented as described in CARM. On TOPS-20 this uses
|
||||
the TIMER% jsys. A signal handler for SIGALRM must be defined before the
|
||||
first call to alarm(), otherwise nothing will happen.
|
||||
The TOPS-20 implementation of sleep() uses a timer separate from
|
||||
that of alarm(). If any signal is handled, sleep() will return immediately
|
||||
with errno set to EINTR; it does not return any value.
|
||||
|
||||
Section 22: Miscellaneous Functions Src: lib/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
int main(argc,argv); * * User program!
|
||||
char *ctermid(s); CTERMI E T20
|
||||
char *cuserid(s); CTERMI E T20
|
||||
char *getcwd(buf,size); GETCWD E T20
|
||||
char *getwd(path); GETCWD E T20
|
||||
char *getenv(name); GETENV E T20 Note 10X does not have LNMST%.
|
||||
char *getlogin(); GETLOG E T20
|
||||
int getopt(argc,argv,optstr); GETOPT * Note other externals defined!
|
||||
int putenv(namval); GETENV E T20
|
||||
char *bsearch(ky,bs,ct,sz,cmp); BSEARC *
|
||||
void qsort(base,cnt,siz,cmp); QSORT * GNU version
|
||||
|
||||
--------------------
|
||||
The latest ANSI C draft has added a new function and new header file:
|
||||
<locale.h>
|
||||
char *setlocale(int category, char *locale);
|
||||
|
||||
Notes:
|
||||
All CARM functions are supported insofar as possible.
|
||||
|
||||
[22.1] main():
|
||||
The runtime startup provides main() with argc and argv, as
|
||||
parsed from the command line (on TOPS-20 this is the RSCAN% buffer).
|
||||
However, it does NOT provide "env" or "environ".
|
||||
|
||||
[22.2] ctermid(), cuserid():
|
||||
These are System V functions and are not present in BSD or ANSI.
|
||||
KCC implements them as per the CARM description.
|
||||
|
||||
[22.3] getcwd(), getcd():
|
||||
Implemented as per description.
|
||||
|
||||
[22.4] getenv(), getlogin(), getopt(), putenv():
|
||||
CARM goofed by only describing getenv().
|
||||
KCC implements all of these, but the environment variables need further
|
||||
explanation.
|
||||
|
||||
[22.5] bsearch():
|
||||
This is a new function in ANSI.
|
||||
[22.6] qsort():
|
||||
KCC uses the GNU (Free Software Foundation) implementation of
|
||||
this function.
|
||||
|
||||
Section BSD(3N): UPM(3N) BSD network functions Src: lib/network/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
struct hostent; <netdb.h> Defs for following
|
||||
struct hostent *gethostent(); GETHST - not yet done
|
||||
struct hostent *gethostbyaddr(adr,l,t); GETHST E T20,10X
|
||||
struct hostent *gethostbyname(nam); GETHST E T20,10X
|
||||
void sethostent(flg); GETHST - not yet
|
||||
void endhostent(); GETHST - not yet
|
||||
|
||||
Section TRM(3X): TERMCAP functions Src: <trmcap.h>, lib/trmcap.c
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
int tgetent(bp,name); TRMCAP *
|
||||
int tgetnum(id); TRMCAP *
|
||||
int tgetflag(id); TRMCAP *
|
||||
char *tgetstr(id, area); TRMCAP *
|
||||
char *tgoto(cm, destcol, destline); TRMCAP *
|
||||
int tputs(cp, affcnt, outc); TRMCAP *
|
||||
|
||||
Tests: Compile lib/trmcap.c with -DTEST to generate a test program.
|
||||
|
||||
Notes:
|
||||
This should be a full TERMCAP emulation. The code is derived from
|
||||
that of Gnuemacs (of the Free Software Foundation).
|
||||
The functions are kept in a library separate from the normal C
|
||||
library; to use them, the program must #include <trmcap.h> and the
|
||||
"-ltrm" switch must be given on the KCC command line.
|
||||
The terminal database file on TOPS-20 is kept in C:TRMCAP.DAT.
|
||||
Programs using these functions must include declarations
|
||||
of the following variables, which TERMCAP expects to use:
|
||||
char PC;
|
||||
char *BC;
|
||||
char *UP;
|
||||
short ospeed;
|
||||
|
||||
Section TMX(3X): Time and Date Functions (Extended) Src: <timex.h>, lib/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
struct tmx <timex.h> * includes <time.h>
|
||||
struct tmz <timex.h> *
|
||||
int time_parse(str, tmx, endptr); TIMEPA *
|
||||
time_t time_make(tmx); TIMEMK *
|
||||
int time_lzone(tmz); TIMEZN E *
|
||||
int time_tzset(); TIMEZN E *
|
||||
|
||||
Notes:
|
||||
Documentation is in the file C:LIBTMX.DOC. These functions
|
||||
were written by Ken Harrenstien and are distributed in a quasi-public
|
||||
fashion, similar to GNU software. They are not supported by any
|
||||
specific C implementation but because the code is available and is
|
||||
portable to any reasonable system, it should be safe to write code
|
||||
using these functions.
|
||||
|
||||
These functions are kept in a library separate from the normal C
|
||||
library; to use them, the program must #include <timex.h> and the "-ltmx"
|
||||
switch must be given on the KCC command line.
|
||||
|
||||
|
||||
Section KCC-1: KCC-specific general-purpose functions Src: lib/
|
||||
|
||||
Name Module Port Comments
|
||||
|
||||
<lots> <jsys.h> T20,10X Defines JSYS nums and arg vals
|
||||
jsys JSYS E T20,10X Support for T20/10X syscalls
|
||||
|
||||
regex* <regex.h> ? GNU version.
|
||||
regex* REGEX * GNU version.
|
||||
Not used, problems with overly
|
||||
long variable names. Foo.
|
||||
|
||||
syscal <sysits.h> ITS Defines ITS system-call macro.
|
||||
_scall SYSCAL E ITS C support for ITS syscalls
|
||||
|
||||
int muuo(ins,d,e); MUUO T10,WAITS Execute MUUO
|
||||
int calli(n,ac,ret); MUUO T10,WAITS Execute CALLI
|
||||
|
||||
Notes on jsys():
|
||||
|
||||
The jsys() function has been provided for ease in performing
|
||||
simple TOPS-20/TENEX monitor calls without being forced to resort to asm().
|
||||
The calling convention is:
|
||||
|
||||
#include <jsys.h>
|
||||
int jsys(num, acs);
|
||||
int num, acs[5];
|
||||
|
||||
The jsys number is given in "num", and registers 1 through 4 are given
|
||||
and returned in the "acs" array. Offsets in acs correspond to machine
|
||||
registers; thus acs[1] goes into AC1 before the call and then takes
|
||||
the value of AC1 after the call. acs[0] is not used unless the call fails.
|
||||
The include file <jsys.h> defines all JSYS names, including
|
||||
certain flags which tell the jsys() routine what behavior to expect from
|
||||
that JSYS. This information allows jsys() to present completely regular
|
||||
behavior to the C user, regardless of which JSYS is invoked.
|
||||
|
||||
jsys() returns:
|
||||
== 0 if it failed. The JSYS error code is returned in acs[0].
|
||||
If something was wrong with the arguments to jsys() itself,
|
||||
so that no JSYS was done, the error code will be 0.
|
||||
< 0 if it was interrupted.
|
||||
This is only possible if the JSYS_OKINT flag was
|
||||
OR'd into "num" for the call. The return value will be
|
||||
-2 if the interrupt happened before the JSYS was invoked,
|
||||
and -1 if it actually interrupted the JSYS.
|
||||
> 0 if it succeeded. The return value will be one of 1, 2, or 3
|
||||
depending on whether the JSYS returned to .+1, .+2, or .+3.
|
||||
|
||||
Note that interruption is ONLY allowed if the JSYS_OKINT flag
|
||||
is set in the "num" argument. Thus, for example, the following call
|
||||
can be interrupted:
|
||||
jsys(WAIT|JSYS_OKINT, acs);
|
||||
but this call will NOT be interrupted:
|
||||
jsys(PMAP, acs);
|
||||
|
||||
If the user program does direct JSYS calls itself with asm()
|
||||
then the signal handling code permits these to be interrupted, and
|
||||
tries to restart the JSYS when the signal handler returns, but this is
|
||||
not guaranteed to work for all possible cases. The jsys() call by
|
||||
contrast is always guaranteed to behave in a predictable way.
|
||||
|
||||
Things are not yet completely normalized for TENEX, because
|
||||
the need to handle .ICILI (illegal instruction) interrupts and emulate ERJMP
|
||||
complicates matters.
|
||||
Reference in New Issue
Block a user