Reference R1063 October 26, 1992 * C89 MTS C Staff University of Michigan Information Technology Division Contents 1 Overview 9 2 Documentation 9 3 How to Run *C89 in MTS 9 3.1 Compiler Unit Assignments 10 3.2 Return Codes from the Compiler 11 3.3 Character Graphics 12 4 Pragmas and Par Field Options 12 Page 2 5 Implementation-Defined Behavior 25 5.1 Diagnostics 25 5.2 Environment 26 5.3 Identifiers 26 5.4 Characters 26 5.5 Integers 27 5.6 Floating Point 28 5.7 Arrays and Pointers 28 5.8 Registers 28 5.9 Structures, Unions, Enumerations, and Bit-fields 29 5.10 Qualifiers 30 5.11 Declarators 30 5.12 Statements 30 5.13 Preprocessing Directives 30 5.14 Library Functions 31 6 Local Extensions 31 6.1 Compiler Identification 31 6.2 FORTRAN Linkage 32 6.3 Saving the Return Code 32 6.4 Access to the Save Area 33 6.5 R-call Linkage 33 6.6 Pseudo-registers 33 6.7 Setting the Pseudo-register Base 34 October 26, 1992 Page 3 7 Writing Portable Code 34 8 Porting Code From Elsewhere to *C89 35 8.1 UNIX Code 35 8.2 Identifier Case and Length 36 8.3 Initialization of Variables 37 8.4 Diagnosing Portability Errors 37 8.4.1 Illegal Character: xx (hex) 37 8.4.2 Missing Include File "xxx.h" 38 8.4.3 External Name Conflicts 38 8.5 File and Device Name Differences 39 8.6 Character Codes 39 9 The Execution Environment 39 9.1 Stack Allocation 40 9.2 Passing Parameters to the Main Program 40 9.3 Details of Parameter Passing 42 10 Calling Non-C Routines 43 10.1 Calling FORTRAN Routines 43 10.1.1 Type Equivalencies for FORTRAN 44 10.1.2 Return Codes 45 10.1.3 Mixing FORTRAN and RCALL 46 Reference R1063 Page 4 10.2 Conflicts between *C89LIB and MTS Library Routines ... 46 10.3 Getting C rather than MTS Functions 46 10.4 Getting MTS rather than C Functions 46 10.5 Calling PLUS Routines 47 10.6 Calling Assembly Language Routines 47 11 Calling C From Foreign Environments 49 11.1 Using FORTRAN Linkage 50 11.2 Using MTS Coding Convention Linkage 51 11.2.1 Initialization of the C Environment 51 11.2.2 Closing the C Environment 52 11.2.3 Calling *C89 from Plus 52 11.2.4 Calling C from Assembly Language 53 12 Putting Debugging Tools Into the Source 54 13 Debugging With SDS 55 13.1 Invoking SDS 55 13.2 Storage Layout 56 13.3 Setting Breakpoints 56 13.4 Continuing Execution after a Break 57 13.5 Removing Breakpoints 57 13.6 Displaying Variables 58 October 26, 1992 Page 5 13.6.1 Displaying External Variables 58 13.6.2 Displaying Static Variables 58 13.6.3 Displaying Local (auto) Variables 59 13.6.4 Displaying Parameters 60 13.6.5 Displaying Pseudo-registers 61 13.7 Other Useful SDS Commands 61 13.8 Correspondence between *C89 and SDS Types 62 14 The Library and Header Files 63 14.1 The *C89 Run-Time Library 64 14.2 Header Files 64 14.2.1 Standard Header Files 65 14.2.2 UNIX Header Files 65 14.2.3 MTS Header File 65 14.2.4 Header File Search Order 66 15 The MTS *C89 Library, Headers, and Macros 66 15.1 assert. h - Debugging Aid 67 15.2 ctype.h - Character Handling 67 15.2.1 isascii 69 15.2.2 toascii 69 15.3 math.h - Mathematics 70 15.3.1 Treatment of Error Conditions 70 Reference R1063 Page 6 15.4 signal. h - Signal Handling 71 15.5 stdio.h - Input/Output 74 15.5.1 Header Definitions 74 15.5.2 Input/Output Alternatives 74 15.5.3 MTS File Organization 75 15.5.4 File Types and Input/Output Modes 76 15.5.5 Control Characters in Output Streams 78 15.5.6 Carriage Control Characters 79 15.5.7 MTS File Names 80 15.5.8 Initial Stream Assignments 81 15.5.9 Random Access 83 15.5.10 Terminal Input/Output 84 15.5.11 Using the MTS I/O Routines 84 15.5.12 Implementation Specifics for the I/O Routines .... 84 15.6 stdlib.h - General Utilities 86 15.6.1 Implementation Specifics for the Utilities 86 15.7 string. h - String Handling 87 15.7.1 memcmp 87 15.7.2 strerror 87 15.7.3 stricmp 87 15.7.4 strnicmp 88 October 26, 1992 Page 7 15.7.5 strchr 88 15.7.6 strrchr 89 15.7.7 strlwr 89 15.7.8 strupr 90 15.7.9 reverse 90 15.8 time.h - Date and Time 91 15.9 mts.h - MTS Specific Routines 91 15.9.1 atoe 92 15.9.2 etoa 92 15.9.3 query 93 16 BSD4.3 UNIX Routines 94 16.1 Kernel Routines 94 16.1.1 File Access - Querying and Modifying 94 16.1.2 Miscellaneous I/O Routines 95 16.1.3 Sockets in *C89LIB 96 16.1.4 Library Utility Routines 97 16.1.5 Signals in *C89LIB 98 16.1.6 Other Unimplemented Kernel Routines 98 16.2 Non-Kernel Routines 99 16.2.1 I/O Routines 99 16.2.2 Signal 99 16.2.3 Character Macros 100 16.2.4 Other Implemented Routines 100 16.2.5 Unimplemented Routines 101 Reference R1063 Page 8 17 Incompatibilities With *C87 102 17.1 Incompatibilities with *C87LIB 102 17.2 Incompatibilities with *C87 Compiler 103 October 26, 1992 Page 9 1 Overview *C89 is a C compiler derived from the C/370 compiler developed by AT&T Information Systems, although almost all of the original AT&T code has been replaced. *C89 now has numerous improvements and is in conformance with the American National Standard for Information Systems - Program- ming Language C (ANSI X3. 159-1989), hereafter referred to as the ANSI C Standard. The *C89 compiler and library attempt to satisfy three goals: 1. to provide a good implementation of the standard language and library, 2. to support many of the UNIX (UNIX is a registered trademark of AT&T Information Systems) library routines, and 3. to provide support for Michigan Terminal System (MTS) routines. 2 Documentation This document does not provide information on the C language or C library except where features are implementation-defined or are local extensions. A copy of a recent ANSI C Standard can be obtained from Dollar Bill Copy- ing on Church Street near South University (Ann Arbor, Michigan, USA). For information on the UNIX routines that are not part of the ANSI Stan- dard, refer to UNIX Programmer's Reference Manual (PRM) - 4-3 Berkeley Software Distribution, from University of California, Berkeley. 3 How to Run *C89 in MTS The MTS command to run the *C89 compiler is $RUN *C89 units PAR=options Reference R1063 Page 10 3 HOW TO RUN *C89 IN MTS In some cases it may be desirable to add some options to control the com- pilation. In particular, it may beconvenient to organize a group of include files into an include library. An include library is a mechanism that allows a single file to be partitioned into one or more "members," each of which corresponds to a single header file. These differences provide a way to com- pile a C program without changing the #include lines in the source code. There may be cases in which a file on some other system is named in such a way that it can't exist on MTS. An include library consists of two parts, a directory and the contents of the include member. The directory starts at the first line in the file and is terminated by a line with eight zeroes. Each line of the directory has a member name and the line number (separated by one or more blanks) where the member is located in the file. Members are separated by $ENDFILEs. Whenever a #include is given, *C89 will search through all specified include libraries for the "file." Unlike normal MTS files, a member of an include library has a name that • can be up to 255 characters. • is case sensitive (e.g., XYZ.h is different from xyz.h). • may consist of any characters other than blanks. There may be cases in which a file on some other system is named in such a way that it can't exist on MTS. A program residing on such a system can be moved to MTS if the file names and the #include lines are changed to reflect MTS restrictions. An include library provides a way to compile such C programs without changing the #include lines in the source code. However, in many cases it is not necessary to use include libraries. Instead, individual include files can be placed in separate MTS files provided the restrictions on MTS file names are satisfied. 3.1 Compiler Unit Assignments The units described above may be assigned as follows: October 26, 1992 3.2 Return Codes from the Compiler Page 11 INPUT= source program. SERC0M= error messages. PRINT= source and object listing. 0BJECT= object module. 2= additional #include libraries containing header files. 99= if assigned, the PAR field will be read from this unit. Typically, only INPUT and OBJECT are assigned. *C89 does not allow INPUT to be assigned to the same file as any of SERCDM, PRINT or OBJECT nor does it allow 2 to be assigned to the same file as any of SERCOM, PRINT or OBJECT. Exception: if INPUT is the terminal, *C89 will allow INPUT to be the same as PRINT, SERCOM, or both. 3.2 Return Codes from the Compiler The MTS return codes generated by *C89 are as follows: The compilation was successful (except for possible warning messages). 4 A file required by *C89 couldn't be accessed. {Exception: #include files that can't be accessed cause rc=8.) 8 One or more compile-time errors were detected or an include file couldn't be accessed. 12 The compiler ran out of memory. 16 An internal failure occurred in *C89. Note: If two or more of these conditions apply, the condition with the highest number prevails. That is, if there are compilation errors and *C89 ran out of memory, the return code is 12. Reference R1063 Page 12 4 PRAGMAS AND PAR FIELD OPTIONS 3.3 Character Graphics If a terminal doesn't support the full range of characters needed to program in C, it is possible to use the alternate character representations described in the ANSI C Standard. Some terminals may display certain characters in a form that may not be familiar. The circumflex (") appears on some terminals as an up-arrow ('f*) and the tilde (~) appears on some terminals as a logical negation(-i). Also, the circumflex and backslash (\) will not print on the line printer and may print as other graphics in some fonts on the page printer. 4 Pragmas and Par Field Options There are numerous options built into the *C89 compiler. These options can be specified either in the PAR field of an MTS $RUN command or in a #pragma command in the source program. Since MTS doesn't allow command lines longer than 256 characters, *C89 will read the PAR field in- formation from unit 99 if it has been assigned. This optional method of specifying the PAR field is most useful for macros that generate commands. The PAR field and #pragma option names are case-insensitive and may be upper, lower, or mixed case. Most options can be negated by prefixing them with "~" or "NO". When these options are specified in the PAR field, their scope is the entire compilation unit. When specified in a pragma, the scope is indicated with each description. The ANSI C Standard gives no guidance on the names and syntax of prag- mas, so they are unique to this implementation. Note that the ANSI C Standard allows unrecognized pragmas to be ignored without an error, so many of the following pragmas may not impair portability, although some might conflict with a pragma on another compiler. Of the multitude of options, only a few are frequently used. These are: SYM to aid in debugging, October 26, 1992 Page 13 PROPER to have the compiler diagnose as many suspect or non- standard constructions as possible, and UNIX4.3, UNIX or UNIX+ to port programs from UNIX. The options and pragmas are: AMODE This option can be set to 24, 31, or ANY. This tells the loader what the addressing mode of a given control section is. For example, if a program can only operate in 24 bit mode, then this option must be set. For most programs this will not be necessary. The default is AMODE=ANY. Pragma Scope: The value at the end of a function determines how the code for the function is treated by the loader. ASCII (default NOASCII) This option causes all character strings and character constants to be converted to ASCII internally. It is the user's responsibility to be careful with this option. If a PAR=ASCII routine calls a routine that isn't ASCII, there may be serious problems. For the most part, the *C89 run-time system assumes EBCDIC. For example, getc, scanf, etc., all return EBCDIC charac- ters, and the printf and scanf formats must be expressed in EBCDIC. This may change at some point in the future. Until the library supports ASCII characters (e.g., for printf formats) , this option is of little utility. Pragma scope: Takes effect immediately. Reference R1063 Page 14 4 PRAGMAS AND PAR FIELD OPTIONS CHECKIOVER (default NOCHECKIOVER) This option causes the compiler to generate code to check that the results of all signed integer computations fit into 32 bits. Turning this on would be most useful when using the signal facility to capture interrupts for integer overflow. Pragma scope: The last value is used for the entire compilation unit. CHECKSTACK (default NOCHECKSTACK) This option causes the compiler to generate code to check that the stack doesn't overflow. If the size of the stack is exceeded from within a routine compiled with this option, an interrupt occurs. Note that *C89LIB is not compiled with this option. Pragma scope: The value at the end of a function is used to determine how to generate code for that function. DEFINC (default DEFINC) This option causes the compiler to search the default include library (*C89INCLUDE). NODEFINC would only be used to in- sure that all symbols are resolved by the user-specified include libraries. This is intended only for use with libraries other than *C89LIB. If NODEFINC is used, a definition for must appear in a user-specified include member or in an include library. Pragma scope: Takes effect immediately. DEFINE (x) This is processed as if a #def ine x 1 had been issued before the source program had started, x may be any legal identifier, x is not translated to upper case before use. This option cannot be negated. Not allowed as a pragma; use #def ine. October 26, 1992 Page 15 DEFINE (x=e) This is processed as if a #def ine x e had been issued before the source program had started, x may be any legal identifier, e can be any sequence of tokens, x and e are not translated to upper case before use. This option cannot be negated. Not allowed as a pragma; use #def ine. DEPEND (default NODEPEND) When this option is in effect, a list containing the names of all the source files and all the include files used by the compiler in a given compilation is printed on the logical I/O unit PRINT. When the DEPEND option is turned on, the LIST option is turned off and the compiler does not parse the source nor does it produce an object module (regardless of the setting of the OBJECT option). The list produced may contain duplicate file names. This option is intended for production of makefile dependencies. Pragma scope: Takes effect immediately. FILL=c (default NOFILL) This option specifies a char-sized value that is used at run-time to initialize each stack frame. This option can be used in debug- ging when a problem with an uninitialized variable is suspected. The value of c must fit into a single character, but can be ex- pressed as any integer constant. For example, each of the follow- ing has the same effect. #pragma fill= , a ) #pragma fill=0x81 #pragma f ill=129 Reference R1063 Page 16 4 PRAGMAS AND PAR FIELD OPTIONS Pragma scope: The last value given this option within a function is used for that function. I=cccc (where cccc is an MTS userlD) This affects #include searches. This adds the userlD cccc to the list of userlDs to be searched when a quoted #include file is specified. For example, $run *C89 input=. . . par=i=W123 i=W456 Where the source file contains the following include: #include "ink.h" *C89 will first look for the file W123 : ink . h. If that doesn't exist, it will look for the file W456 : ink . h, and if it isn't there, it looks for the file ink.h on the current userlD. This option may be specified more than once and the userlDs are searched in the order specified. This option is useful when compiling a program developed on one userlD from another userlD. #include directives that use angle brackets are unaffected by this option. This option cannot be negated. Pragma scope: Takes effect immediately. LANG=x (default LANG=ANSI) The LANG option defaults to processing the ANSI C Standard language. To aid in porting programs from UNIX, a few ad- ditional syntax constructions are allowed that are non-standard but commonly accepted by traditional Kernighan and Ritchie compilers, when LANG=K&R is specified. For example, text ap- pended to #endif will be ignored if the LANG=K&R option is set. October 26, 1992 Page 11 LIST (default NOLIST) LIST=n (default LIST=0) The LIST option controls echoing of source lines to PRINT. The LIST identifier by itself is the same as LIST=1. NOLIST is the same as LIST=0. If LIST=1, everything except #include files is listed. If LIST=2, everything, including #include files, is listed. If the logical I/O unit PRINT is assigned and the DEPEND option is off, LIST is set to 1. Pragma scope: Takes effect immediately. LOADNAME ( cname , Iname) This option causes the external name cname in the source pro- gram to be mapped into the name Iname in the object module. This option can be used to allow C programs to access system names that don't conform to C syntax. Pragma scope: The same scope as cname. LONG (default LONG) This option suppresses truncation of external names. If NOLONG is specified, external names are truncated to eight characters. Pragma scope: The last value is used for the entire compilation unit. MC (default NOMC) Normally, external names are mapped to upper case; for exam- ple, fopen is changed into FOPEN. If MC is selected, then external names are left in the original case, i.e., mixed case. Note: The Reference R1063 Page 18 4 PRAGMAS AND PAR FIELD OPTIONS *C89 run-time system is compiled with NOMC, and hence, MC pre- vents the use of *C89LIB and makes use of *OBJUTIL, SDS and similar programs. Pragma scope: The last value is used for the entire compilation unit. MTSLINE (default NOMTSLINE) This option determines how #line commands are interpreted and how SYM records are generated. If MTSLINE is in effect, the numbers in these commands are assumed to be MTS line numbers multiplied by 1000. For example: #line 1500 is assumed to refer to line 1.500. If NOMTSLINE is specified, then numbers are assumed to be integral line numbers. For example: #line 45 is assumed to refer to line 45. NOMTSLINE is useful when compil- ing source code that originated on a non-MTS system. Pragma scope: Takes effect immediately. If no #line commands appear in the source file, SYM records are generated assuming MTS line numbers. Otherwise, the value of the MTSLINE op- tion at the time of the last #line command in the source file determines how SYM records are produced by the compiler. OBJECT (default OBJECT) Object code generation may be suppressed with N00BJECT. Pragma scope: The last value is used for the entire compilation unit. 0BJLIST (default N00BJLIST) October 26, 1992 Page 19 If OBJLIST is specified, an object listing is written to the I/O unit PRINT. Pragma scope: The last value is used for the entire compilation unit. 0PT=n (default 0PT=1) 0PT=O causes no analysis of the intermediate code to be made to determine code size or register usage, so code is generated using worst-case assumptions. Compilation is slightly faster than 0PT=1. NDDPT can be used as an alternative to 0PT=0. 0PT=1 causes two passes to be made over the intermediate code. A first quick pass makes an analysis of the code size and register usage. A second pass is then made to generate code that is usually more efficient. DPT=2 additionally will use peephole optimization techniques to clean up various inefficiencies in the generated object code (e.g., eliminate dead code, eliminate redundant loads) Also 0PT=2 causes variables to be assigned to registers under certain conditions (see section 5.8, "Registers," for more information) . Pragma scope: The value at the time of a declaration of a given variable determines if that variable will be considered for assign- ment to a register. For other properties of OPT, the value at the end of a function determines how that function will be compiled. PORT (default NOPORT) If PORT is specified, *C89 prints warnings that indicate which parts of a program might not be portable. This will not detect all violations; neither does the presence of a warning guaran- tee a non-portable program nor does the absence of a warning guarantee a portable program. The following cause a portability warning. Other features may also be added to cause portability warnings. Reference R1063 Page 20 4 PRAGMAS AND PAR FIELD OPTIONS • The __f ortran, __retcode, __prvbase, and __pseudoregister extensions. • The FILL, LOADNAME, PR0T0=O, RCALL and ZEROARG prag- mas. • Casts between pointers and integers. • Casts between pointers to different types. • Uses of identifiers beginning with an underscore in ways that conflict with the ANSI standard. Pragma scope: Takes effect immediately. PROPER The PROPER pragma stands for a collection of other pragmas that would all be used if one were trying to write a maximally portable and correct program. The pragmas set by PROPER are: #pragma port standard warn=4 proto=4 Pragma scope: Takes effect immediately. PR0T0=n (default PR0T0=2) The PROTO option controls whether prototypes are required and how they are used. It can have the following values: PROTO=0 All prototypes are ignored. PROTO=l Permits the last parameter to be omitted without generating an error or warning. This is to be used with the ZEROARG option for compatibility with certain UNIX implementations (e.g., that of Sun Microsystems) that allow final parameters to be omitted, and this also supplies an extra zero- valued parameter. PROTO=2 Prototypes are used if provided, but the compiler doesn't insist on having them. October 26, 1992 Page 21 PROTO=3 All function declarations, but not definitions, are required to have prototypes. PROTO=4 All function declarations and definitions are re- quired to have prototypes. Pragma scope: takes effect immediately. RCALL {fname , inregs , outreg) This option is used only to provide an interface to certain MTS functions. This option specifies that the function fname is to use R-call linkage. The inregs parameter specifies which registers are to be loaded with parameters, and the outreg parameter specifies which register, if any, contains the result. inregs is specified as a sequence of hexadecimal digits, one for each of the general registers to be loaded with a parameter. Each of the registers specified in inregs is restricted to the range 0-7. Similarly, outreg specifies either general register RO or Rl. For example, #pragma rcall(xyz,043, 1) would declare the function xyz to use R-call linkage, loading the first parameter into RO, the second into R4, and the third into R3. The result will be returned in Rl. The register specifications are optional. If inregs is omitted, parameters will be passed with an S-type linkage, but it is still possible to specify outreg as 1. If outreg is omitted, the value is returned in RO. For example, #pragma rcall(xxx,043) /* result in RO */ #pragma rcall(yyy, , 1) /* no param regs */ Pragma scope: The same scope as fname. Reference R1063 Page 22 4 PRAGMAS AND PAR FIELD OPTIONS RENT (default NORENT) The option RENT causes all static and extern variables, as well as string constants, to have the const attribute. This forces *C89 to check for possible re-entrancy violations. If you don't know what re-entrancy is, you don't need to use this option. Pragma scope: Takes effect immediately. RMODE (default RM0DE=ANY) This indicates to the compiler where the code for the csect can be loaded at time execution. This can be set to 24 or ANY. Pragma scope: The value at the end of a function determines how the code is treated by the loader. STANDARD, STANDARD+, UNIX, and UNIX+ (default STANDARD) These four options are especially useful in porting programs to or from UNIX systems. The two effects these options have are: (1) to define compile-time symbols that control which parts of the standard header files are processed, and (2) to set other pragma options. STANDARD defines only those identifiers which are in the standard header files and defined in the ANSI C Standard. No additional UNIX symbols are defined. This also sets LANG=ANSI and WARN=3. STD and ANSI are allowed as equivalent abbreviations. STANDARD+ gives all of the standard identifiers from the standard header files and additionally defines all identi- fiers that would normally be defined in the UNIX ver- sion of the header file. In the few cases that the standard and UNIX definitions conflict, the standard definitions take precedence. This also sets LANG=ANSI and WARN=3. STD+ and ANSI+ are allowed as equivalent abbreviations. October 26, 1992 Page 23 UNIX gives only those identifiers in the standard header files that are defined in UNIX. No additional ANSI C Standard identifiers are defined. This also sets LANG=K&R and WARN=1. UNIX+ defines those identifiers in the standard header files that are defined in UNIX and additionally defines all non- conflicting ANSI C Standard identifiers. This also sets LANG=K&R and WARN=1. Note that if UNIX or UNIX+ is used and you also want to have the compiler check for warnings, the WARN option must be used after the UNIX or UNIX+ option. For example, PAR=UNIX+ WARN=3 Pragma scope: Takes effect immediately. SUMMARY (default SUMMARY) This option provides a summary of the object code produced during the compilation of each function. The summary includes the number of bytes required for the generated code, constants, and stack. It also gives information about the number of unused general and floating point registers. Pragma scope: The last value is used for the entire compilation unit. SYM (default SYM) If SYM is on, SDS SYM records are generated in the object module. See section 13, "Debugging With SDS." Pragma scope: The last value is used for the entire compilation unit. TEST Synonym for SYM. Reference R1063 Page 24 4 PRAGMAS AND PAR FIELD OPTIONS UNDEF (x) This is processed as if a #undef x had been issued before the source program had started, x may be any legal identifier. As many DEFINE and UNDEFs can be issued as desired. If more than one is given, they are processed in order, x is not translated to upper case before use. This option cannot be negated. Not allowed as pragma; use #undef . UNIX See STANDARD UNIX4.3 This is short-hand for UNIX+, WARN=1 and LANG=K&R. Note that if it is desired to have the compiler check for warnings, the WARN option must be used after the UNIX4.3 option. For example, PAR=UNIX4.3 WARN=3 WARN=n (default WARN=3) The WARN option controls which warning messages are printed. The possible values range from (no warnings) to 4 (all possible warnings are printed). No warnings. NOWARN is a synonym for WARN=0. 1 Serious warnings. E.g., a loop doesn't appear to terminate. 2 Possible confusion warnings. E.g., the assignment operator (=) occurs where an equality operator (==) would usually occur. (Also includes WARN=l). October 26, 1992 Page 25 3 Default type warnings. E.g., int was omitted. (Also includes WARN=1 and WARN=2). 4 Stylistic warnings. E.g., a variable in an inner block hides another by the same name in an outer block. (Also includes WARN=1, WARN=2 and WARN=3). Pragma scope: Takes effect immediately. ZEROARG (default NOZEROARG) If ZEROARG is specified, an extra int zero argument is appended to every parameter list and PR0T0=1 is set. This is provided to mimic the behavior of the Sun Microsystems C compiler. Pragma scope: Takes effect immediately. 5 Implementation-Defined Behavior The ANSI C Standard specifies that every C compiler and library should describe its implementation of the following standard features. 5.1 Diagnostics • All diagnostics produced by *C89 have the form: , line : If begins with the "warning:", the error will not suppress object code generation. If it does not begin with "warning:" , it will suppress object code generation. Reference R1063 Page 26 5 IMPLEMENTATION-DEFINED BEHAVIOR 5.2 Environment • The semantics of the arguments passed from the MTS command envi- ronment to main are described in section 9, "Execution Environment." • The nature of interactive devices is described in MTS Volume 4-' Ter- minals and Networks in MTS, Reference R1004. 5.3 Identifiers • There may be up to 256 significant characters in identifier names. The ANSI C Standard requires only 31 significant characters. • By default, up to 128 characters are used in external names. The ANSI C Standard requires only 6 significant characters, though most implementations support many more. If the option PAR=N0L0NG is specified, only 8 characters will be used in external names. • By default, case is insignificant in external names. If the option PAR=MC is specified, case is significant. 5.4 Characters • The EBCDIC character set is used for both compilation and execution. Further information on exactly which characters are supported for the various devices can be found in MTS Volume 1: The Michigan Terminal System, Reference R1001. • No alternate shift states are provided for multibyte characters. • There are 8 bits in a character in the execution character set. • Normally, no mapping is performed between string constants in the source file and the execution environment. If the option ASCII is supplied, the characters in string constants are mapped from ASCII to EBCDIC. • All characters that might be present in a string constant can be rep- resented in the execution environment. October 26, 1992 5.5 Integers Page 21 • A character constant that is longer than one character is packed into an int right-justified and zero-filled. No more than four characters can be placed into an int. (This is also true for multibyte characters and wide-character constants.) • Multibyte characters will be converted to wide-character constants with the mbtowc routine under all legal locales. • A "plain" char is unsigned. 5.5 Integers • All integers are represented in two's-complement notation and have sizes and byte (8-bit) alignments as follows. The signed and unsigned attributes do not affect the size or alignment. char is 1 byte, aligned on a byte boundary. short is 2 bytes, aligned on a two-byte boundary. int is 4 bytes, aligned on a four-byte boundary. long int is also 4 bytes, aligned on a four-byte boundary. • Converting an integer to a signed integer of shorter length will result in a value with the same high order bit (or sign bit) and other bits removed from the left until the value fits. Converting an unsigned integer to a signed integer of the same length will result in the same bit pattern but now interpreted as a signed value. If this results in truncation, the new value will be negative. • Bit- wise operations on signed integers simply take place on their nor- mal two's-complement representation. • The sign of the remainder in an integer division is the same as the sign of the dividend. • The result of a right shift of a signed negative integer fills bit positions on the left with the sign bit. Reference R1063 Page 28 5 IMPLEMENTATION-DEFINED BEHAVIOR 5.6 Floating Point • The representation of floating-point numbers is described in detail in the IBM System/370 Principles of Operation. The sizes and align- ments are as follows: float is 4 bytes, aligned to a 4-byte boundary. double is 8 bytes, aligned to an 8-byte boundary except when passed as a parameter, when it is aligned to a 4-byte boundary, long double is 16 bytes, aligned to an 8-byte boundary except when passed as a parameter, when it is aligned to a 4-byte boundary. Currently, only the first 8 bytes are used in computations. • If an integer is too large to be converted to a float, it will be rounded to a float. • A floating-point number that is converted to a narrower floating-point value is rounded. 5.7 Arrays and Pointers • The maximum size of an array can be held in an unsigned int. • Casting may take place between pointers and integers without altering the bit pattern, but this may generate a warning. • The difference between two pointers may be held in an int. 5.8 Registers • Register objects are placed into registers only if PAR=0PT=2 is specified, the type of the object is integral or pointer, and there are enough free registers ("integral" means char, short, int, long or enum). GR2 through GR7 are used for expression evaluation. Any of the registers GR2 through GR7 not needed for expression evaluation can be used to October 26, 1992 5.9 Structures, Unions, Enumerations, and Bit-fields Page 29 hold variables. For example, if GR2 is needed to evaluate an expression and all other registers are free, then five registers are available for register variables. The number of available registers can vary anywhere from zero to six, depending on the complexity of the function. 5.9 Structures, Unions, Enumerations, and Bit-fields • Members of a union accessed by a member of a different type will access the original bit pattern. • The first byte of a struct or union is aligned to the largest alignment required by any of the members of that struct or union, except when passed as a parameter, when it is aligned to a four-byte boundary. For members of a union or struct, the alignment is as follows: char is aligned on a byte boundary. short is aligned on a two-byte boundary. int is aligned on a four-byte boundary. long int is aligned on a four-byte boundary. enum is aligned on a four-byte boundary. float is aligned to a four-byte boundary. double is aligned to an eight-byte boundary. long double is aligned to an eight-byte boundary. pointers are aligned to a four-byte boundary. arrays are aligned the same as the members of that array. struct is aligned the same as the largest alignment needed by any of the members. union is aligned the same as the largest alignment needed by any of the members. bit fields are never aligned except when the field would otherwise straddle four consecutive byte boundaries. In such cases the bit field is aligned to the next byte bound- ary to prevent this. Alignment may require the insertion of padding bytes. • "Plain" bit fields are treated as signed. Reference R1063 Page 30 5 IMPLEMENTATION-DEFINED BEHAVIOR • Bit fields are allocated from high-order to low-order bits within an int. • A bit field may straddle a byte boundary provided that this doesn't cause the field to straddle four consecutive byte boundaries, in which case it will be aligned to the next byte boundary. • enum types are implemented as int. Note that even though enums types are implemented as int, a warning message will result when enums are mixed with ints. 5.10 Qualifiers • Currently, the volatile qualifier does not affect code generation. This may be changed in future versions of the compiler. 5.11 Declarators • There may be no more than 13 declarators modifying a type. 5.12 Statements • There is effectively no limit on the number of case values allowed in a switch statement. 5.13 Preprocessing Directives • The EBCDIC character set is used in the preprocessor as well as during execution. Character constants consisting of a single character are never negative. • The method of locating includable source is described in section 14.2, "Header Files." • The processing of quoted #include files is described in section 14.2, "Header Files." October 26, 1992 5.14 Library Functions Page 31 • The recognized #pragmas are described in section 4, "Pragmas and Par Field Options." • If the time and date are not known (which should never happen) __TIME__ and __DATE__ will have the values "18:59:59" and "Dec 31 1969" respectively. 5.14 Library Functions • The null pointer (NULL) is represented as 4 bytes of all zeros. Other implementation-dependent aspects of the library are described in sec- tion 15, "The MTS *C89 Library, Headers, and Macros." 6 Local Extensions *C89 has a number of extensions, which primarily help to provide an in- terface to existing MTS routines. These extensions should not be used if a portable program is desired. 6.1 Compiler Identification Several macros are defined to make it possible for the code to identify the compiler, operating system, and hardware that are being used. These macros are: _C89 _MTS _IBM370 _SITExxx Reference R1063 Page 32 6 LOCAL EXTENSIONS (where "xxx" is a two- or three-letter site name. For example, at the Uni- versity of Michigan this is "UM" ; at Renssalaer Polytechnic Institute this is "RPI"; at the University of British Columbia this is "UBC") These macros can be used in a single source file that may be compiled either by *C89 or another, incompatible, compiler. For example: #ifdef _C89 *C89 stuff #else other compiler stuff #endif It is also possible to compile a file differently depending on where it is beinj; compiled. For example: #ifdef _SITEUM UM stuff #endif #ifdef _SITERPI RPI stuff #endif 6.2 FORTRAN Linkage If a function is declared __f ortran, linkage to it will be by means of a stan- dard IBM 370 S-type calling sequence. The details of the calling sequence are described in MTS Volume 3: System Subroutine Descriptions, Reference R1003, and in section 10.1, "Calling FORTRAN Routines." 6.3 Saving the Return Code It is possible to get the return code from a call. See section 10.1.2, "Return Codes." October 26, 1992 6.4 Access to the Save Area Page 33 6.4 Access to the Save Area Each function has a predefined array, called __SAVEAREA, in its stack frame. This is an array of 16 ints, which overlaps the coding conventions save area. Values may be fetched from this area, and at the programmer's risk, values may be modified. For example, issuing the statement __SAVEAREA[15] = 8; allows a C routine to set the return code that can be tested by the caller. 6.5 R-call Linkage The ability to call R-type routines is supported by means of the RCALL pragma. 6.6 Pseudo-registers The storage class __pseudoregister allows variables to be allocated in the pseudo-register vector. This is necessary only if re-entrant code is desired. Example: pseudoregister int globals [100] ; Such a variable can then be accessed just like any other variable. *C89 initializes the pseudo-register vector to all zeros before passing control to the main program, provided the main program is written in C. This cannot be guaranteed if the main program is written in PLUS. A pseudo-register must not have an initializer. *C89 doesn't produce re-entrant code by default. However, it is possible to modify programs to be re-entrant. See the RENT option in section 4, "Pragmas and Par Field Options." Reference R1063 Page 34 7 WRITING PORTABLE CODE 6.7 Setting the Pseudo-register Base It is possible to specify a new pseudo-register area base on a call, for example: sub(a, b, c, prvbase w) ; __prvbase sets the value of GR11 to a desired value before making the call. The expression following __prvbase must be of a pointer type. On return from the call, GR11 is restored to its previous value. This feature is provided primarily for MTS system programmers. 7 Writing Portable Code While it is quite possible to write C programs that can easily be moved (ported) to other machines, care must be taken to achieve portability. Some of the issues that must be considered are: • Use the PORT Option. Specify the PORT option so that some detectable portability violations will be flagged by the compiler. Although this will not catch all prob- lems, it will get some of them. • Do Not Use int. The code must not depend on the size of data elements. A common offender is int, which is often either 16 or 32 bits. It is better to use either #def ine or typedef to define a new identifier of the appropriate size to use in declarations. To use int alone is to allow the compiler implementor to make the size decision for you. The following is recommended: #define int8 signed char #define intl6 short #define int32 int October 26, 1992 Page 35 and then use only the identifiers int32, intl6 and int8 in place of int , short or char. When moving to a system that has a different definition of int, it is only necessary to change these definitions. • Make No Character Code Assumptions. Avoid using the actual encoding of characters. MTS (*C89) uses EBCDIC character codes while most systems use ASCII. • Use Variable Length Parameter Lists. Variable length parameter lists should be handled using the type and macros in (va_list, va_start, va_arg, and va_end). It is advisable to use these macros because other C compilers may handle variable length parameter lists in a different way or have types of different sizes. However, the parameter passing method used by *C89 is compatible with that used by most UNIX C compilers. • Isolate System Dependencies. Avoid accessing system-dependent data structures, e.g., the fields in a FILE structure, and try to isolate the system dependencies in a separate module. Remember that UNIX path names are, in general, quite different from MTS file/device names. Code that refers to files or devices by name is very likely to be system-dependent. Don't depend on *C89 extensions such as the FILL option. 8 Porting Code From Elsewhere to *C89 8.1 UNIX Code Several options have been provided to make porting C programs written for UNIX systems somewhat easier. The UNIX4.3 pragma (option) may provide sufficient portability. See section 4, "Pragmas and Par Field Options," for details. Some UNIX C compilers append an additional zero argument to parameter lists. If the code is coming from one of those compilers (e.g., that used by Sun Microsystems), the ZEROARG pragma would be useful. Reference R1063 Page 36 8 PORTING CODE FROM ELSEWHERE TO *C89 There are a number of UNIX functions in the library. However, the facilities of MTS do not always provide the functionality necessary to implement some of the UNIX functions. 8.2 Identifier Case and Length The ANSI C Standard allows for some variation in how external variable names are treated. It requires only a minimum of the first six characters to be significant, ignoring any case distinctions. By default, *C89 allows 128 significant characters in external names but does ignore case distinctions. Note that this is not the case for static and local identifiers. For example, a declaration at the outer level (external) int abc, ABC; /* illegal conflict of EXTERNAL identifiers */ is legal in many systems, but it will not work correctly in *C89. The compiler may be able to diagnose some external name collisions but not those occurring between separate compilation units. If the option PAR=MC is specified, then the outer level declaration int abc, ABC; will be legal. (PAR=MC must not be used indiscriminately; see section 4, "Pragmas and Par Field Options," for more information). October 26, 1992 8.3 Initialization of Variables Page 31 8.3 Initialization of Variables At the beginning of execution, external and static variables are initialized to all zeros. No code should depend on the implicit initial values of auto variables, but in fact, some imported code may inadvertently depend on the fact that stack storage starts off with a value of zero (unlike MTS). The FILL pragma may be used to set the entire stack frame to the fill value upon function entry. Note that because the storage allocated for local variables within inner blocks may overlap, the variables in inner blocks may not always be set to the fill value. The FILL pragma should not be used blindly except where there is a proven problem, as it will slow execution. Do not write programs that depend on the FILL feature, since the program will not be portable. 8.4 Diagnosing Portability Errors When moving a C program from elsewhere to MTS, *C89 will often pro- duce many warning or error messages. Most of the warning messages are a consequence of the diagnostics in *C89 and can be ignored (such warnings can be controlled with the UNIX4.3 and WARN options). Here are some suggestions for dealing with those errors that cannot be ig- nored. 8.4.1 Illegal Character: xx (hex) This probably indicates a problem was introduced as the file was transferred to MTS. For example, it may not have been correctly translated from ASCII to EBCDIC. Reference R1063 Page 38 8 PORTING CODE FROM ELSEWHERE TO *C89 8.4.2 Missing Include File "xxx.h" If the missing include file is a private include file, it should simply be trans- ferred to MTS from the original system. If the include file is a system include file from another system, the same features may be available in *C89INCLUDE in a different include file. If the equivalent features are not available, there may be serious difficulties in getting the program to run on MTS. 8.4.3 External Name Conflicts It is possible that the originating system's method of processing external names was different from that used by *C89 on MTS. The following error message may indicate this problem: Error: the following external names do not resolve to unique loader names. This will happen when the names differ only in upper and lower case letters in the name as in XYZ and xyz. In some cases the compiler will not recognize that external names are not unique (for example, if the conflict is between names in separate compilation units). In this case the name conflict will be diagnosed by the MTS loader. Regardless of which program gives the warning, the solutions are the same. In such cases one of the two names can be changed. This can be done using C's #def ine feature as follows: #define namel name2 Make sure the names you pick are all unique. The LOADNAME option can also be used to help with these problems. October 26, 1992 8.5 File and Device Name Differences Page 39 8.5 File and Device Name Differences Even when a program compiles successfully, there is no guarantee that it will run successfully. One problem is that programs on other systems (such as UNIX) may use routines that do not exist in *C89LIB or MTS. Another problem is that file naming schemes are quite different among different op- erating systems. For example, if a program brought from UNIX refers to a tape as /dev/rts8, that reference will have to be changed to something that is a tape on MTS. 8.6 Character Codes Since MTS uses EBCDIC and many other systems use ASCII, there may be problems because the program assumes too much about the character set. Problems sometimes arise because A-Z does not form a contiguous range in EBCDIC. For example, the following is true in ASCII but not in EBCDIC: > i '+!==' y 9 The Execution Environment Execution of a *C89 program usually begins in a function in *C89LIB. This function performs various initializations such as allocating the run- time stack and initializing the memory management and I/O routines. A call is then made to the (user) function main. Entering a C function from a program written in some other language, as well as calling functions written in other languages, is discussed below. Reference R1063 Page 40 9 THE EXECUTION ENVIRONMENT 9.1 Stack Allocation One of the duties of an initialization function is to allocate a stack in which local variables and housekeeping data are stored. The default stack is 160K, but a program with larger storage requirements will need a larger stack. If the external integer variable _stack is defined within any of the user's compilation units, it is taken to be the number of pages (4K each) of stack space needed. Upon entry, each function requires a minimum of 64 bytes of stack space. To this one must add the space required by all local variables and tempo- raries. The SUMMARY pragma will print out the required stack space for each function. Thus, a program with substantial stack requirements might contain the fol- lowing line in it: int _stack = 32; which requests 32 pages (131,072 bytes) of stack space. *C89 protects the first page after the end of the allocated stack so that stores into this region will result in a protection exception. The storage protection exception will often occur at the first instruction of a function as it tries to save the registers. If a stack addressing exception occurs, typically either the stack may be too small or there is unlimited recursion. The stack size is used and the final page is store-protected only when exe- cution is started in a *C89 main program. 9.2 Passing Parameters to the Main Program Parameters given on the PAR field on the $RUN command for a C main pro- gram may be accessed in the standard C fashion. Specifically, a C program that needs to examine the PAR parameters should be declared as October 26, 1992 9.2 Passing Parameters to the Main Program Page 41 main(argc , argv) int argc; char *argv [] ; The PAR-field parameters are placed in strings pointed to by the elements of argv array, starting at argv[l]. argc is one greater than the number of parameters given. The contents of argv [0] are undefined, which is not compatible with UNIX. Some systems pass a third argument, arge, which is a pointer to an environ- ment list. While this third parameter may be declared, *C89 always passes a NULL (0). The parameters are separated by blanks (not commas as one would nor- mally expect in an MTS PAR field). The following characters have special meaning. Blanks (one or more) separate the parameters. Quotes (single and double) are used to enclose characters so that the spe- cial characters (such as blank) are inactivated. The result has the quotes removed. If the quotes are unbalanced, a parameter is made of all characters from the last unbalanced quote up to the end. Backslash causes the next character to be taken literally. For example: main (argc , argv) int argc; char *argv [] ; {int i ; for (i=l; i (acos, asin, atan, atan2, cos, cosh, exp, log, loglO, sin, sinh, sqrt, tan, tanh) are remapped with the LOADNAME pragma to names in *C89LIB that begin with an underscore. 10.4 Getting MTS rather than C Functions Few MTS system routines have the same names as C library functions, but when this happens and the MTS function must be called, it is best to call the MTS routine by an alternate name. This is true for the MTS routines FREAD, FWRITE, MOUNT, READ, RENAME, REWIND, SYSTEM, TIME, WRITE, and many of October 26, 1992 10.5 Calling PL US Routines Page 4 7 the mathematics routines such as ACDS or SQRT. Some MTS routines have alternate names already defined in the MTS system (e.g., READ, TIME, and WRITE have alternate entry points MTSREAD, MTSTIME, and MTSWRITE). The header file contains prototype definitions for many MTS system functions and defines the alternate entry point names MTSMOUNT, MTSRENAME, MTSREWIND, and MTSSYSTEM. For example, you may call the MTS system subroutine READ (at its alternate entry point mtsread) by using the following code: #include char *buffer; short int len; int mods, lnum, fdub, re; mtsread(buff er , &len, femods, felnum, fefdub, retcode re); In this example, MTSREAD expects addresses of all its parameters, buffer is already an address, so & is not used with it. 10.5 Calling PLUS Routines It is easy to call PLUS from *C89 provided that the data types of the PLUS arguments match the data types of the C parameters. Remember that PLUS may pack objects in a parameter list differently than C does. This can affect both the arguments to the routine and the return value. Also remember that the definition of a PLUS string and a C string are different. 10.6 Calling Assembly Language Routines If an assembly language routine is to be called from C, it must first save all registers in the region pointed to by GR13. On entry, GR1 will point to a parameter list (as explained in section 9.3, "Details of Parameter Passing"). GR10 must be used as the code base register. After entry, the routine must set GR12 to the value of GR13 and then increase GR13 by the size of the Reference R1063 Page 48 10 CALLING NON-C ROUTINES routines stack frame plus 64 bytes for the save area (i.e., if the routine needs 64 bytes of stack, you must increase the value of GR13 by 128). The routine is then free to use this area for temporary storage. (If the routine doesn't need any temporary storage, it should increase GR13 by 64). After entry, the routine must not disturb the contents of GR11. On exit the routine must restore all general registers except GRO from the area pointed to by GR12. Floating point registers need not be restored. If the routine returns an integral type or a pointer, it should return the value in GRO. If it returns a float it should return the value in the high portion of FRO, the low portion will be ignored. If it returns a double or long double, it should return the value in FRO. If the routine returns a struct or union, it must move the struct or union into memory supplied by the caller. The address of this memory is the first parameter passed to the routine. A typical routine to be called from C will look like this: ROUTINE STM 0,15,0(13) LR 12,13 LR 10,15 USING ROUTINE, 10 LA 13,stack_frame_size(13) L 0,return_value LM 1,15,4(12) BR 14 The sequence above does not do stack checking. If stack checking is desired, the following sequence can be used instead: October 26, 1992 Page 49 ROUTINE STM 0,15,0(13) LR 12,13 LR 10,15 USING ROUTINE, 10 LA 13,stack_frame_size(13) L 15,4(11) C 13,0(15) BNL error_routine L 0,return_value LM 1,15,4(12) BR 14 This code will insure that there is enough stack for 72 bytes beyond the current stack frame (so that subroutines can be safely called). Stack checking is only necessary if more than 72 bytes of stack are used by the procedure or if the procedure contains one or more procedure calls. 11 Calling C From Foreign Environments There are two ways to define a C function so that it may be called from a non-C program. A normal C function uses the MTS coding convention linkages internally, so any calling program that uses the same linkage may call a C program subject to C environment initialization requirements given below. Alternatively, a C function may be defined to be entered with a FORTRAN (OS S-type) linkage. Also see section 9, "Execution Environment," for details of parameter pass- ing. Reference R1063 Page 50 11 CALLING C FROM FOREIGN ENVIRONMENTS 11.1 Using FORTRAN Linkage By using the __f ortran keyword on a function definition, it is possible to define a C function that can be called directly from any language that uses FORTRAN (OS S-type) linkage. A C function that is defined this way will call an interface routine at the time of entry to initialize the C environment, if it has not already been initialized. The programmer doesn't have to be concerned with explicit initialization of the C environment (with C89INIT). The _stack and _TRUSTME parameters are used in the initialization process exactly like C main programs. For example, a C function that can be called from FORTRAN and will return the sum of its arguments could be written as follows: fortran int sum(int *a, int *b) { return a+b; } Note that the types of parameters and return values needed by the C pro- gram are as described in the previous section "Type Equivalences for FOR- TRAN." The programmer must be aware of the consequences of such a function definition. • There is additional overhead upon entry, because of the need to estab- lish a C environment. • All calls to such a function must use OS S-type (FORTRAN) linkage, including calls from other C functions. No such routine can be called asynchronously, for example calling a C func- tion with a FORTRAN linkage from either PGNTTRP or ATTNTRP will not work correctly. The return code for such a routine can be set by adding the following state- ment anywhere in the routine. If the statement is placed in a routine called by the __f ortran routine, the return code is not preserved. October 26, 1992 11.2 Using MTS Coding Convention Linkage Page 51 __SAVEAREA[15] = e; where "e" is any integer expression. If I/O was performed while in the C environment, it may be necessary to insure that all streams are closed so that the final buffer contents are properly written. This can be done by calling the _cleanup function before the final C function returns. 11.2 Using MTS Coding Convention Linkage This section describes how one may call a C function with normal coding conventions linkage. This type of call is generally available only from Plus or assembly language. 11.2.1 Initialization of the C Environment If the main program is not written in C, the initialization routine C89INIT must be called at some point before entering the C-environment. Failure to do so will result in many C routines not working, in particular the I/O routines, storage routines, and the exit routine. C89INIT must be called only once and must not be called if there was a C main program. C89INIT must be called using the MTS coding convention linkage. Plus uses this linkage convention, but for other languages, see The MTS Coding Conventions by Steve Burling. C89INIT takes a single int parameter with the value in the range 0-7, the sum of three bit flags. Bit 31 (value 1) affects how exits within the C code are interpreted. If is given for this bit, then exit(0) causes the MTS routine SYSTEMS to be called. A call to exit with a non-zero value results in the MTS routine ERROR* being called. When 1 is given for this bit, all calls to exit will return to C89INIT which, in turn, returns to whomever called C89INIT. Reference R1063 Page 52 11 CALLING C FROM FOREIGN ENVIRONMENTS When this is done, care must be taken. The return value from C89INIT must be checked, and the program must respond correctly. Otherwise an infinite loop will result. If bit 30 (value 2) is on, the standard units stdin, stdout, and stderr are not opened within C89INIT. Suppressing this opening may be useful if the standard opening would cause problems. Even if this bit is set on, it is still possible to explicitly open these units with calls to freopen (See section 15.5.8, "Initial Stream Assignments.") If this bit is off, the units are opened as expected within C89INIT. If bit 29 (value 4) is on, this will allow explicit and implicit concatenation, line number ranges and I/O modifiers to be used for files/devices opened for input. This is analagous to the _TRUSTME flag. "Normal" returns from C89INIT give a return value of 0, returns caused by a call to exit return 1. In the latter case the return code from C89INIT will contain the value given to exit. 11.2.2 Closing the C Environment If I/O was performed while in the C environment, it may be necessary to insure that all streams are closed so that the final buffer contents are properly written. This can be done by calling the .cleanup function before the final C function returns. 11.2.3 Calling *C89 from Plus As an example of how C89INIT may be used, the following is a possible PLUS program which calls C89INIT: °/„Include (Main, Message, Message_Initialize, Integer, Boolean) ; °/ Punch(" ENT MAIN"); Procedure C89INIT is Procedure October 26, 1992 11.2 Using MTS Coding Convention Linkage Page 53 Parameter Flag is Integer, Result From_Where is Boolean in Register End; Procedure C_Stuff is Procedure End; Definition Main; Variable Mcb is Pointer to Unknown; Mcb := Message_Initialize() ; /* Init C environment before calling C routines */ If C89INIT(1, return code Re) then Message(Mcb, " The return code was " , Re); Return; End if ; /* C_Stuff is a routine written in C. */ C.Stuff () ; End; 11.2.4 Calling C from Assembly Language Calls from assembly language to C are straightforward, provided the correct registers are set up beforehand. GR1 must point to a parameter block. (If the called routine doesn't expect any parameters, a parameter block need not be supplied). The format of the parameter block was explained in section 9, "Execution Environment." GR13 must point to a stack. This region must be large enough for all the routines that are called as a result of calling the particular C routine. C main programs typically allocate 160,000 bytes for this purpose. GR11 must point to the global area. This contains all the pseudo-registers. The CXD instruction should be used to determine its size. The first two Reference R1063 Page 54 12 PUTTING DEBUGGING TOOLS INTO THE SOURCE words of the region have special significance to coding convention routines. See The MTS Coding Conventions by Steve Burling. The global storage of C currently does not use this region, but the C run-time system does. GR14 and GR15 must be the return address and the entry point address, respectively. On return, the C program will restore all general registers except GRO. Floating point registers are not restored by the called program. If the routine returns a floating point value, it will be in FRO; if the routine returns any other type of value (except a struct), it will be in GRO. If the C function returns a struct, there must be another parameter passed at the beginning of the parameter list that is the address of where the struct result should be stored (GRO will not be set in this case). A typical call to a C routine might look like this: L 13,A(stack_space) L 11 ,A(pseudo_register_space) LA 1 ,parameter_list L 15, =V (routine) BALR 14,15 12 Putting Debugging Tools Into the Source The most common way to debug C programs is to insert printf calls at critical points in the program. It's often useful to #define a flag that controls whether debugging source is generated by the preprocessor. This allows the debugging code to be completely enabled or disabled with only a recompilation. October 26, 1992 Page 55 It's also easy to use the facilities of to insert optional debugging code permanently in the source program. To determine if failure to initialize a local variable could be the source of a bug, the program can be recompiled with the FILL option, which will then initialize all local variables to some desired value. 13 Debugging With SDS *C89 does not come with a separate debugging program or package. How- ever, *C89 programs can be monitored with the MTS symbolic debugger (SDS). The following sections are not a tutorial in SDS. If you haven't used SDS, see MTS Volume 13: The Symbolic Debugging System, Reference R1013. The intent of this section is to point the way toward using the most useful SDS commands. 13.1 Invoking SDS SDS can be invoked in two fashions. In the first, simply replace the $RUN command with the $DEBUG command, and the debugger will take over. In the second, invoke the debugger using the $SDS command once a program has been loaded. You may find it convenient to use the second method when a bug unexpectedly appears and the program stops with a protection exception or something of that sort. Issue the $SDS command followed by an include of the object to be debugged. The include enables SDS to obtain the symbol table information. SDS obtains information about symbolic names from two sources. First, the names that the MTS loader uses are available to it. Second, there are names that the compiler told SDS via "SYM" records. These informational records are produced only when the SYM pragma or compile option has been given. Note: SDS maps all names to upper case internally. Reference R1063 Page 56 13 DEBUGGING WITH SDS Normally, the following commands should be issued at the beginning of a debugging session to prevent the signal routines from trapping attention and program interrupts. set attn=off pgnt=off 13.2 Storage Layout The following C constructions in a compilation unit are mapped into object module entities as follows. Each object module contains one or more control sections (csects). External functions are each assigned a separate csect. This csect contains both the code and the constants from a function. The main program is no different from any other function - it is just an external function that is called by the library when the program is executed. Static functions are appended onto the control section of the first exter- nal function. There must be at least one external function in every compilation unit that has static functions. External variables are placed in their own separate csects. Static variables are collected into a single blank csect. Local variables (auto) are allocated on the run-time stack. 13.3 Setting Breakpoints It's possible to indicate points in the program where execution should stop. These are conventionally called breakpoints. A breakpoint may be set at the beginning of the function f by issuing break f October 26, 1992 13. 4 Continuing Execution after a Break Page 57 where f is the name of the function. Note that the LOADNAME of the function is used here. For many C library routines this is different than the real name. The LOADNAME is frequently prefixed with an underscore (_). For example, read becomes _read. It's also possible to set a breakpoint at any statement. To do so both a line number and a CSECT must be specified (See section 13.2, "Storage Layout.") This can be done either by specifying the CSECT within a CSECT command, which may be followed by one or more BREAK commands, or by specifying the CSECT within the BREAK command. For example both of the following two sets of commands do the same thing: csect f break #13 break #13_7 or break #13@cs=f break #13_7@cs=f The first of these break statements will put a breakpoint at the code for the statement that has source line number 13.000. The second will put a breakpoint at the code for source line number 13.700. 13.4 Continuing Execution after a Break When execution stops at a breakpoint and variables have been examined, and it is desired to continue execution, issue the continue command. The breakpoint from which execution is proceeding remains in effect. 13.5 Removing Breakpoints Breakpoints may be removed by means of the restore command. For ex- ample, to undo the effect of the previous break commands, issue one of the following two sets of commands: Reference R1063 Page 58 13 DEBUGGING WITH SDS restore f restore #13@cs=f restore #13_7@cs=f or csect f restore f restore #13 restore #13_7 The clean command can be used to remove all breakpoints. 13.6 Displaying Variables The ease with which SDS can be used to display variables depends upon the storage class of the variable. Each kind is discussed separately. It is often useful to use the SDS @t= modifier to select the appropriate type. (A complete list of types that can be displayed is given in section 13.8, "Correspondence between *C89 and SDS Types.") 13.6.1 Displaying External Variables To display external variables, issue the SDS display command with the name of the external variable. For example, to display an int external variable called count, use the command: display count@t=f 13.6.2 Displaying Static Variables Static variables can not currently be displayed from SDS. October 26, 1992 13.6 Displaying Variables Page 59 13.6.3 Displaying Local (auto) Variables When a *C89 function is executing, GR12 points to the current stack frame. The current stack frame holds the save area for saving the registers on entry as well as all of the function's local (auto) variables and temporaries. The save area occupies the first 64 bytes of the stack frame. To display an auto variable, it's necessary to know its offset in the current stack frame. All auto variables are allocated on the execution stack (even variables that have been assigned to a register.) The first variable will have offset 64 and subsequent variables are assigned offsets with higher offsets aligned as appropriate. For more information on how the compiler calculates the offsets, see the sections on "Integers", "Floating Points", etc.. Once the offset (in hexadecimal) is known, the display command can be used to display auto variables in the current function as follows: display $grl2+offset By default SDS will display values in hexadecimal. If some other type is desired, it is necessary to append the @t= modifier. For example, to display 10 characters starting at offset 1C, display $grl2+lC@t=cllO For variables that have been assigned to registers, you must determine to which register the variable has been assigned. (This can be done by looking at the OBJLIST output from the compiler.) Then simply issue a command such as display gr5@t=f where GR5 is replaced with the correct register number and t=f can be replaced with a different expression, if the value is not an integer. Reference R1063 Page 60 13 DEBUGGING WITH SDS 13.6.4 Displaying Parameters Parameters are normally allocated on the execution stack. If a parameter has been assigned to a register, its value is copied into that register soon after the beginning of the function. When a *C89 function is called, GR1 points to the parameter block. Soon after the beginning of execution, this value is copied to GR8, and GR1 may be used for other purposes. To display a parameter, it's necessary to know its offset in the parame- ter block, see section 9.3, "Details of Parameter Passing," to learn how to calculate such offsets. Once the offset (in hexadecimal) is known, the display command can be used as follows: display $grl+offset display $gr8+offset The first command is used immediately after program entry, and the second command is used after GR8 has been assigned a value. As was the case for auto variables, by default SDS will display values in hexadecimal. This can be overridden in the same manner. For parameters that have been assigned to registers, you must determine to which register the variable has been assigned. (This can be done by looking at the OBJLIST output from the compiler.) Then simply issue a command such as display gr5@t=f October 26, 1992 13.7 Other Useful SDS Commands Page 61 where GR5 is replaced with the correct register number and t=f can be replaced with a different expression, if the value is not an integer. If this is not done, you will obtain the value the parameter had before the routine was called. For parameters passed to an r-call routine, the parameter resides in the save- area of the routine in question. The offset is simply four times the register number. For example, the offset for GRO is 0, the offset for GR1 is 4, the offset for GR2 is 8, and so on. Such parameters can be displayed in the same way as an auto variable. See the previous section for more information. 13.6.5 Displaying Pseudo-registers Objects which are normal external variables in other C systems have been implemented as pseudo-registers in *C89LIB in order that all simultaneous users may use the same copy of the library routines. In particular, errno has been implemented as pseudo-register. At some point before issuing a display command, SDS must be told which register contains the pseudo- register base. This needs to be done only once per SDS session. using prarea $grll Once SDS knows where the pseudo-register base is, pseudo-registers may be displayed in the same way that any external variable is displayed. So, for example, one can issue the command display errno 13.7 Other Useful SDS Commands To print the call history after a breakpoint, one may use the following com- mand: Reference R1063 Page 62 13 DEBUGGING WITH SDS trace stack To determine the point at which execution has stopped after a breakpoint, one can issue the following command: symbol $psw Once SDS has stopped at the beginning of a function you can continue execution and stop when the function returns with the command continue $grl4 you can determine the caller of that function by issuing the command symbol $grl4 (but only at the beginning of the function) . 13.8 Correspondence between *C89 and SDS Types To display C variables in something approximating their C types, the fol- lowing SDS types should be used. char @t=cll (see text). signed char @t=fll. short @t=fl2. int @t=f. October 26, 1992 Page 63 float @t=e. double @t=d. long double @t=d (only the first 8 bytes used). Note that SDS does not have any support for unsigned types. Such data can be displayed with a signed type with the caveat that large numbers will be incorrectly displayed with negative values. They can also be displayed in hex with @t=xll, @t=xl2 or @t=xl4 depending on the length of the data item. Arrays of char can be displayed with @t=cln with n replaced by the re- quired length. For example, a string of length 10 would be displayed with @t=cll0. Single chars may often contain either small integers or character information, therefore @t=cll or @t=xll or @t=fll may all be used, the choice made based on the exact situation. Note that SDS will not deter- mine the length of a string automatically, nor does @t=c correctly display "non-printing characters." In order to see non-printing characters, a string or character must be displayed with @t=xln. For structs, arrays and unions, the object must be broken down into smaller pieces each of which can be displayed with the types indicated. For other types such as bit fields and pointers, they can be displayed in hexadecimal with the type modifier @t=xln (where n is replaced with the correct length. A bit field with length of 3 bytes would be displayed with @t=xl3, a pointer of length 4 would be displayed with @t=xl4). Bit fields that do not occupy an integral number of bytes can be display with @t=xln, but it is up to the programmer to interpret the information. 14 The Library and Header Files This section describes the library support for the run-time environment in MTS for C programs. *C89LIB is the run-time support library used by programs compiled with *C89. *C89INCLUDE is the header file include library with the standard headers that provide the definitions and declarations required by programs using *C89. Reference R1063 Page 64 14 THE LIBRARY AND HEADER FILES 14.1 The *C89 Run-Time Library The MTS *C89 run-time library (*C89LIB) provides all the ANSI C Stan- dard library functions. Additionally, it contains many UNIX facilities. Be- cause MTS does not support some features available in UNIX, certain facil- ities are either omitted entirely or are present only in an abbreviated form. *C89LIB was designed to behave similarly to BSD4.3 UNIX. However, *C89LIB is not identical to BSD4.3, and it may be necessary to make some alterations to the source code of programs that run on UNIX to get them to run on MTS. In particular, one must recognize that there are two types of files (binary and text) in *C89LIB (BSD4.3 has only one type of file); the way MTS processes control characters is different from BSD4.3; and the details on how certain devices (such as printers) work is different. Also some facilities of BSD4.3 are not provided. Each of these differences may require changes to some programs. More details about these differences are described in the following sections. It is also possible to call MTS routines directly. See sections 10.2 - 10.4. 14.2 Header Files The MTS file *C89INCLUDE contains the standard headers (those enclosed in angle brackets). *C89INCLUDE contains, in the include library format, the various include files provided by BSD4.3 implementations of UNIX. In addition to this, it contains a complete set of ANSI C Standard header files and an include member called , which is read in by the compiler before reading the source file. (This provides certain translations that are necessary for the proper functioning of *C89LIB.) The members in this file are usually contained in separate files on UNIX systems. By default, only the standard symbols are available from the standard header files. To access additional symbols, primarily those used in UNIX systems, the STANDARD+, UNIX, or UNIX+ pragmas can be used. The effects of these pragmas on the standard header files are: October 26, 1992 14-2 Header Files Page 65 • STANDARD, the default, includes only the standard identifiers. • STANDARD+ includes all standard identifiers and all UNIX and MTS identifiers that don't conflict with the standard. • UNIX includes only UNIX identifiers. • UNIX+ includes all UNIX identifiers and all standard and MTS identi- fiers that don't conflict with the UNIX definitions. The following sections summarize the features available that are specific to *C89. A complete description of each header file can be found by examining *C89INCLUDE. 14.2.1 Standard Header Files All ANSI C Standard header files are supported: , , , , , , , , , , , , , , . 14.2.2 UNIX Header Files The include files from the BSD4.3 UNIX system are also available in this library. A list of the available header files can be found by examining the beginning of *C89INCLUDE. 14.2.3 MTS Header File Function prototypes, type definitions, and flag values for MTS routines may be found in . Reference R1063 Page 66 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS 14.2.4 Header File Search Order The two kinds of header, or include, files (angle-bracket and quoted header files) are searched for in the following order. The search ends when a match- ing file name is found. Angle-bracket header files are searched in the following order: 1. Search any library-organized file assigned to unit 2. 2. Search *C89INCLUDE (unless NODEFINC was specified). Quoted header files are searched in the following order: 1. Search for the file on the MTS userlDs specified in the I option in the order the userlDs were specified. 2. Search the current userlD. 3. Search any library-organized file assigned to unit 2. 4. Search *C89INCLUDE (unless NODEFINC was specified). 15 The MTS *C89 Library, Headers, and Macros This section provides a summary of extensions or implementation-defined features of *C89LIB and *C89INCLUDE. The following sections correspond to header file names and are presented in alphabetical order of those names. Functions that have non-standard behavior and functions that are not re- quired by the ANSI C Standard are noted as such. October 26, 1992 15.1 assert. h - Debugging Aid Page 61 15.1 assert. h - Debugging Aid The header defines the assert macro. This is used for putting diagnostics into the program. When an assertion failure occurs, a message similar to the following is printed on stderr: Assertion failed. Line 15.000 of file xyz.c. After printing this message, the routine abort is called. 15.2 ctype.h - Character Handling The header declares several macros useful for testing and map- ping characters. In all cases, the argument is an int, the value of which is representable as an unsigned char or is equal to the macro EOF. If the argument has any other value, the results will be unpredictable. The term 'printing character refers to a member of an implementation- defined set of characters, each of which occupies one printing position on a display device. These include the space character, the alphabetic charac- ters (a-z, A-Z), the decimal digits (0-9), and the following characters: >, V The term control character refers to one of an implementation-defined set of non-printing characters. In our implementation, the control characters are those whose values fall between the values 0X00 through 0X3F. The following control characters have special meanings: • '\n' (newline) • '\f ' (form feed) • '\r' (carriage return) • '\b' (backspace) Reference R1063 Page 68 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS • '\t' (horizontal tab) • '\v' (vertical tab) Some of these functions are implemented both as macros and functions, an #include of is needed to make the macros available. The character-testing functions described in this section return non-zero (true) if, and only if, the value of the argument c conforms to the description of the function. The following standard functions are implemented: int isalnum(int c) - true for upper-case, lower-case letters and digits. int isalpha(int c) - true for upper-case and lower-case letters. int iscntrl(int c) - true for control characters listed above. int isdigit(int c) - true for decimal digits. int isgraph(int c) - true for printing characters, excluding space. int islower(int c) - true for lower-case letters (a-z). int isprint(int c) - true for printing characters listed above. int ispunct(int c) - true for printing characters, excluding space and alphanumeric characters. int isspace(int c) - true for '\f ', '\r', '\n', '\r', '\f, '\v', and space. int isupper(int c) - true for upper-case letters (A-Z). int isxdigit(int c) - true for hexadecimal digits (0-9, a-z, A-Z). int tolower(int c) - if isupper(c) is true, returns the corresponding lower-case letter. Otherwise, the argument is returned unchanged. int toupper(int c) - if islower(c) is true, returns the corresponding upper-case letter. Otherwise, the argument is returned unchanged. The above macros assume an EBCDIC character set. October 26, 1992 15.2 ctype.h - Character Handling Page 69 15.2.1 isascii Name: isascii Purpose: Test for an ascii character Include file: Prototype: int isascii (int c) Description: isascii returns true if the argument can be represented in 7 bits. If the decimal value of c falls in the range to 127, it will return true. Note: This function is not required by the ANSI C Standard. Programs using this function may not be portable. This function is included for compatibility with UNIX implementations. 15.2.2 toascii Name: toascii Purpose: Character mapping to ASCII Include file: Prototype: int toascii (int c) Description: The character codes used by the *C89 compiler are standard EBCDIC. This macro returns the value of a character's ASCII equiv- alent. Note: This routine uses the same translate tables as MTS. This function is not required by the ANSI C Standard. Programs using this function may not be portable. This function is specific to the *C89 implementation on MTS. Reference R1063 Page 70 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS 15.3 math.h - Mathematics The header declares the floating point mathematical functions and defines three macros related to error processing. The floating point functions described in this document take double- precision arguments and return double-precision values. The header maps references of math functions (e.g., sqrt) into references to the actual supported names (e.g., _sqrt). In this way, conflicts between C function names and MTS subroutine or function names are avoided. 15.3.1 Treatment of Error Conditions For all functions, a domain error occurs if an input argument is outside the domain over which the mathematical function is defined. When a domain error occurs, the integer variable errno acquires the value of the macro EDOM. With the exception of log and loglO, all math functions return 0.0 on a domain error. Both log and loglO set errno to EDOM if the argument is negative. The value returned by log(-x) is the same as log(x) for all x. The value returned by loglO(-x) is the same as loglO(x) for all x. f mod returns zero if its second argument is 0.0 and the value of errno is not changed. Similarly, a range error occurs if the result of the function cannot be repre- sented as a double value. If the result overflows (the magnitude of the result is so large that it cannot be represented in an object of the specified type), the function returns the value of the macro HUGE_VAL, with the same sign as the correct value of the function; the integer variable errno acquires the value of the macro ERANGE. If the result underflows (the magnitude of the result is so small that it cannot be represented in an object of the specified type), the function returns zero. This case is not considered to be an error, and the value of errno is not changed. contains all of the ANSI C Standard function prototypes and macros. If UNIX+ is specified, a number of BSD4.3 additional function pro- totypes and macros become available. October 26, 1992 15. 4 signal. h - Signal Handling Page 11 15.4 signal. h - Signal Handling defines a number of macros and function prototypes that allow for interception of various events by a C program. The signal parameters recognized by the signal facility follow. Those pre- ceded by an * (asterisk) may result from the environment outside the library environment, e.g., an attention interrupt or a hardware program interrupt, or from a call to the raise function. The others currently can only be raised. Some signals can be ignored, blocked (via the user specifying a blocking mask), or caught (by the user specifying a signal handler). SIGKILL and SIGSTOP cannot be ignored or caught. SIGKILL, SIGSTOP, and SIGCONT cannot be blocked. For all other signals, they may be ignored, blocked, or caught. The following is the list of the supported signals (SIG_IGN means ignore the signal) : * SIGHUP 1 Hangup. (Default = $SIGN0FF from MTS.) * SIGINT 2 Attention interrupt. (Default = Error exit to MTS with the process still loaded.) * SIGQUIT 3 Quit. The same as SIGTERM, but can be raised from the keyboard. (Default = Terminate the process via exit (0) .) * SIGILL 4 Illegal operation or invalid function image (per the C Standard). This is caused by either an operation exception, privi- leged operation exception, execute exception, or specification excep- tion. (Default = Error exit to MTS with the process still loaded.) * SIGIDVF 5 Integer overflow caused by a fixed-point overflow. (De- fault = SIG_IGN.) * SIGABRT 6 Abnormal termination. Causes the process to terminate without cleanup. (Default = Error exit to MTS with the process still loaded.) * SIGDECDVF 7 Decimal overflow caused by decimal overflow exception. (Default = SIG_IGN.) Reference R1063 Page 72 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS * SIGFPE 8 Floating point exceptions, caused by the following hard- ware exceptions: data exception (decimal operations), integer divide by zero, decimal divide by zero, floating exponent overflow, and float- ing point divide by zero. (Default = Error exit to MTS with the process still loaded.) * SIGKILL 9 Terminate the process. (Cannot be caught, ignored, or blocked.) (Default = $SIGN0FF from MTS.) * SIGBUS 10 Bus error. This is caused by a protection exception in MTS. (Default = Error exit to MTS with the process still loaded.) * SIGSEGV 11 Segmentation violation (invalid storage access) caused an addressing exception in MTS. (Default = Error exit to MTS with the process still loaded.) * SIGSYS 12 Bad argument to system call. (Default = Error exit to MTS with the process still loaded.) * SIGPIPE 13 Write on pipe with no one to read it. (Default = Error exit to MTS with the process still loaded.) * SIGALRM 14 Alarm clock. Typically used by a process so that it can be woken up at a specific time in the future. (Default = Error exit to MTS with the process still loaded.) * SIGTERM 15 Software termination signal. In UNIX the system will send this signal to all processes shortly before a shutdown to give the processes a chance to cleanup. (Default = Terminate the process via exit(0).) * SIGURG 16 Urgent condition on I/O channel, usually an out-of-band message on a TCP stream. (Default = Error exit to MTS with the process still loaded.) * SIGSTOP 17 A stop signal from something other than a terminal. (Cannot be caught, ignored, or blocked.) (Default = Error exit to MTS with the process still loaded.) * SIGTSTP 18 Stop signal from the terminal. In UNIX this is used to checkpoint a process and place it in the background. (Default = Error exit to MTS with the process still loaded.) October 26, 1992 15. 4 signal. h - Signal Handling Page 13 * SIGCDNT 19 Continue a stopped process. (Cannot be blocked.) (De- fault = Error exit to MTS with the process still loaded.) * SIGCHLD 20 This signal is sent to the parent when a child stops or exits. (Default = Error exit to MTS with the process still loaded.) * SIGCLD The same as SIGCHLD. Given for backwards compatibil- ity. (Default = Error exit to MTS with the process still loaded.) * SIGTTIN 21 Given to reader's process group upon background read from a terminal. (Default = Error exit to MTS with the process still loaded.) * SIGTTDU 22 Like SIGTTIN for output. (Default = Error exit to MTS with the process still loaded.) * SIGID 23 Given to a process when input or output is possible (asynchronous). (Default = SIG_IGN.) * SIGXCPU 24 Given to a process when it has exceeded its CPU time limit. (Default = Error exit to MTS with the process still loaded.) * SIGXFSZ 25 Given to a process when it has exceeded its file size limit. (Default = Error exit to MTS with the process still loaded.) * SIGVTALRM 26 Virtual time alarm. (Default = Error exit to MTS with the process still loaded.) * SIGPRDF 27 Profiling time alarm. (Default = Error exit to MTS with the process still loaded.) * SIGSIGNF 28 Floating point significance caused by hardware floating point divide by zero. (Default = SIG_IGN.) * SIGUNFLD 29 Floating point underflow caused by hardware floating point exponent underflow. (Default = SIG_IGN.) * SIGUSR1 30 User-defined signal 1. (Default = SIG_IGN.) * SIGUSR2 31 User-defined signal 2. (Default = SIG-IGN.) Reference R1063 Page 74 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS The equivalent of "signal (sig,SIG_DFL) ;" is not executed prior to calling a user-defined signal handler for the signal sig. Further occurrences of signal sig are blocked until the user's handler returns. The user's signal handler function remains in effect until the user explicitly invokes the signal function to change the signal handling setting, i.e, via SIG_IGN, SIG_DFL, or another handling function. In some systems the SIGILL signal default is reset upon delivery of the signal to a user-specified handler. This implementation treats SIGILL no differently from the other signals. Blocking of a signal, if allowed, is accomplished by either the user calling the UNIX kernel functions sigblock or sigsetmask, or by a signal being delivered by the signal facility to a user-defined signal handler function. In the latter case, future occurrences of the same signal are implicitly blocked by the signal facility. For either case of blocking, only the first occurrence of each blocked signal is queued for processing; other occurrences of the same signal are ignored. A queued event is processed by the signal facility, when it becomes unblocked (by a user function call or by a return of a user-defined signal handler for which the signal facility implicitly blocked the signal). If integer overflow checking is to be used, the CHECKIOVER option must be enabled when the program is compiled. 15.5 stdio.h - Input/Output 15.5.1 Header Definitions The header declares one type, several macros, and many func- tions for performing input and output. It contains the standard definitions and also additional definitions and macros that are contained in , in the BSD4.3 implementation of UNIX. 15.5.2 Input/Output Alternatives There are several methods of performing input/output in C: October 26, 1992 15.5 stdio.h - Input/Output Page 15 • • Use the standard C I/O library, which provides services in a manner compatible with other C implementations. Because this method is portable, it is preferred. Use UNIX functions which are not in the Standard C library. Many of the UNIX BSD4.3 functions are provided in *C89LIB. A detailed description of what is and what is not available is included in later parts of this documentation. More complete descriptions of these functions can be found in UNIX Programmer's Reference Manual, April 1986. Call MTS system I/O subroutines and functions directly. A descrip- tion of these can be found in MTS Volume 3: System Subroutine De- scriptions, Reference R1003. 15.5.3 MTS File Organization The MTS file system, with its line-oriented files, is unusual among operating systems. In particular, many C programs assume a byte-oriented structure, in which newline characters are stored explicitly (rather than causing a skip to the next line of the file) and bytes may be addressed individually. The MTS file structure, however, defines the boundaries of lines, i.e., the begin- ning and end of each line; hence, newline characters are not used to separate lines. In UNIX systems, files may be sparsely populated, and non-existent bytes may be addressed individually. Currently MTS, the standard C I/O library, and the underlying UNIX kernel all require that for a byte to be ad- dressed, it must physically exist within a file's bounds. Of course, in MTS, as in UNIX, one may append data to the end of a file. The MTS file system provides features that are not in some other operating systems. Features which are not compatible with doing an f seek or lseek on a file are: • Explicit file concatenation • Implicit file concatenation • SENDFILE • Sequential files Reference R1063 Page 16 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS 15.5.4 File Types and Input/Output Modes *C89LIB allows files to be used in either of two modes, text mode and binary mode. The mode affects the behavior of the following UNIX kernel routines: read, write, open, lseek, truncate, ftruncate, stat, lstat, fstat and most C standard I/O routines. A file accessed in text mode is referred to as a text file and a file accessed in binary mode is referred to as a binary file. This is compatible with the ANSI C Standard. In many systems (including UNIX), both text mode and binary mode can use the same mechanism, and there need not be any difference between a text file and a binary file. However, this isn't possible on MTS. Binary mode is extremely close to UNIX behavior. In binary mode, bytes are read and written unchanged, including the newline character. File streams opened in binary mode may be positioned to arbitrary byte positions using integer offsets. Almost all C programs that originated on a UNIX system and use the standard I/O library will run unchanged in binary mode. The actual MTS records written in binary mode (except possibly the last record) will be of constant length, which is 1024 in this implementation. However, a program using *C89LIB need not be aware of this fact (the program can write in any size it wants). In general, files written in binary mode cannot be directly read by other pieces of MTS software. They cannot be viewed easily by the MTS File Editor or similar methods; they can be read or written only by a program using *C89LIB. Text mode, the default, allows files to be written that can be read by other MTS programs and vice versa. The behavior of I/O on a text file differs from I/O on a binary file in a number of respects: • Trailing blanks at the end of a line may not appear when the file is read in. • If you seek to a position within a text file where there is a newline ; \n' and write a character other than a newline character, the newline character remains in the file. Replacing the very last '\n' in the file is possible. October 26, 1992 15.5 stdio.h - Input/Output Page 77 • If you seek to a position within a text file where there is a character other than a newline character and write a newline character, the newline character is ignored and the original character is replaced by a blank space character. (That is, it is not possible to change the number of lines in a text file after they have been written except by use of the routines truncate and f truncate). • It is not possible to seek to a position beyond the end of a text file. • If two newline characters are written one after the other to a text file, it is processed as if three characters were written: a newline character, a space, and a newline character, in that order. • Control characters may be replaced with other characters. See section 15.5.5, "Control Characters in Output Streams," for more information. • The character written in column one of the file may be interpreted as a carriage control character. See section 15.5.5, "Carriage Control Characters," for more information. • No more than 32,767 non-newline characters may be written between consecutive newline characters on a file. (If this is attempted, newline characters will be inserted every 32,767 characters.) For devices other than files, there is an ananalogous limit which may be 32,767 or a smaller number, depending on the device and the circumstances. • If a file has been opened for writing, characters have been added be- yond the end of the file, and the last such character written was not a newline character, a newline character gets written automatically when the file is closed, when _exit is called, or when the program terminates. • A text file can be read or written by any MTS program. *C89LIB cannot determine whether a file is text or binary without help from the programmer. It will make assumptions and those assumptions may be wrong in some cases. There are ways to override the normal behavior of *C89LIB to make sure a specific file is processed correctly. The kernel routines open and creat accept CLTEXT and CLBINARY for flag values to denote text or binary mode files. The standard C routines f open Reference R1063 Page 18 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS and f reopen use the character b in the mode parameter to indicate binary mode. Once a file has been used as a text file or a binary file, the run-time system will remember this until _exit is called (calls to open and creat will ignore the CLTEXT and 0_BINARY parameters for such files; they will select the type of the file based on its remembered value) . If a program has calls to the routines truncate, lstat, or stat, the sys- tem can determine the file type if the file has been previously used by the program. In other cases the programmer can use the routine __deffile to specify the correct interpretation. The call __deffile(0) causes all fu- ture such situations to assume text mode. The call __deff ile(l) causes all future such situations to assume binary mode. Warning: If a file is not opened correctly, information will be returned incorrectly. If a file is opened for a write and opened incorrectly, the file will almost certainly be damaged in the process. 15.5.5 Control Characters in Output Streams For a binary stream, all characters are passed unchanged in I/O operations with both the standard and the kernel I/O routines. This is the default for text files also, with the exception of '\n', which is always interpreted as skipping to the next line, and no character, as such, gets written to the file. For text files, a method is provided to indicate that control character inter- pretation is required for a given fd, i.e., a file descriptor. A call to ioctl, that is, ioctl(fd,XHTABS,NULL) will indicate to the run-time system that control character interpretation is expected for the file accessed by this f d, on I/O calls using this fd. If a file has been opened with f open, the file descriptor number is available through the f ileno macro. For output to the terminal, this feature becomes active by default. No call to ioctl is needed. Note: this feature is allowed for files or devices opened only for output. The following apply to text files where control character interpretation has been requested. October 26, 1992 15.5 stdio.h - Input/Output Page 19 • The tab character '\t' is expanded into the appropriate number of spaces to move the column position to the next tab column (the tab stops are set every 8 spaces). • '\r' moves the buffer position to the beginning of the buffer unless it is already at the beginning, in which case it has no effect. • '\b' moves the buffer position indicator back by one unless the buffer position indicator is already at the beginning of the buffer, in which case it has no effect. • '\v' skips to the next line. That is, the current output line is written out, and the buffer position points to the same column it was on before the '\v' was encountered; the spaces up to that position are filled with space characters. '\f gets replaced with a blank space if carriage control mode is not in effect. If carriage control mode is on, then the current output line is written out, and the character 1 gets written at the first position in the buffer. 15.5.6 Carriage Control Characters In some cases the information in column one of a file will not be visible but, instead, will be removed and used to control the amount of spacing between lines. Whether this occurs or not depends on where the output line is being sent. When output is sent directly to a terminal, column one is printed on the terminal; i.e., it is not interpreted. However, if the output is directed to a file and then to a terminal, column one is not printed but is used to control spacing. Normally, output sent to *PRINT* (the printer) will have column one interpreted for carriage controls. Output sent anywhere else is not interpreted for carriage controls. The most common carriage controls are ' 1 ' to advance to the top of the next page, ' ' for single space, '0' for double space, and '-' for triple space. Other characters are specified in MTS Volume 1: The Michigan Terminal System, Reference R1001. Reference RI063 Page 80 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS For text files, a method is provided to indicate that carriage control mode is required for a given fd, i.e., a file descriptor. A call to ioctl, that is, ioctl (fd,CRCTL, NULL) will indicate to the run-time system that carriage control characters need to be written for the file accessed by this f d, on I/O calls using this f d. If a file has been opened with f open, the file descriptor number is available through the f ileno macro. For output to the terminal, this feature becomes active by default. No call to ioctl is needed. Note: this feature is allowed for files or devices opened only for output. When this mode is active, every output line is written with a blank or a carriage control character if a control character that effects a carriage control was part of the output (example: '\f '). NOTE: If a file that is being used for output with carriage control is opened multiple times or opened for read/write there may be unexpected interac- tions. 15.5.7 MTS File Names MTS does not differentiate between upper-case and lower-case characters within file names. In MTS, the string argument filename for open and f open may contain any of the following: A file name, possibly preceded by a userlD and followed by I/O modi- fiers and a line number range, e.g., MYID : MYFILE(1 , 20) . Line number ranges and I/O modifiers are only allowed if the _TRUSTME flag has been set. A device name, e.g, *PRINT*. A sequence of file or device names explicitly concatenated with "+" characters, e.g., A+B(l, 10)+ABCD:THEIRFILE. This is normally not allowed (see below). A logical unit name or number preceded with a "|" (vertical bar) char- acter, e.g., (INPUT, (PRINT, (OBJECT, (0, |l, ..., (99. October 26, 1992 15.5 stdio.h - Input/Output Page 81 If a file or device is opened for writing, or reading and writing, then use of the MTS-specific features of I/O modifiers, line number ranges, and explicit concatenation are not allowed. Open will set errno to EIO and return in these cases. And implicit concatenation also is not available since, $Continue with and $Endf ile are treated as data. The above is the default behaviour for all files and devices. However, if the program contains a definition for an external variable called _TRUSTME, then explicit and implicit concatenation, line number ranges and I/O modifiers are allowed for files/devices opened for input only. (This does not apply when the routine C89INIT is used to initialize the C environment. In that case, these MTS features are allowed only if bit 3 is used when C89INIT is called). When _TRUSTME or bit 3 of C89INIT is used, the programmer must be aware of the following consequences. If there is more than one instance of the file being open and one of these instances has the I/O modifier or the line number ranges, it may cause prob- lems with synchronization, and the results of read calls may be erroneous. If one such instance is for the file to be opened with write, the behaviour is unpredictable. Seeking to random byte positions in the file will also not work, when concatenation or line number ranges are involved. Basically, if the file is being opened multiple times and I/O is performed through multiple fps, then concatenation, line number ranges, and the other I/O modifiers should not be used. If they are, then the results are unpre- dictable. For more information on valid file names, consult MTS Volume 1: The Michigan Terminal System, Reference R1001. 15.5.8 Initial Stream Assignments At the start of execution, stdin is assigned to logical I/O unit INPUT, stdout to the logical I/O unit PRINT, and stderr to to the logical I/O unit SERCDM. By default, *C89 will complain if either stdin or stdout is assigned to a file/device that does not exist or to which you have no access. Also by default, stdout and stderr are emptied if they are attached to files. Reference R1063 Page 82 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS If any of this behavior is not desired, it is possible to suppress the initial opening of the three I/O units. To do this, place a reference to the exter- nal variable jioopen anywhere in the program. Then the three units can be manually opened as desired by using the routine freopen. Note that the units must be opened in the following order: stdin, stdout, and then stderr. For example: #include int _noopen; main() { /* Open stdin first. */ if (freopen ("| INPUT", "w" , stdin)==0) {FILE *msink; /* stderr hasn't been opened yet, so don't write an error message on it. */ msink = f open("*MSINK*" , "w") ; fprintf (msink, " Error opening INPUT."); exit (4) ; } /* Open stdout second. */ if (f reopen ("| PRINT" , "w" , stdout)==0) {FILE *msink; /* stderr hasn't been opened yet, so don't write an error message on it. */ msink = f open("*MSINK*" , "w") ; fprintf (msink, " Error opening PRINT."); exit (4) ; } setlinebuf (stdout) ; /* Open stderr third. */ if (f reopen (" | SERCOM", "w" , stderr) ==0) {FILE *msink; /* stderr hasn't been opened yet, so don't October 26, 1992 15.5 stdio.h - Input/Output Page 83 write an error message on it . */ msink = f open("*MSINK*" , "w") ; fprintf (msink, " Error opening SERCOM."); exit (4) ; } setlinebuf (stderr) ; /* Rest of the program . . . */ } Of course this may be modified as needed to suit a given situation. 15.5.9 Random Access Disk files may be processed randomly by requesting that a given byte posi- tion be made the current one. The functions f seek and lseek set the byte position, while ftell returns the current byte position. MTS random access organization is line-oriented, while the C library random access support is byte-oriented. To efficiently access bytes in MTS files, one of two byte-access organizations is used, depending on whether the file stream is in binary or text mode. In binary mode the byte positions are specified by integers, making it possi- ble to seek to a specific byte, given its offset. This is very efficient, since all lines in the file, except for possibly the last, are of the same length, which makes the byte-position computation simple. Random access must be handled carefully. Changing the length of a line in a file opened for random access will result in an error that will not be detected by the *C89LIB I/O support. Those who want to access MTS files by line number may call MTS subrou- tines, such as MTSREAD and MTSWRITE, directly. Reference RI063 Page 84 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS 15.5.10 Terminal Input/Output Terminal input/output is a sensitive area for programming support. It in- volves the way in which the operating system handles the terminal, as well as the actual behavior of the terminal when given various control codes. Many UNIX-based programs use a library of terminal-independent routines named curses. This library is not available with *C89. Sophisticated ap- plications may call the MTS screen-support routines for full control of the terminal. The terminal support provided with *C89 is character-based, providing the ability to read lines from the terminal and to write lines or line segments to the terminal. The normal character I/O functions are used for this purpose. 15.5.11 Using the MTS I/O Routines It is possible to directly call the MTS routines READ and WRITE, but this must be done with some care. First, the routines must be called by their aliases MTSREAD and MTSWRITE so they don't interfere with the routines READ and WRITE in the C library. Second, they must not use any units that are also being used by the C I/O routines. Third, the __f ortran linkage must be used. 15.5.12 Implementation Specifics for the I/O Routines fopen fopen and freopen are system-dependent by their nature, since they both use a parameter that is a file name. For this reason, fopen and freopen calls are not generally portable. For information on constructing a valid file name, see section 15.5.7, "MTS File Names." If the file is opened in append mode, the file position indicator is initially placed at the end of the file. Opening a file multiple times may cause problems with I/O synchronization, and hence, is strongly discouraged. remove If the file is open, the remove function returns with an error, and errno is set to EINTR. October 26, 1992 15.5 stdio.h - Input/Output Page 85 rename If a file with the new name already exists, the function rename returns with an error and errno is set to EEXISTS. I/O formatting The output for %p conversion for f printf and the input for °/p conversion for f scanf are the same as those used for °/ x conversion. There is no special meaning attached to the '-' character in the scan list for the f scanf %[ format. Random I/O The functions ftell and fgetpos set errno to ESPIPE if the file is not indexable. In text mode, errno gets set to ENOMEM if memory is not available for allocating needed data structures. perror perror (s) will produce the following output on stderr: if s is not a null pointer and the character pointed to by it is not the null character, s is written followed by a colon (:), a space, and the appropriate error message. The error message is produced by using the current setting of errno as an index into the array sys_errlist, which contains the error messages. For the list of the error messages, see the include member sy s/ errno. h or the UNIX Programmer's Reference Manual, April 1986. The error messages and error numbers produced by *C89LIB are identical to those produced by BSD 4.3 UNIX. Input and Output Writing to a stream does not cause the associated file to be truncated beyond that point. MTS allows zero-length files to exist. The implementation does not set a limit on the number of null characters that may be appended to data in a binary stream. (See section 15.5.3, "MTS File Organization" and section 15.5.4, "File Types and Input/Output Modes.") I/O buffers There are two I/O buffers used by the run-time system. The outer level buffer is the one modified by calls that use the FILE pointer. A call to f flush or any action that requires buffer flushing moves this buffer's contents onto an internal I/O buffer. The internal buffer is modified also by the kernel calls dealing with I/O. When the internal buffer overflows or Reference R1063 Page 86 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS the '\n' is encountered, its contents are written to the file or I/O unit. The contents of this buffer are written to the file or I/O unit when calls are made that require updating the contents of the physical unit. 15.6 stdlib.h - General Utilities This header contains the macros and function prototypes required by the ANSI C Standard as general utilities. 15.6.1 Implementation Specifics for the Utilities calloc If size requested is zero, calloc returns NULL. malloc If size requested is zero, malloc returns NULL. realloc If size requested is zero, realloc frees the pointer and returns NULL. If the ptr is NULL and the size is non-zero, realloc allocates mem- ory and returns a pointer to the start of the memory. If memory is expanded, realloc does not initialize the extra space that is allocated. abort The abort function flushes the I/O buffers of all open files, destroys any temporary files created by tmpf ile, and terminates program execution with an error code of 8. It never returns to the caller. exit A call to the exit function terminates execution of the program, and the value of its argument is returned as the MTS return code. getenv The getenv function uses the string argument to obtain the value of a MTS command macro variable. If there is no macro variable with that name, NULL is returned. Otherwise, the value is converted to a string and that string is returned. To set the environment variable, use the MTS Command Macro Processor. For details refer to MTS Volume 21: MTS Command Extensions and Macros, Reference R1021. October 26, 1992 15.7 string. h - String Handling Page 81 system The system function takes a string parameter that is in the form of an MTS command. This command is passed to MTS for processing. 15.7 string. h - String Handling This header contains all the standard macros and prototype definitions re- quired by ANSI C Standard as well as some string function available in BSD4.3 UNIX. 15.7.1 memcmp Note: Objects with "holes" (used as padding for alignment purposes within structure objects), strings that are shorter than their allocated space, and unions may cause problems in comparison with memcmp. 15.7.2 strerror The error messages generated by strerror are the same as the contents of the array sys_errlist. The integer argument is used as an index into the ar- ray. For the list of the error messages, see the include member sys/errno.h or the UNIX Programmer's Reference Manual, April 1986. The error mes- sages and error numbers produced by *C89LIB are identical to those pro- duced by BSD4.3 UNIX. 15.7.3 stricmp Name: stricmp Purpose: String comparison (case insensitive) Include file: Prototype: int stricmp (const char *sl, const char *s2) Description: stricmp returns an integer result similar to strcmp. The stricmp function is similar to strcmp, except it is case insensitive. Reference R1063 Page 88 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS Note: This function is not required by the ANSI C Standard. Programs using this function may not be portable. Example: #include char *sl, *s2; if (stricmp(sl,s2)==0) { > /* Here, if si and s2 are the same except for upper-case/lower-case differences in one or more characters, stricmp returns */ See also: strcmp, strncmp, strnicmp, memcmp 15.7.4 strnicmp Name: strnicmp Purpose: String comparison (case insensitive with count) Include file: < string. h> Prototype: int strnicmp (const char *, const char *, size_t) Description: This function returns an integer similar to strcmp. The strnicmp function is similar to stricmp, except it compares not more than the third parameter number of characters from the string pointed to by the first parameter to the string pointed to by the second parameter. Note: This function is not required by the ANSI C Standard. Programs using this function may not be portable. 15.7.5 strchr Note: The name index is recognized as a synonym for this function, since some UNIX implementations use the name index. For portability consider- ations, use of the name strchr is preferred. October 26, 1992 15.7 string. h - String Handling Page 89 15.7.6 strrchr Note: This function is known by the name rindex in some UNIX implemen- tations. With *C89LIB, the name rindex is a synonym for this function. For portability considerations, use of the name strrchr is preferred. 15.7.7 strlwr Name: strlwr Purpose: Convert string to lower case Include file: Prototype: char * strlwr (char *s) Description: This function returns a pointer to the transformed string s as described below: strlwr converts the upper-case characters in the string pointed to by s to their corresponding lower-case characters. The non-alphabetic characters are unaffected by this transformation. Note: This function is not required by the ANSI C Standard. Programs using this function may not be portable. Example: #include char *t ; char s [50] ; /* Space for a string. */ strcpy(s, "aBc;Def ") ; /* Initialize it. */ t = strlwr (s) ; /* Convert to lower case. */ /* Both s and t now point to "abc;def". */ See also: strupr Reference R1063 Page 90 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS 15.7.8 strupr Name: strupr Purpose: Convert string to upper case Include file: < string. h> Prototype: char * strupr (char *s) Description: This function returns a pointer to the transformed string s as described below: strupr converts the lower-case characters in the string pointed to by s to their corresponding upper-case characters. The non-alphabetic characters are unaffected by this transformation. Note: This function is not required by the ANSI C Standard. Programs using this function may not be portable. Example: #include char *t ; char s [50] ; /* Space for a string. */ strcpy(s, "aBc;Def ") ; /* Initialize it. */ t = strupr (s) ; /* Convert to upper case. */ /* Both s and t now point to "ABC;DEF". */ See also: strlwr 15.7.9 reverse Name: reverse Purpose: Convert string to its reverse order Include file: < string. h> Prototype: char *reverse(char *s) Description: reverse returns a pointer to the string s. It reverses the order of the characters in the string s. October 26, 1992 15.8 time.h - Date and Time Page 91 Note: This function is not required by the ANSI C Standard. Programs using this function may not be portable. Example: #include char *s, *p; strcpy(p,s) ; if (strcmp(reverse(s) ,p)==0) printf(" %s is a palindrome\\n" ,s) ; 15.8 time.h - Date and Time In addition to routines required by the ANSI C Standard, the routines f time, times, and gettimeofday are supplied in . They are not part of the ANSI C Standard but are available in UNIX. They behave as described in the UNIX Programmer's Reference Manual, April 1986. The local time zone, as used by these functions, varies depending on where the program is executed. For Ann Arbor, Michigan and Troy, New York, either EST or EDT is used. For Vancouver, British Columbia, either PST or PDT is used. The times when transitions to and from Daylight Savings time occur are based on a table, which is accurate for most of North America. The era for the clock function is relative to the starting time of the MTS task that is running the program. 15.9 mts.h - MTS Specific Routines A number of prototypes are defined in . It is important to use these prototypes so that the proper linkage is made to the appropriate MTS routines. Most of these routines are described in MTS Volume 3: System Subroutine Descriptions, Reference R1003. Some additional C routines are described below. Reference R1063 Page 92 15 THE MTS *C89 LIBRARY, HEADERS, AND MACROS 15.9.1 atoe Name: atoe Purpose: Translate ASCII to EBCDIC Include file: Prototype: char atoe (char *str, int len) Description: The function atoe converts the characters in the ASCII string pointed to by the argument str to their corresponding EBCDIC representation. It returns the last character after conversion and NULL if the string is empty. This function uses the ASCII to EBCDIC conversion table provided by the system. Note: This function is not required by the ANSI C Standard. Programs using this function may not be portable. See also: etoa 15.9.2 etoa Name: etoa Purpose: Translate EBCDIC to ASCII Include file: Prototype: char etoa (char *str, int len) Description: etoa converts the characters in the string pointed to by the argument str to their corresponding ASCII representation. It returns the last character after conversion and NULL if the string is empty. Each character is converted to the corresponding 7-bit ASCII character code, with the parity bit set to zero. Note: This function is not required by the ANSI C Standard. Programs using this function may not be portable. October 26, 1992 15.9 mts.h - MTS Specific Routines Page 93 15.9.3 query Name: query Purpose: Prompt for terminal input Include file: Prototype: int query (char *prompt, char *reply, int maxinplen) Description: query displays the string pointed to by prompt on the stdin stream, if stdin is attached to a terminal; otherwise, the prompt is not written. Then stdin is read with the input being truncated, if necessary, to the length maxinplen - 1, to allow for appending a '\0' to the end of the input to make it a string. The input string result is stored in the object pointed to by reply and the function returns. The length of the prompting string is limited to 79 characters, not including its '\0' terminator. If the string is longer, only 79 characters will be used for the prompt. query returns a zero if input was successfully done; it returns EOF, if either an end-of-file was encountered or an input error occurred. Note: This function is not required by the ANSI C Standard. Programs using this function may not be portable. Example: #include int ret; /* return value from query */ static char prompt []=" Input please:"; static int maxlen=100; /* maximum input length. */ char inparea[100] ; /* the input line */ ret=query (prompt ,inparea,maxlen) ; /* Prompt */ if (ret!=0) printf ("Unable to prompt and read.\n"); Reference R1063 Page 94 16 BSD 4. 3 UNIX ROUTINES 16 BSD4.3 UNIX Routines This section mainly goes over the UNIX routines and their expected be- haviour in this library. These fall into two categories: the kernel routines and the non- kernel routines. The kernel routines are described in chapter 2 of the UNIX Programmer's Reference Manual, April 1986 and the others are described in chapter 3. Many of the ANSI C Standard routines are also described in chapter 3 of the UNIX Programmer's Reference Manual, April 1986. The ANSI C Standard also has routines not mentioned in chapter 3. 16.1 Kernel Routines This section deals with the kernel routines of UNIX. Most of these routines go through a routine called syscall which connect the kernel and non- kernel levels of the library. This section describes how the behavior of *C89LIB is different from BSD4.3. If not otherwise specified, each routine is assumed to behave identically to BSD4.3. Full descriptions are given of extensions and implementation-defined features. The routines read, write, open, close and lseek are described in the section . 16.1.1 File Access - Querying and Modifying The routines that deal with file access (either specifying, modifying, or sim- ply retrieving access information) are the routines access, creat, open, chmod, and f chmod. For each of these routines that requires a "pathname," an MTS filename should be supplied instead. When an existing file is used, the access of the file is queried to determine whether a given type of use is allowed. This query determines the result of the routine access. READ access (in the MTS sense) for the current userlD, project, and program key is needed for read access in the UNIX sense. READ , WRITE/CHANGE and WRITE/EXPAND access (in the MTS sense) for the current userlD, project, and program key are needed for write access in the UNIX sense. October 26, 1992 16.1 Kernel Routines Page 95 READ access (in the MTS sense) for the current user ID, project, and the program key *MTS.RUN is needed for execute access in the UNIX sense. Note that it is possible to permit a file (using MTS mechanisms) such that its access controls are more complicated than can be represented by the routine access. Currently both creat and open ignore their third parameters. In UNIX, the access of a file is changed with chmod or f chmod, which is not implemented in *C89LIB. 16.1.2 Miscellaneous I/O Routines Various I/O related UNIX routines have been implemented: close, dup, dup2, f cntl, flock, f sync, ftruncate, getdtablesize, ioctl, lseek, read, readv, rename, sync, truncate, umask, unlink, write, writev. For each of these routines that requires a "pathname," an MTS filename should be supplied instead. sync sync causes an f sync to be performed on all files open by the current process. (It has no effect on other processes). fcntl For fcntl the F_GET0WN and F_SET0WN commands are not imple- mented. The FASYNC flag is not implemented. flock Unlike UNIX, file locking is mandatory; that is, reading a file causes the equivalent of flock (d, L0CK_SH) to be executed. Writing to a file or modifying it causes the equivalent of flock(d, L0CK_EX) to be executed. Also flock will allow L0CK_EX only if the file is permitted for write. A file is said to be open if some process has called open on the file and has not yet called close or is making some other use of the file. While a file is open, other processes may not unlink, rename, or chmod the file. If flock is called with LOCKJJN, the file will be unlocked but it will remain open. Reference R1063 Page 96 16 BSD 4. 3 UNIX ROUTINES rename, unlink If rename is called and the second file already exists, an error is returned and neither file is affected. With successful calls to rename and unlink, the old file is instantly unavail- able, and any attempts to do I/O on a file descriptor attached to the old file cause an error. The failure will occur only when actual I/O is done to the file and not when information is added to the buffer. Permission to rename or unlink a file is not as described in the UNIX Pro- grammer's Reference Manual, April 1986. A file can be renamed or unlinked if, and only if, the userlD which calls rename or unlink has DESTROY/RENAME access to the file. Normally only the owner of the file will have such access. This access can be changed by using the $PERMIT command or the MTS PERMIT subroutine. It cannot be changed by use of the chmod routine. 16.1.3 Sockets in *C89LIB The following socket-related routines have been implemented: accept, bind, connect, gethostname, getpeername, getsockname, listen, recvfrom, select, sendto, socket. The following socket routines have not been implemented. They set errno to EFAULT and return -1 when called: gethostid, getitimer, setitimer, getsockopt, recv, recvmsg, send, sendmsg, sethostid, sethostname,setsockopt, socketpair UDP datagram The UDP implementation on MTS can handle 1500 octets, the minimum required to be handled for Ethernet connections as per RFC 894. (Note: Seems to handle only 1472 bytes of actual data.) The general default maximum size required by internet is only 576 octets. When sending data to hosts that are not on the same Ethernet, some hosts in the route may have to fragment the data if the length of the datagram ex- ceeds their capacity, even if the intended receiver may be capable of handling the larger size. October 26, 1992 16.1 Kernel Routines Page 97 shutdown shutdown closes the TCP connection. The behaviour is the same as in UNIX BSD4.3 shutdown when the second parameter has value 2. The partial shutdowns available with how=0 or how=l, where how refers to the second parameter, are not currently supported by our implementation. 16.1.4 Library Utility Routines The following utility routines available in UNIX are implemented: _exit, getgid, getgroups, getegid, getpagesize, getpgrp, getpid, getppid, getpriority, getrusage, gettimeofday, getuid, geteuid, setpriority and syscall. It is assumed that the UNIX group ID is the same as the MTS project and the UNIX userlD is the same as the MTS userlD. It is assumed that the UNIX process ID and the UNIX process group are the same and are both the same as the MTS task number. It is assumed that the parent to all processes is process 0. The process group cannot be changed. syscall syscall is subject to the same constraints as the facility it calls. For example, syscall (SYS_read, . . .) has exactly the same behaviour as read( . . . ). getgroups When the routine getgroups is called, one group is returned and it is the same as the current group user ID. getpriority It is not possible to modify the priority of a process, getpriority always returns 0. setpriority setpriority returns (OK) but does not do anything. Reference R1063 Page 98 16 BSD 4. 3 UNIX ROUTINES setregid, setreuid The system will not allow the UNIX group ID or the UNIX userlD to be changed when setregid or setreuid is called. 16.1.5 Signals in *C89LIB The routines kill, killpg, sigblock, sigsetmask, and sigvec have been provided. When the routines kill and killpg are called, if the argument matches the current process, the call is processed as expected. If an attempt is made to signal another process with either kill or killpg, EPERM is returned. Signal routines have some MTS-specific features, which are described earlier under . The routines alarm, siginterrupt, sigpause, sigreturn, sigstack, wait, and wait3 are not available. 16.1.6 Other Unimplemented Kernel Routines The following routines are mainly of use to the superuser, and they set errno to EPERM and return -1 when called: acct, adjtime, chroot, mknod, mount, umount, quota, reboot, setgroups, sett imeof day, setquota, swapon, vhangup The following routines pertain to directories. Since MTS does not have directories, they always set errno to ENDTDIR and return -1 when called: chdir, link, mkdir, readlink, rmdir, symlink The following routines have not been implemented. They return -1 and set errno to the values indicated: execve, fork, profil — EPERM ptrace, utimes, vfork — EPERM October 26, 1992 16.2 N on- Kernel Routines Page 99 brk, sbrk — ENOMEM pipe — EFAULT chown, fchown — EPERM setrlimit, setpgrp — EPERM 16.2 Non-Kernel Routines This section deals with routines, header files, and macros other than the kernel routines. Unless otherwise specified, routines are assumed to be- have identically to BSD4.3. Full descriptions are given of extensions and implementation-defined features. Some of the routines mentioned are also ones required by the ANSI C Standard, so they may have been mentioned earlier. 16.2.1 I/O Routines printf , fprintf , sprintf , _doprnt, scanf , f scanf , and sscanf have been modified to conform to the ANSI C Standard. They all should be upward compatible with BSD4.3. The following routines and macros have been implemented. However the details of their behaviour are analogous to the behavior for read, write and lseek as explained in section 16.1, "Kernel Routines." printf, fprintf, _doprnt, scanf, fscanf , f close, fflush, ferror, feof , clearerr, f ileno, fread, fwrite, ftell, rewind, getc, getchar, fgetc, getw, gets, fgets, putc, putchar, fputc, putw, puts, fputs. 16.2.2 Signal The routine signal works essentially as it does in BSD 4.3; however, there are some differences. See the earlier descriptions. The routines alarm and siginterrupt do not work. Reference R1063 Page 100 16 BSD 4. 3 UNIX ROUTINES 16.2.3 Character Macros The following macros all assume an EBCDIC character set: isalpha, isupper, islower, isdigit, isxdigit, isalnum, isspace, ispunct, isprint, isgraph, iscntrl, isascii, toupper, tolower, toascii. 16.2.4 Other Implemented Routines The following math routines have been implemented: acos, asin, atan, atan2, cabs, cbrt, ceil, copysign, cos, cosh, erf, erfc, exp, fabs, floor, hypot, infnan, lgamma, log, loglO, pow, rint, sin, sinh, sqrt, tan, tanh. In addition, the following routines have been implemented: abort, abs, atof, atoi, atol, bcopy, bcmp, bzero, ffs, htonl, htons, ntohl, ntohs, crypt, setkey, encrypt, ctime, localtime, gmtime, asctime, timezone, ecvt, fcvt, gcvt, exit, frexp, ldexp, modf, fseek, gethostbyname, gethostbyaddr, gethostent, sethostent, endhostent, getopt, getpass, finite, inet_addr, inetjietwork, inet_ntoa, inet_makeaddr, inet_lnaof, inetjietof, insque, remque, malloc, free, realloc, calloc, alloca, mktemp, mkstemp, ns_addr, ns_ntoa, perror, sys_errlist, sys_nerr, psignal, sys_siglist, qsort, rand, srand, random, srandom, initstate, setstate, re_comp, re_exec, rexec, setbuf , setbuffer, setlinebuf , setjmp, longjmp, sleep, strcat, strncat, strcmp, strncmp, strcpy, strncpy, strlen, index, rindex, stty, gtty, swab, time, ftime, times, ttyname, isatty, ttyslot, ualarm, ungetc, usleep, utime, valloc, vlimit, vtimes. The assert macro and the macros defined in varargs.h are available. The symbols end, etext, and edata are available. October 26, 1992 16.2 N on- Kernel Routines Page 101 16.2.5 Unimplemented Routines The following routines are not implemented: dbm_open, dbm_close, dbm_f etch, dbm_store, dbm_delete, dbm_f irstkey, dbm_nextkey, dbm_error, dbm_clearerr, execle, execlp, exect, execv, execve, execvp, environ, getfsent, getfsspec, getfsfile, getfstype, syslog, openlog, closelog, setlogmask, system, res_mkquery, res_send, res_init, dn_comp, dn_expand, scandir, alphasort, setuid, seteuid, setruid, setgid, setegid, setrgid, rcmd, rresvport, ruserok, popen, pclose, pause, nice, nlist, initgroups, opendir, readdir, telldir, seekdir, rewinddir, closedir, execl, setfsent, endfsent, getgrent, getgrgid, getgrnam, setgrent, endgrent, getlogin, getnetent, getnetbyaddr, getnetbyname, setnetent, endnetent, getprotoent, getprotobynumber, getprotobyname, setprotoent, endprotoent, getwd, getdiskbyname, getpw, getpwent, getpwuid, getpwnam, setpwent, endpwent, setpwf ile, getservent, getservbyport, getservbyname, setservent, endservent, getttyent, getttynam, setttyent, endttyent, getusershell, setusershell, endusershell. The following math routines are not available: asinh, acosh, atanh, drem, expml, loglp, logb, jO, jl, jn, scalb, yO, yl, yn. None of the multiple precision arithmetic routines are available: madd, msub, mult, mdiv, pow, gcd, invert, rpow, msqrt, mcmp, move, min, omin, fmin, m_in, mout, omout, fmout, m_out, sdiv, itom. None of the plotting routines are available: openpl, erase, label, line, circle, arc, move, cont, point, linemod, space, closepl. None of the termcap routines are available: tgetent, tgetnum, tgetflag, tgetstr, tgoto, tputs. Reference R1063 Page 102 11 INCOMPA TIBILITIES WITH *C87 In addition, none of the following routines are available: dbminit, fetch, store, delete, f irstkey, nextkey, monitor, monstartup, moncontrol. Many UNIX-based programs use a library of terminal-independent routines named curses. These routines are not available with *C89LIB. The routines available in some unix systems in the library lib2648 are not available. 17 Incompatibilities With *C87 17.1 Incompatibilities with *C87LIB Most programs using *C87LIB will work unchanged with *C89LIB if all components of the program are recompiled. There are, however, a few dif- ferences between *C87LIB and *C89LIB: • eat_cookie is no longer needed and is not available. • The values of stdin, stdout, and stderr cannot be modified. The routine f reopen should be used to reassign these units. • f flush only moves the level 3 buffer to the kernel. To do the equivalent of what f flush did in *C87LIB, one needs to call both f flush and f sync. • The routines read, write, open, lseek, and close require small inte- gers to be used as file descriptors (similar to what UNIX expects). • f seek uses integer offsets instead of "magic cookies." • open does not assume binary mode. The mode is passed through the appropriate flag value, namely CLTEXT or -BINARY. • Many more routines are available. October 26, 1992 17.2 Incompatibilities with *C87 Compiler Page 103 • By default, I/O modifiers, line number ranges, and explicit concate- nation are not allowed. Any attempt to use these features will be treated as an error. $C0NTINUE WITH and $ENDFILE lines are never treated as special; they are always treated as data. *C87LIB allowed these features to be used when files where opened with the c option. This is not allowed in *C89LIB. There is a different method of allow- ing $C0NTINUE WITH and $ENDFILE lines, but it works on input only. This has been discussed under I/O. • When writing to files or devices other than terminal, tab characters are not interpreted by default. An ioctl call is required to cause interpretation of tab characters. • Carriage control is no longer supported via the use of the 'p' in the mode parameter for f open. This is done with an ioctl call on files or devices opened only for output. • C87INIT has been renamed C89INIT. • The behaviour of getenv has changed. 17.2 Incompatibilities with *C87 Compiler • *C89 does not predefine the macro _C87. It defines the macro _C89 instead. • *C89INCLUDE is used as the default macro library instead of *C87INCLUDE. This means by default, you have to use *C89LIB to get programs to execute correctly. • *C87 includes only when the option PAR=UNIX4.3 is used. *C89 always includes at the start of compilation. • Object code produced by *C89 must be run with *C89LIB. It cannot be run with *C87LIB. • The option RETCODE is no longer available. RETCODE users must rewrite their programs to use __retcode instead. • fortran is no longer accepted as an alias for __f ortran. The latter keyword must be used whenever FORTRAN linkage is required. Reference R1063 Page 104 ^ INCOMPATIBILITIES WITH *C87 • When two or more function declarations have conflicting function pro- totypes, *C89 will print an error message under circumstances that *C87 does not. • *C89 no longer allows declarations of two typedef s with the same name to occur in the same block. • In some complicated initializers, *C89 and *C87 may produce different code. • There are some subtle differences in the way the compiler determines whether an expression is signed or unsigned. This will have an effect only for the "<<", "*/." and "/" operators. • *C87 complained when non-portable usage was made of identifiers that began with an underscore. The rules on portability have changed since that part of the compiler was written; thus, *C89 uses different rules. • *C89 may produce error messages in circumstances that *C87 does not, and conversely, *C89 may compile a program without complaint when *C87 does produce an error message. • LONG defaults on. Hence by default, external identifiers are not trun- cated to 8 characters. • *C87 always truncated pseudo-registers to 8 characters, even if the LONG option was turned on. *C89 truncates pseudo-registers only if the LONG option is off. October 26, f992 Index . FALSE . , 44, 45 . TRUE . , 44, 45 *C87, 103 *C87INCLUDE, 103 *C87LIB, 102 *C89, 9 *C89INCLUDE, 64 *C89LIB, 39, 46, 63 *PRINT*, 79 SCONTINUE WITH, 75, 103 $DEBUG, 18, 23, 55 $ENDFILE, 10, 75, 103 $PERMIT, 96 $RUN, 9, 12 $SDS, 18, 23, 55 .cleanup, 51, 52 _doprnt, 99 .exit, 77, 78, 97 jioopen, 82 _sqrt, 70 .stack, 40, 50 __deff ile, 78 __fortran, 20, 32, 43, 44, 46, 50, 51, 84, 103 __pseudoregister, 20, 33 __prvbase, 20, 34 __retcode, 20, 45, 103 __SAVEAREA, 33 _TRUSTME, 50, 52, 80, 81 #def ine, 14, 34, 38, 54 #endif, 16 #include, 10, 11, 16, 17, 31, 68 #line, 18 #pragma, 12, 31 #undef , 24 31 bit, 13, 22 abort, 67, 86, 100 abs, 100 accept, 96 access, 94, 95 acct, 98 acos, 46, 100 acosh, 101 ad j time, 98 alarm, 98, 99 alloca, 100 alphasort, 101 AM0DE, 13 ANSI, 16 ANSI Standard C, 9 arc, 101 argc, 41 arge, 41 argv, 41 arithmetic functions, 101 arrays, 28 ASCII, 13, 26 asctime, 100 asin, 46, 100 as inn, 101 assembly language, 47, 51, 53 assert, 67, 100 , 55, 65, 67 atan, 46, 100 atanh, 101 atan2, 46, 100 atoe, 92 atof , 100 atoi, 100 atol, 100 ATTNTRP, 50 auto, 59 105 Page 106 INDEX bcmp, 100 bcopy, 100 binary mode, 76, 77, 102 bind, 96 bit-fields, 29, 30 BREAK, 57 brk, 99 BSD4.3 UNIX, 9, 22, 64, 94 bzero, 100 cabs, 100 calloc, 86, 100 carriage control, 79 case, 30 cbrt, 100 ceil, 100 char, 27, 29 CHARACTER, 44, 45 character graphics, 12 character sets, 26, 39, 67 chdir, 98 CHECKI0VER, 14, 74 CHECKSTACK, 14 chmod, 94-96 chown, 99 chroot, 98 circle, 101 clearerr, 99 clock, 91 close, 94, 95, 102 closedir, 101 closelog, 101 closepl, 101 compiler options, 10, 12 COMPLEX, 44, 45 C0MPLEX*16, 44, 45 C0MPLEX*8, 44, 45 concatenation, 81 connect, 96 const, 22 cont, 101 control characters, 78 control sections, 56 conversion, 92 copysign, 100 cos, 46, 100 cosh, 46, 100 creat, 77, 78, 94, 95 crypt, 100 csect, 56 CSECT, 57 ctime, 100 , 65, 67-69 curses, 84, 102 C87INIT, 103 C89INIT, 50, 51, 81, 103 dbminit, 102 dbm_clearerr, 101 dbm_close, 101 dbm_delete, 101 dbm_error, 101 dbm_fetch, 101 dbm_f irstkey, 101 dbm_nextkey, 101 dbm_open, 101 dbm_store, 101 debugging, 18, 23, 54, 55, 67 declarators, 30 DEFINC, 14 DEFINE, 14 delete, 102 DEPEND, 15, 17 dn_comp, 101 dn_expand, 101 documentation, 9 double, 28, 29, 42, 45, 48, 70 DOUBLE PRECISION, 43, 44 October 26, 1992 INDEX Page 107 drem, 101 dup, 95 dup2, 95 eat_cookie, 102 EBCDIC, 13, 39 EBCDIC to ASCII, 92 ecvt, 100 edata, 100 EDOM, 70 EEXISTS, 85 EINTR, 84 encrypt, 100 end, 100 endf sent, 101 endgrent, 101 endho stent, 100 endnetent, 101 endprotoent, 101 endpwent, 101 endservent, 101 endttyent, 101 endusershell, 101 EN0MEM, 85 EN0TDIR, 98 enum, 29, 30 environ, 101 EOF, 67, 93 EPERM, 98 ERANGE, 70 erase, 101 erf, 100 erf c, 100 errno, 61, 70, 84, 85, 96 , 65 error messages, 24, 25 errors, 37 ESPIPE, 85 etext, 100 etoa, 92 execl, 101 execle, 101 execlp, 101 exect, 101 execv, 101 execve, 101 execvp, 101 exit, 86, 100 exp, 46, 100 explicit concatenation, 75, 103 expml, 101 extern, 22 external names, 17, 26, 38 fabs, 100 FASYNC, 95 f cnmod, 94, 95 f chown, 99 f close, 99 f cntl, 95 fcvt, 100 feof , 99 f error, 99 fetch, 102 ff lush, 85, 99, 102 ff s, 100 fgetc, 99 fgetpos, 85 fgets, 99 file access, 94 file locking, 95 f ileno, 78, 80, 99 FILL, 15, 20, 35, 37, 55 finite, 100 f irstkey, 102 float, 28, 29, 42, 45, 48 , 65 floating point, 28 Reference R1063 Page 108 INDEX flock, 95 floor, 100 fmin, 101 fmod, 70 fmout, 101 f open, 77, 78, 80, 84, 103 fork, 99 fortran, 103 FORTRAN, 32, 43, 50, 103 fprintf , 85, 99 fputc, 99 fputs, 99 f read, 99 free, 100 f reopen, 78, 82, 84, 102 frexp, 100 fscanf , 85, 99 f seek, 75, 83, 100, 102 f stat, 76 f sync, 95, 102 ftell, 83, 85, 99 ftime, 91, 100 ftruncate, 76, 77, 95 fwrite, 99 F_GET0WN, 95 F_SET0WN, 95 gcd, 101 gcvt, 100 getc, 13, 99 getchar, 99 getdiskbyname, 101 getdtablesize, 95 getegid, 97 getenv, 86, 103 geteuid, 97 getfsent, 101 getfsf ile, 101 getf sspec, 101 getf stype, 101 getgid, 97 getgrent, 101 getgrgid, 101 getgrnam, 101 getgroups, 97 gethostbyaddr, 100 gethostbyname, 100 gethostent, 100 gethostid, 96 gethostname, 96 getitimer, 96 getlogin, 101 getnetbyaddr, 101 getnetbyname, 101 getnetent, 101 getopt, 100 getpagesize, 97 getpass, 100 getpeername, 96 getpgrp, 97 getpid, 97 getppid, 97 getpriority, 97 getprotobyname, 101 getprotobynumber, 101 getprotoent, 101 getpw, 101 getpwent, 101 getpwnam, 101 getpwuid, 101 getrlimit, 99 getrusage, 97 gets, 99 getservbyname, 101 getservbyport, 101 getservent, 101 getsockname, 96 getsockopt, 96 October 26, 1992 INDEX Page 109 gettimeofday, 91, 97 getttyent, 101 getttynam, 101 getuid, 97 getusershell, 101 getw, 99 getwd, 101 gmtime, 100 group id, 97 gtty, 100 header files, 10 htonl, 100 htons, 100 HUGE.VAL, 70 hypot, 100 I, 16, 66 I/O, 74, 76, 78, 80, 95, 96 I/O modifiers, 81, 103 identifiers, 26 implementation specifics, 25, 67, 70, 71, 84, 86, 91 implicit concatenation, 75, 103 include files, 16, 38 include libraries, 10, 14 index, 88, 100 inet.addr, 100 inet_lnaof, 100 inet_makeaddr, 100 inet_netof, 100 inet_network, 100 inet_ntoa, 100 infnan, 100 initgroups, 101 initstate, 100 INPUT, 11, 81 input (terminal, prompt), 93 insque, 100 int, 27, 29, 30, 34, 67 INTEGER, 43, 44 integer computations, 14 INTEGER*2, 43, 44 INTEGER*4, 43, 44 integers, 27 interactive I/O, 84 invert, 101 ioctl, 78, 80, 95, 103 isalnum, 68, 100 isalpha, 68, 100 isascii, 69, 100 isatty, 100 iscntrl, 68, 100 isdigit, 68, 100 isgraph, 68, 100 islower, 68, 100 isprint, 68, 100 ispunct, 68, 100 isspace, 68, 100 isupper, 68, 100 isxdigit, 68, 100 itom, 101 jn, 101 jO, 101 j 1,101 kill, 98 label, 101 LANG, 16 ldexp, 100 lgamma, 100 lib2648, 102 , 65 line, 101 line number ranges, 103 linemod, 101 link, 98 LIST, 15, 17 Reference R1063 Page 110 INDEX listen, 96 LDADNAME, 17, 20, 46, 57 local extensions, 31 , 65 localtime, 100 LDCK_EX, 95 LOCKJJN, 95 log, 46, 70, 100 logb, 101 LOGICAL, 43-45 logical I/O units, 10, 81 L0GICAL*1, 44 L0GICAL*4, 44 loglp, 101 loglO, 46, 70, 100 LONG, 17, 104 LONG, 26 long double, 28, 29, 48 long int, 27, 29 longjmp, 100 lseek, 75, 76, 83, 94, 95, 99, 102 lstat, 76, 78 madd, 101 makefiles, 15 malloc, 86, 100 , 46, 65, 70 mathematics, 70 mbtowc, 27 MC, 17, 26 mcmp, 101 mdiv, 101 memcmp, 87 min, 101 mkdir, 98 mknod, 98 mkstemp, 100 mktemp, 100 modf, 100 moncontrol, 102 monitor, 102 monstartup, 102 mount, 98 mout, 101 move, 101 msqrt, 101 msub, 101 MTS files, 75, 80 MTS system subroutines, 21, 32, 46, 84 , 47, 65, 91-93 MTSLINE, 18 MTSM0UNT, 47 MTSREAD, 47, 83, 84 MTSRENAME, 47 MTSREWIND, 47 MTSSYSTEM, 47 MTSTIME, 47 MTSWRITE, 47, 83, 84 mult, 101 multiple precision, 101 m_in, 101 m_out, 101 nextkey, 102 nice, 101 nlist, 101 N0ASCII, 13 N0CHECKI0VER, 13 N0CHECKSTACK, 14 N0DEFINC, 14, 66 N0DEPEND, 15 N0FILL, 15 N0LIST, 17 N0L0NG, 17, 26 N0MC, 17 N0MC, 26 N0MTSLINE, 18 October 26, 1992 INDEX Page 111 NOOBJECT, 18 NOOBJLIST, 18 NOOPT, 19 NOPORT, 19 NORENT, 22 NOSUMMARY, 23 NOSYM, 23 NOTEST, 23 NOWARN, 24 NOZEROARG, 25 ns.addr, 100 ns_ntoa, 100 ntohl, 100 ntohs, 100 NULL, 31, 92 OBJECT, 11, 15, 18 OBJLIST, 18 omin, 101 omout, 101 open, 76-78, 80, 94, 95, 102 open file, 95 opendir, 101 openlog, 101 openpl, 101 OPT, 19, 28 options, 10, 12 0_BINARY, 77, 78, 102 0_TEXT, 77, 78, 102 PAR field options, 10, 12 parameter passing, 42 parameters, 60 pause, 101 pclose, 101 PERMIT, 96 perror, 85, 100 PGNTTRP, 50 pipe, 99 plotting, 101 PLUS, 33, 47, 51 point, 101 pointers, 28 popen, 101 PORT, 19, 34 portability, 34 pow, 100, 101 pragma, 12 preprocessor, 30 PRINT, 11, 15, 17, 19, 81 printf , 13, 99 process group, 97 process id, 97 prof il, 99 prompt (terminal), 93 PROPER, 13, 20 PR0T0, 20 pseudo-registers, 20, 33, 61, 104 psignal, 100 ptrace, 99 putc, 99 put char, 99 puts, 99 putw, 99 qsort, 100 query, 93 quota, 98 raise, 71 rand, 100 random, 100 random access I/O, 83 RCALL, 20, 21, 33, 46 rcmd, 101 read, 76, 94, 95, 99, 102 READ, 84 readdir, 101 readlink, 98 readv, 95 Reference R1063 Page 112 INDEX REAL, 43, 44 REAL*4, 43, 44 REAL*8, 43, 44 realloc, 86, 100 reboot, 98 recv, 96 recvfrom, 96 recvmsg, 96 registers, 28, 53 remove, 84 remque, 100 rename, 85, 95, 96 RENT, 22 res_init, 101 res_mkquery, 101 res_send, 101 RETC0DE, 103 RETURN, 45 return codes, 11, 45 reverse, 90 rewind, 99 rewinddir, 101 rexec, 100 re_comp, 100 re_exec, 100 rindex, 89, 100 rint, 100 rmdir, 98 RMDDE, 22 rpow, 101 rresvport, 101 ruserok, 101 save area, 33, 48 sbrk, 99 scalb, 101 scandir, 101 scanf , 13, 99 sdiv, 101 SDS, 55 seekdir, 101 select, 96 send, 96 sendmsg, 96 sendto, 96 sequential files, 75 SERC0M, 11, 81 setbuf, 100 setbuffer, 100 setegid, 101 seteuid, 101 setfsent, 101 setgid, 101 setgrent, 101 setgroups, 98 sethostent, 100 sethostid, 96 sethostname, 96 setitimer, 96 setjmp, 100 , 65 setkey, 100 setlinebuf , 100 setlogmask, 101 setnetent, 101 segpgrp, 99 setpriority, 97 setprotoent, 101 setpwent, 101 setpwf ile, 101 setquota, 98 setregid, 98 setreuid, 98 setrgid, 101 setrlimit, 99 setruid, 101 setservent, 101 setsockopt, 96 October 26, 1992 INDEX Page 113 setstate, 100 settimeofday, 98 setttyent, 101 setuid, 101 setusershell, 101 short, 27, 29 shutdown, 97 sigblock, 74, 98 SIGCONT, 71 SIGILL, 74 siginterrupt, 98, 99 SIGKILL, 71 signal, 14, 71, 99 , 65, 71, 98 signed, 27, 30 sigpause, 98 sigreturn, 98 sigsetmask, 74, 98 sigstack, 98 SIGST0P, 71 sigvec, 98 SIGJDFL, 74 SIG.IGN, 74 sin, 46, 100 sinh, 46, 100 sleep, 100 socket, 96 socketpair, 96 space, 101 sprintf , 99 sqrt, 46, 70, 100 srand, 100 srandom, 100 sscanf , 99 stack, 40 stack size, 14, 40 STANDARD, 22 STANDARD+, 22 stat, 76, 78 static, 22 , 35, 65 , 65 stderr, 81, 82, 85, 102 stdin, 81, 82, 93, 102 , 65, 74, 94 , 65 stdout, 81, 82, 102 store, 102 strcat, 100 strchr, 88 strcmp, 87, 88, 100 strcpy, 100 strerror, 87 stricmp, 87, 88 string comparison, 87 , 65, 87-90 strlen, 100 strlwr, 89, 90 strncat, 100 strncmp, 100 strncpy, 100 strnicmp, 88 strrchr, 89 strupr, 89, 90 stty, 100 SUMMARY, 23, 40 supported signals, 71 swab, 100 swapon, 98 switch, 30 SYM, 13, 18, 56 symlink, 98 sync, 95 sys/errno.h, 85, 87 syscall, 94, 97 syslog, 101 system, 86, 101 sys.errlist, 85, 87, 100 Reference R1063 Page 11 4 INDEX sys_nerr, 100 sys_siglist, 100 tan, 46, 100 tanh, 46, 100 telldir, 101 termcap, 101 terminal (input, prompt), 93 terminal I/O, 84 TEST, 23 text files, 78 text mode, 76, 77 tgetent, 101 tgetflag, 101 tgetnum, 101 tgetstr, 101 tgoto, 101 time, 100 , 65, 91 times, 91, 100 timezone, 100 tmpf ile, 86 toascii, 69, 100 tolower, 68, 100 toupper, 68, 100 tputs, 101 truncate, 76-78, 95 ttyname, 100 ttyslot, 100 typedef , 34, 104 types, 30 ualarm, 100 UDP, 96 umask, 95 umount, 98 UNDEF, 24 ungetc, 100 union, 29 UNIX, 13, 22, 24 UNIX BSD4.3, 9, 22, 64, 94 UNIX incompatibility, 41 , 14, 64, 103 UNIX+, 22 UNIX4.3, 13, 24, 35, 37 unlink, 95, 96 unsigned, 27 usleep, 100 utime, 100 utimes, 99 valloc, 100 varargs.h, 100 va_arg, 35 va_end, 35 va_list, 35 va_start, 35 vf ork, 99 vhangup, 98 vlimit, 100 volatile, 30 vtimes, 100 wait, 98 wait3, 98 WARN, 24, 37 write, 76, 94, 95, 99, 102 WRITE, 84 writev, 95 yn, 101 yO, 101 yl, 101 ZERDARG, 20, 25 October 26, 1992