DECUS C LANGUAGE SYSTEM Runtime Support Library Reference Manual by Martin Minow Edited by Robert B. Denny This document describes the RSX/VMS/RSTS/RT11 DECUS C language system runtime support library. DECUS Structured Languages SIG Version of 15-Oct-81 NOTE This software is made available without any support whatsoever. The person responsible for an implementation of this system should expect to have to understand and modify the source code if any problems are encountered in implementing or maintaining the compiler or its run-time library. The DECUS 'Structured Languages Special Interest Group' is the primary focus for communication among users of this software. UNIX is a trademark of Bell Telephone Laboratories. RSX, RSTS/E, RT11 and VMS are trademarks of Digital Equipment Corporation. CHAPTER 1 INTRODUCTION The C support library contains three major groups of functions: o Functions called by the compiler to perform certain mathematical operations (such as floating-point multiply or function entrance) that are not performed in-line. o Functions that may be called by C programs to perform operations, such as copying a string, that are more efficiently performed by optimized assembly language subroutines. o An implementation of (most of) the Unix Standard I/O library. CHAPTER 2 THE STANDARD LIBRARY WARNING This version of the library is somewhat incompatible with previous versions of the Decus C compiler. This incompatibility allows greater compatibility with Unix Version 7, and the capability of generating global references and definitions containing the radix-50 '$' and '.' characters. All C programs should be linked together with the run-time support library. On systems that support logical device descriptors, this will generally be stored in the C: logical device/account. On RSX-11M, the library will be found in LB:[1,1]. To link a C program, proceed as follows: RSX TKB TKB> task/CP,map=objects,LB:C/LB TKB> / ENTER OPTIONS: TKB> STACK=2000 TKB> // RT11 R LINK *save,map=objects,C:SUPORT,C:CLIB/B:2000 *^C Note that, on RSX-11M, the task should be built checkpointable. This is automatic on RSTS/E and VMS emulated modes. On native RSX-11M, the task-builder may be rebuilt with '/CP' as the default. If the '/CP' switch is not given, the task may abort (no memory) when started. Stack extension is needed if subroutines locally allocate large amounts of data. On RT11, note that the '/B' (bottom) switch must be given to increase the size of the run-time stack. This is needed as local variables are allocated on the stack. If the stack size C Runtime Support Library Page 2-2 Reference Manual is not increased, the program may abort without any error message. The standard I/O interface header file is in C:STDIO.H (LB:[1,1]STDIO.H on native RSX-11M implementations) and should be included in all C programs as follows: #include 2.1 Introduction to Unix-style Stream I/O ____________ __ __________ ______ ___ This section presents an overview of the 'standard' I/O interface for C programs. These routines have proven easy to use and, while they do not provide the full functionality of RSX or RMS, they give the programer essentially all that is needed for everyday use. The discussion includes the following: - Opening and closing files - Reading data from files - Writing data to files Note that this file system is limited: files are sequential with only a limited amount of random-access capability. Also, little of the power of RMS/FCS is available. On the other hand, the limitations make C programs easily transportable to other operating systems. When a C program is started, three files are predefined and opened: stdin The 'standard' input file stdout The 'standard' output file stderr The 'standard' error file Stderr is always assigned to the command terminal. Stdin and stdout are normally assigned to the command terminal, but may be reassigned or closed when the program starts. 2.2 Opening and Closing Files _______ ___ _______ _____ The fopen and fclose functions control access to files. They are normally used as follows: #include /* Define standard I/O */ FILE *ioptr; /* Pointer to file area */ ... if ((ioptr = fopen("filename", "mode")) == NULL) error("Can't open file"); C Runtime Support Library Page 2-3 Reference Manual All information about an open file is stored in a buffer whose address is returned by fopen(). The buffer is dynamically allocated when the file is opened and deallocated when the file is closed. Its format is described under the heading IOV. The mode string contains flags defining how the file is to be accessed: r Read only w Write new file a Append to existing file (or write new) (Doesn't work on RT11 modes). It also defines some record-control information: n No newlines mode ('binary' files) u RSX: The user program allocates record buffers RT11: Console output is done using .ttyout If mode 'n' is specified, the RSX I/O routines do not interpret the end of a RMS logical record as defining the end of a human-readable line. This is necessary to process 'binary' information. On RT11, the I/O routines do not remove carriage-returns from input files, nor do they insert carriage-returns when newlines are output. Mode 'u' is treated differently on RSX and RT11. If specified on RSX the user maintains the file's record buffer. The program may only call the fget() and fput() routines. Each such call will be translated directly to an RMS/FCS GET$ or PUT$ call. (In RT11 mode, fput() may be used to write binary records which are subsequently read by fget(). The file should be opened with 'n' mode.) If mode 'u' is specified on RT11 mode when opening the console terminal, single character output will be performed (using the RT11 monitor routine .ttyout). If not specified, output will be one line at a time (using the monitor routine .print). The library initialization process opens stderr in mode 'u' and stdout in normal mode. This means that mixing I/O to both units will result in synchronization problems. To obtain single-character output on stdout, the program need simply execute: if (freopen("tt:", "wu", stdout) == NULL) error(""); The program calls fclose(ioptr) to terminate processing on a file. This closes the file and reclaims system-controlled buffer space. fmkdl(ioptr) may be called to close and delete an open file. C Runtime Support Library Page 2-4 Reference Manual 2.3 Reading Data from a File _______ ____ ____ _ ____ The simplest way to read a file is to call the getchar() or getc() routines which read the next character from a file. For example, the following program counts the number of characters in a file: #include main() { register int ccount; register int lcount; register int c; FILE *ioptr; if ((ioptr = fopen("foo.bar", "r")) == NULL) error("Cannot open file"); ccount = 0; lcount = 0; while ((c = getc(ioptr)) != EOF) { ccount++; if (c == '\n') lcount++; } printf("%d characters, %d lines.\n", ccount, lcount); } Other input routines include: gets Read a line from the standard input fgets Read a line from a file fgetss Read a line from a file, remove terminator ungetc Push one character back on a file fseek Position the file to a specific record These routines are used together with the ferr() and feof() functions which allow testing for error and end of file conditions, respectively. The package assumes that all error conditions are lethal and force end of file. 2.4 Writing Data to a File _______ ____ __ _ ____ There are several routines for data output which are directly analagous to the data input routines: putchar Write a character to standard output putc Write a character to a specified file puts Write a string to the standard outpt fputs Write a string to a specified file fputss Write a record to a specified file ftell Return record location (for fseek) In addition, the printf() or fprintf() routine is used to format C Runtime Support Library Page 2-5 Reference Manual and print data (as was shown in the previous example). Printf() is flexible, powerful, and easy to use; and is perhaps the single most important routine in the file system. 2.5 Interaction with the Operating System ___________ ____ ___ _________ ______ The support library attempts to provide a consistant operating system interface on several implementations of quite different operating systems. The possiblities include: o Native RT11 o Native RSX-11M or IAS o RT11 emulated on RSTS/E o RSX-11M emulated on RSTS/E o RSX-11M emulated on VAX/VMS This section mentions the inconsistencies and random bugs that are more or less intentionally present. 2.5.1 Logical Unit Numbers _______ ____ _______ RT11, RSTS/E, and RSX-11M use small integers to number all I/O channels. Unfortunately, the numbering is not consistent and channel usage differs among the various systems. This has resulted in several quirks: o On RT11, console terminal interaction uses the .ttyout and .print monitor functions. While no device is opened by the fopen() function, a channel number is reserved. o On RSX-11M, a channel must be allocated to the console terminal. When a C program starts, the 'command terminal' is opened on logical unit 1 and assigned to stderr. This is not done using the fopen() routine (although the stderr IOV structure is defined as if fopen() were called). Also, fclose() cannot close stderr. In addition to the standard I/O routines, there are two routines, msg() and regdmp(), that direct output to logical unit 1. These routines were used to debug the library, and are otherwise useful for disasters. On RT11, msg() and regdmp() use the .print monitor function. C Runtime Support Library Page 2-6 Reference Manual o On both systems, the first true files are stdin and stdout. These are opened on logical units 0 and 1 (RT11) or 2 and 3 (RSX). Code in fclose() double-checks that the logical unit number of the file being closed corresponds to the proper slot in the logical unit table. o Since the standard I/O routines know little about the operating system, they do not deal with certain special features. For example, on RT11, the 'user service routine' (USR) is used to open files. The file open routine does not attempt to locate IOV areas so that the USR does not swap over them. This can be a problem for very large 2.5.2 Wild-Card Files _________ _____ The fwild() and fnext() routines can be used to process 'wild-card' files. On RSX-11M and VMS/RSX emulation, the file name, extension, and/or file version may be expressed as '*' to indicate wild-card support. Due to restrictions in the RSX-11 Files-11 structure (ODS1), the ' ', ';0' and ';-1' version numbers will NOT function properly on native RSX-11. This means that '*.MAC' will not work, for instance. The algorithm in fwild() depends on the directory being sorted, as in the ODS2 file structure used on VAX/VMS. If you sort the directory to be used in an fwild() operation (use the SRD program available from DECUS with the /WB switch) in order of decreasing file version numbers, then the " ", ";0", and ";-1" versions will work. Wild-card devices, units, or UIC codes are not supported. Note that, on RSX11 emulated on VMS, the ';-1' (earliest version) requires special processing by the user program, as noted in the description of fwild(). On RSX-11M emulated on RSTS/E, the file name and/or extension may contain '*' or '?' wild-cards. Wild-card devices, units, or UIC (PPN) codes are not supported. On RT-11, the file name and/or extension may contain '*', '%' or '?' wild cards. The '?' wild-card is synonymous with '%'. Wild-card devices, or units are not supported. Since wild-card C Runtime Support Library Page 2-7 Reference Manual support is not an RT-11 system service, the file specification parsing and directory operations are handled by the C library fwild() and fnext() functions. The fwild/fnext module requires about 480 words of storage. Also, a file opened by wild-card uses a 1024 byte buffer, twice the normal size, which is shared between data and directory operations. 2.5.3 Memory allocation ______ __________ Memory is allocated using the malloc() function. It works correctly on all operating systems, expanding memory on RSX and RT11/RSTS. On 'native' RT11, all available memory is allocated by invoking the monitor .settop function with a '-2' argument. Neither library supports extended memory (PLAS) directives. The sbreak() routine may be used for permanent allocation of memory. Once memory has been allocated using sbreak(), it cannot be freed. 2.5.4 Global symbols ______ _______ Global symbols defined or referenced by C programs may cause unexpected parts of the operating-system support library to be loaded, with undesirable consequences. There are several aspects to this problem: o A symbol refered to by a C program which is not resolved by the object modules or libraries may cause some part of the system library to be loaded. For example, if a C program refers to the sqrt() function (which is not present in the standard library), the linker may attempt to load the function from the Fortran library. Since the Fortran sqrt() function contains a reference to the Fortran run-time error message routine, the load map may contain many strange global symbols. o Another problem occurs when a C program defines a global symbol that duplicates a global in the system library. This may prevent loading some necessary part of the system library, causing the link to fail with unresolved global symbols. For example, on RSX-11M emulated on RSTS/E V7.0, the following will fail: int eof; /* Global */ main () { } CHAPTER 3 LIBRARY FUNCTION DESCRIPTIONS This chapter contains descriptions of each of the C-callable runtime library functions. In most cases the I/O functions match those of UNIX V7 closely, with differences normally called out. For more information, consult "The C Programming Language" by Brian Kernighan and Dennis Ritchie (Englewood Cliffs, NJ: Prentice-Hall, ISBN 0-13-110163-3). C Runtime Support Library Page 3-2 $$ctim Convert $$rtim Buffer to Ascii 3.1 Convert $$rtim Buffer to Ascii _______ ______ ______ __ _____ ********** * $$ctim * ********** Usage char * $$ctim(buffer); struct TIME { int year; /* G.TIYR year - 1900 */ int month; /* G.TIMO Jan. = 1 */ int day; /* G.TIDA */ int hour; /* G.TIHR 00 .. 23 */ int minute; /* G.TIMI 00 .. 59 */ int second; /* G.TISC 00 .. 59 */ int tick; /* G.TICT 00 .. tsec-1 */ int tsec; /* G.TICP tick/second */ } buffer; dayofweek(buffer); struct TIME buffer; Description $$ctim() converts the time information in buffer such as returned by $$rtim() to a character string in the format: Sun Sep 16 01:03:52 1973\0\0 All the fields have constant width. Note that there are two trailing 's for the benefit of programs converted from Unix (where the year is followed by a ). $$ctim(0) returns the current time of day, calling $$rtim() internally. The format of the returned information is identical to the Unix function of the same name except that the Unix function has a trailing newline which is omitted here. dayofweek() returns the day of the week (Sunday = 0) for the date information in the argument buffer. Bugs There is no range checking on the information passed. C Runtime Support Library Page 3-3 $$init One-time initialization code 3.2 One-time initialization code ________ ______________ ____ ********** * $$init * ********** Usage Description When a C program is started, a command line is parsed to form the argv[] array and the standard input, output, and error files are opened. main() may be declared as follows: main(argc, argv) int argc; char *argv[]; { register int i; /* Arg counter */ for (i = 1; i < argc; i++) { printf("arg[%d] == %s\n", i, argv[i]); } } Note the following: On RSX11/M (even emulated), argv[0] will be set to the task name. On RT11 modes, argv[0] will be set to a dummy value. If no command line is passed to the program, it will prompt the task name (or "Argv") and read a line from the command terminal. To disable this, the user program may define a global flag as follows: $$narg = 1; main (argc, argv) { ... } If $$narg is initialized non-zero and no command line is passed to the program, or if the initialization sequence fails to read an argument, main() will be called with one argument. The command line prompt may be changed from the task name (or "Argv") by defining a global string as follows: C Runtime Support Library Page 3-4 $$init One-time initialization code char *$$prmt = "Command line prompt" main(argv, argc) { ... On Vax VMS, the program may be installed as a "foreign command" by a command such as: $ command :== $disk:[dir]filename and executed by typing: $ command arg1 arg2 Diagnostics Can't parse command line ?C-Standard input, [filename]: error text ?C-Standard output, [filename]: error text ?C-No memory. The "can't parse" message is given if the command line format is incorrect (because of unbalanced quotation marks, for example). The "standard input" or "standard output" messages are a user error if input or output are redirected and the associated files cannot be opened. The text should be self-explanatory. The "no memory" message suggests a severe case of program immensity. On RSX systems, it probably means that the task was not built /CP (checkpointable). All errors are fatal. Bugs On RSTS/RSX, command lines are limited to 80 bytes, although 128 byte commands are feasable. On VMS V3.0 and V3.1, the command name includes the expanded form of the command name. This means that long command name translations coupled with long argument strings may cause the total argument string to exceed 80 bytes. Such arguments will be truncated by the operating system without warning. The work-around is to make use of logical names: $ assign $disk[directory.subdirectory] bin $ program :== $bin:prog The expanded form of the "program" command is just C Runtime Support Library Page 3-5 $$init One-time initialization code "bin:prog". On VMS V3.0 and V3.1, the distributed RSX file service (FCS) refuses to open "stream Ascii" files. This module contains a dynamically-installed patch to the open routine. An error message will be printed if the patch cannot be installed correctly. The VMS3.0 compile-time switch enables this patch. There is also code in fopen.mac that is affected by this patch. It might be reasonable to make error messages non-fatal so $$init could be called by a user program. On RSX, the program aborts (by executing a BPT instruction) if the program fails to open stderr or obtain partition parameters. C Runtime Support Library Page 3-6 $$main Start of C programs 3.3 Start of C programs _____ __ _ ________ ********** * $$main * ********** Usage $$main:: /* Start of C programs */ extern int $$opsy; /* Operating system */ extern int $$rsts; /* Non-zero if RSTS/E */ extern int $$vms; /* Non-zero if VMS */ extern int $$pos; /* Non-zero if P/OS */ extern int $$uic; /* RSX: Default uic */ extern int $$stnd; /* Stack end point */ extern int $$scca; /* RT11: .scca control */ extern char $$task[]; /* RSX: task name */ extern int $$tick; /* Clock interrupt rate */ Description This module contains the run-time startoff for C programs. It intializes the C environment and calls the main() subroutine. On return from the main program, exit() is called to close all files and return to the operating system. The following globals are defined in this module: $$opsy Operating system unique value. This value is 7 on RT11, and set as per the GTSK$ directive on RSX-based systems: $$opsy Operating system unique value. This value is 7 on RT11, and set as per the GTSK$ directive on RSX-based systems: RSX11-D 0. RSX11-M 1. RSX11-S 2. IAS 3. RSTS/E V7 4. VMS 5. RSX11-M+ 6. RT11 7. P/OS 9. $$rsts This value is non-zero if the program is running on RSTS/E. It is zero if the program is running native RSX, RT11, P/OS or VMS compatibility mode. $$vms This value is non-zero if the program is running (in compatibility mode) on Vax VMS. It is zero if the program is C Runtime Support Library Page 3-7 $$main Start of C programs running native RSX, RT11, P/OS or on RSTS/E. $$pos This value is non-zero if the program is running on the Professional P/OS. It is zero if the program is running native RSX, RT11, or on RSTS/E or VMS. $$stnd The (top) end of the stack on entrance. $$scca On RT11, the .scca control word. This is needed to allow RSTS/E programs to trap end of file. $$task On RSX, the task name in Ascii. $$tick The clock interrupt rate. This is set at initialization on RT11 and on the first call to time() or ftime() on RSX. $$uic On RSX, the default UIC word from GTSK$. Diagnostics On RSX, the task aborts with a BPT if the standard error file did not open. Otherwise, explanatory error messages are printed. Bugs C Runtime Support Library Page 3-8 $$narg Define default for $$narg 3.4 Define default for $$narg ______ _______ ___ ______ ********** * $$narg * ********** Usage int $$narg = ; ... main() { ... } Description If no command line is provided when the program starts, the program will print a prompt on the command terminal, read one line and build the argv[] vector. If this is undesirable, include a global definition of $$narg in your C program as follows: int $$narg = 1; This will supress the command terminal read operation. The argv[] vector will be set to a dummy value. If the user program does not define $$narg, it will be defined so as to enable the prompt. Note that $$narg must be initilized at compilation time. It is tested by the initialization code before the main() program is called. Bugs C Runtime Support Library Page 3-9 $$prmt Null prompt pointer 3.5 Null prompt pointer ____ ______ _______ ********** * $$prmt * ********** Usage char *$$prmt = "Prompt string"; Description This pointer is checked in $$init and if the user has defined $$prmt then it will be used as the task prompt instead of using the task name on RSX or "Argv:" on RT-11. C Runtime Support Library Page 3-10 $$rtim Date and time conversion 3.6 Date and time conversion ____ ___ ____ __________ ********** * $$rtim * ********** Usage $$rtim(buffer); struct TIME { int year; /* G.TIYR year - 1900 */ int month; /* G.TIMO Jan. = 1 */ int day; /* G.TIDA */ int hour; /* G.TIHR 00 .. 23 */ int minute; /* G.TIMI 00 .. 59 */ int second; /* G.TISC 00 .. 59 */ int tick; /* G.TICT 00 .. tsec-1 */ int tsec; /* G.TICP tick/second */ } buffer; Description Stores the current time of day in the buffer. The format is compatible with the RSX11-M GTIM$ executive service. Bugs C Runtime Support Library Page 3-11 $$utim Convert $$rtim buffer to Unix time 3.7 Convert $$rtim buffer to Unix time _______ ______ ______ __ ____ ____ ********** * $$utim * ********** Usage long $$utim(buffer); struct TIME { int year; /* G.TIYR year - 1900 */ int month; /* G.TIMO Jan. = 1 */ int day; /* G.TIDA */ int hour; /* G.TIHR 00 .. 23 */ int minute; /* G.TIMI 00 .. 59 */ int second; /* G.TISC 00 .. 59 */ int tick; /* G.TICT 00 .. tsec-1 */ int tsec; /* G.TICP tick/second */ } buffer; Description The user calls $$rtim() to initialize a buffer. Then, $$utim will convert buffer contents to the number of seconds since Jan 1, 1970. Note: $$utim() does not compensate for local timezone or daylight savings time. Bugs This routine works only in the range: 1970 <= year < 2100 C Runtime Support Library Page 3-12 abort Abort program with a BPT trap 3.8 Abort program with a BPT trap _____ _______ ____ _ ___ ____ ********* * abort * ********* Usage abort() Description After closing all files, the program exits by executing a BPT trap. Bugs C Runtime Support Library Page 3-13 abs Integer absolute value 3.9 Integer absolute value _______ ________ _____ ******* * abs * ******* Usage abs(val) int val; Description Return absolute value of the integer argument. Bugs C Runtime Support Library Page 3-14 alloc Allocate memory 3.10 Allocate memory ________ ______ ********* * alloc * ********* Usage char * alloc(n); /* -1 if no space */ Description Allocate the requested number of bytes, returning a pointer to the first. The program image will be expanded as needed. alloc() returns -1 if the requested space could not be allocated. free() is used to return the buffer to free space. See also the description of malloc(), realloc() and sbrk(). Diagnostics Bugs alloc() is obsolete. Use malloc() for new programs. C Runtime Support Library Page 3-15 ascr50 Ascii to Radix-50 conversion 3.11 Ascii to Radix-50 conversion _____ __ ________ __________ ********** * ascr50 * ********** Usage ascr50(count, input, output) int count; int *output; char *input; Description Convert 'count' characters from ascii to Radix 50. If there aren't a multiple of 3 characters, blanks are padded on the end. The ascii string is moved to the output when finished. The input and output areas may be the same since three input characters are read for every two bytes of output. Bugs C Runtime Support Library Page 3-16 atod Convert Ascii to double floating 3.12 Convert Ascii to double floating _______ _____ __ ______ ________ ******** * atod * ******** Usage double atod(buffer) char *buffer; Description Converts a double-precision floating point number written in scientific notation from ASCII to a "double" number. The BNF for numbers which can decoded by this routine follows: := := | | := | . | . | . := | := { E | e | D | d } := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 := + | - | The conversion stops on the first non-legal character. (Note: if this routine is declared type char *, it will return a pointer to the first non-legal character.) Bugs C Runtime Support Library Page 3-17 atof Convert Ascii to double floating 3.13 Convert Ascii to double floating _______ _____ __ ______ ________ ******** * atof * ******** Usage double atof(buffer) char *buffer; Description Converts a double-precision floating point number written in scientific notation from ASCII to a "double" number. The BNF for numbers which can decoded by this routine follows: := := | | := | . | . | . := | := { E | e | D | d } := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 := + | - | The conversion stops on the first non-legal character. (Note: if this routine is declared type char *, it will return a pointer to the first non-legal character.) Bugs C Runtime Support Library Page 3-18 atoi Convert Ascii to integer 3.14 Convert Ascii to integer _______ _____ __ _______ ******** * atoi * ******** Usage atoi(p) char *p; Description Convert string to integer. No data checking is performed. The conversion stops at the first non-integer. Leading spaces, tabs, plus-signs and/or Description Convert string to integer. No data checking is performed. The conversion stops at the first non-integer. Leading spaces, tabs, plus-signs and/or newlines are ignored. The integer may be preceeded by a minus sign. Bugs C Runtime Support Library Page 3-19 atol Convert Ascii to long 3.15 Convert Ascii to long _______ _____ __ ____ ******** * atol * ******** Usage long atol(p) char *p; Description Convert string to integer. No data checking is performed. The conversion stops at the first non-integer. Leading spaces, tabs, plus-signs and/or newlines are ignored. The integer may be preceeded by a minus sign. Bugs C Runtime Support Library Page 3-20 brk Change memory allocation 3.16 Change memory allocation ______ ______ __________ ******* * brk * ******* Usage char * brk(addr); int *addr; Description brk() sets the run-time library's "top of memory" pointer to addr. This value should have been returned by a previous call to sbrk(). Intervening calls to malloc() or file open routines may cause memory to be corrupted by calling brk(). Diagnostics Returns 0 if the brk() argument is reasonable. Returns -1 if it is greater than the current top of memory. (Use sbrk() to increase memory allocation.) Bugs C Runtime Support Library Page 3-21 call Call (Fortran) subroutine from C 3.17 Call (Fortran) subroutine from C ____ _________ __________ ____ _ ******** * call * ******** Usage return_value = call(routine, count, &arg1, ... &argN); extern int routine(); /* PDP-11 function name */ int count; /* Number of arguments */ Description C Library user-callable interface between C programs and subroutines which follow the standard PDP11 calling sequence. Note that call() saves and restores registers r2-r5. The arguments are as follows: routine The name of the PDP11 routine to be called. count The number of arguments in the calling sequence. arg1 The first argument. For example: extern int sort(); int data_to_sort[NDATA]; int ndata = NDATA; call(sort, 2, &data_to_sort, &ndata); Note that, if the called function returns some other datatype such as a long, the routine and call() must be correctly declared: long call(); long myfun(); long larg; long result; result = call(myfun, 1, &larg); If call() is being used to return several different datatypes, type coersion may be effective: C Runtime Support Library Page 3-22 call Call (Fortran) subroutine from C int call(); long myfun(); long larg; long result; result = (long)call(myfun, 1, &larg); Bugs: WARNING: watch out for trouble if the PDP-11 routine does any I/O. Floating-point data return has not been implemented. C Runtime Support Library Page 3-23 callc Call (Fortran) subroutine from C 3.18 Call (Fortran) subroutine from C ____ _________ __________ ____ _ ********* * callc * ********* Usage integer callc ivalue = callc(routine, arg1, ... argN) Description User-callable interface between Fortran programs and subroutines written in C. The arguments are as follows: routine The name of the C routine to be called. arg1 The (location of the) first argument. For example: call callc(sort, table, nelement) Bugs There will be I/O library conflicts since C files have not been initialized. The following problem will occur if a C subroutine is called from a Fortran main program: The C subroutine refers to the save register routine (CSV$) which refers to the C main program. This pulls in a large amount of I/O dependent code, which may cause conflicts. What is worse is that there will be two main programs. It is therefore recommended that there be a C main program that calls Fortran subroutines that may, in turn, call C subroutines. The programmer can also define a dummy program that resolves the globals referenced by CSV$ or modify callc.mac to provide the necessary globals. C Runtime Support Library Page 3-24 caller Return name of profiled caller 3.19 Return name of profiled caller ______ ____ __ ________ ______ ********** * caller * ********** Usage char * caller(); Description If the routine which called the current function was compiled using the profile option, caller() returns a pointer to the name of the calling function. If the calling function was not compiled with profiling enabled, a pointer to the null string is returned. Example: foo() { foobar(); } foobar() { extern char *caller(); printf("foobar was called by %s\n", caller()); } Bugs C Runtime Support Library Page 3-25 calloc Allocate and Initialize Memory 3.20 Allocate and Initialize Memory ________ ___ __________ ______ ********** * calloc * ********** Usage char * calloc(n, m); /* NULL if no space */ int n; /* Number of elements */ int m; /* Size of an element */ Description Calloc() allocates space for n elements, each m bytes long. On return, the space is zero'ed. The program image will be expanded as needed. If the requested space cannot be allocated, calloc() returns NULL. See also the description of malloc(), realloc() and sbrk(). The space is returned by calling free(). Diagnostics Bugs C Runtime Support Library Page 3-26 calltr Trace Path to the Caller 3.21 Trace Path to the Caller _____ ____ __ ___ ______ ********** * calltr * ********** Usage calltrace(outfd); FILE *outfd; Description calltrace() prints the calling path (from main()) to the routine that called calltrace()) on the indicated file. The path is printed on one line as: [ main sub1 sub2 ] If a subroutine within the path was not compiled with profiling, or does not start with a call to the C register register save routine, it will be printed as (where is the octal address of the entry to the routine). Note that the last entry on the line is the routine that invoked calltrace(). A call trace will be printed on exit if profiling is enabled and the program aborts or calls error(). Bugs C Runtime Support Library Page 3-27 clearerr Clear file error flags 3.22 Clear file error flags _____ ____ _____ _____ ************ * clearerr * ************ Usage clearerr(iop); FILE *iop; Description Clear the error flags for an open file. This may be needed for interaction with the user's console terminal. Bugs C Runtime Support Library Page 3-28 concat Concatenate strings 3.23 Concatenate strings ___________ _______ ********** * concat * ********** Usage char * concat(out, in0, in1, ..., inN, 0); char *out; char *in0, in1, ... inN; Description Concat concatenates the argument strings. It returns a pointer to the first byte of out. Bugs C Runtime Support Library Page 3-29 copy Copy a given number of bytes 3.24 Copy a given number of bytes ____ _ _____ ______ __ _____ ******** * copy * ******** Usage char * copy(out, in, nbytes) char *out; /* Output vector */ char *in; /* Input vector */ unsigned int count; /* Bytes to copy */ Description Copy the indicated number of bytes from the input area to the output area. Return a pointer to the first free byte in the output area. The copying will be faster if out and in are either both even or both odd addresses. Bugs C Runtime Support Library Page 3-30 cpystr String copy 3.25 String copy ______ ____ ********** * cpystr * ********** Usage char * cpystr(out, in); char *out; char *in; Description Copy "in" to "out". Return a pointer to the end of out. This allows the following usage: char *ptr; char buffer[BUFSIZ]; extern char *cpystr(); ptr = cpystr(buffer, text); ptr = cpystr(ptr, more_text); The above sequence appends more_text to the copy of text already moved into the buffer. Bugs C Runtime Support Library Page 3-31 csv$ C register save and restore 3.26 C register save and restore _ ________ ____ ___ _______ ******** * csv$ * ******** Usage jsr r5,csv$ ... jmp cret$ Description C program Run-time Environment Each C subroutine starts with a call to CSV$ and exits by jumping to CRET$. Upon exit, the stack need not be equal to its value on entrance. During the execution of all C subroutines, register R5 points to the current "environment." Within a subroutine, it appears as follows: _______________ | | SP -> | 1st loc. var. | -10(R5) C$AUTO-2(R5) |_______________| | | | Saved R2 | -6(R5) |_______________| | | | Saved R3 | -4(R5) |_______________| | | | Saved R4 | -2(R5) |_______________| | | R5 -> | Saved R5 | |_______________| | | | Return add. | +2(R5) |_______________| | | | First arg. | +4(R5) C$PMTR+0(R5) |_______________| | | | Second arg. | +6(R5) C$PMTR+2(R5) |_______________| Within a subroutine, Registers R0-R4 and the top of the C Runtime Support Library Page 3-32 csv$ C register save and restore stack, (sp) are available for use. Registers R0 and R1 are not preserved by subroutines and may be used to pass a return value. R5 must not be modified by a subroutine. All variable addressing must be done by offsets to R5. Subroutine arguments must be accessed by reference to C$PMTR. Subroutine local variables must be accessed by reference to C$AUTO. This permits modification of calling sequences without rewriting all subroutines. CSV$ refers to global symbol $$main to call the run-time startup program from the (RSX) library. Bugs C Runtime Support Library Page 3-33 ctime Convert time value to ascii 3.27 Convert time value to ascii _______ ____ _____ __ _____ ********* * ctime * ********* Usage #include char * ctime(tvecp) long *tvec; /* Time value pointer */ char * asctime(tm) struct tm *tm; /* Time buffer pointer */ Description ctime() converts a time value, as returned by time() to an ascii string. For compatibility with previous versions, ctime(0) obtains and converts the current time of day. Note, however, that ctime(0) is not portable. asctime() converts a time vector, as returned by localtime() to an ascii string. The string is statically allocated. It has the format Sun Sep 16 01:03:52 1973\n\0 012345678901234567890123 4 5 0 1 2 All the fields have constant width. To remove the trailing newline, just: char *tp; extern char *ctime(); int tvec[2]; time(&tvec); /* Get time */ tp = ctime(&tvec); /* in Ascii */ tp[24] = '\0'; /* Fix newline */ Bugs There is no range checking on the information passed. C Runtime Support Library Page 3-34 delete Delete a named file 3.28 Delete a named file ______ _ _____ ____ ********** * delete * ********** Usage delete(filename) char *filename; Description Delete the named file. Returns 1 on success, 0 on error (such as file not found). If an error occurs, $$ferr can be checked for the error code. On RSX modes, the filename as passed need not include an explicit version number. If none is provided, file.nam;0 will be deleted. Note that the filename returned by fgetname() always includes an explicit version. On RT modes, the only error ever returned is "File not found". Bugs On RSX/VMS, the file must be in the user's current ("SET DEFAULT") directory. On RSTS, "SY0:" cannot be distinguished from "SY:". C Runtime Support Library Page 3-35 envsave Multi-level function return 3.29 Multi-level function return ___________ ________ ______ *********** * envsave * *********** Usage int * envsave(); envreset(frame, hval, lval) int *frame; /* Frame pointer */ int hval; /* High-order return */ int lval; /* Low-order return */ Description These functions permit a multi-level return from a C function to one of its dynamic ancestors in the stack. Envsave() returns the address of the frame of its caller. Later calls to envreset() with this pointer as an argument will create the illusion that the last function invoked by the caller of envsave() returned directly with a value equal to the parameter(s) to envreset(). Envreset() simulates a return to the function whose frame pointer matches frame (the result of a previous call to envsave()). Envreset() may be made to look as if it is returning a one or two word value. If only a single integer value is passed in addition to envreset(), it looks as if a 1-word value was returned. If two integers (or equivalently, a long) are specified, it looks like a long is returned. Thus any 1 or 2 word value may be returned because of the lax type checking in C. It is catastrophic to attempt to return to a function which has itself already returned!!! The following illustrates use of envsave() and envreset(): int *save_frame; process() { ... save_frame = envsave(); if (subroutine()) { C Runtime Support Library Page 3-36 envsave Multi-level function return /* * Success */ } else { /* * Failure */ } } subroutine() { /* * Abort on error */ if (...) envreset(save_frame, 0) /* * Success */ return(1); } When subroutine() detects an error, it calls envreset() to return to the caller of process(), passing a "failure" flag. Bugs If the caller of envsave() has already returned, disaster will result. It is highly recommended that programs use setjmp/longjmp instead. C Runtime Support Library Page 3-37 error Error exit from C programs 3.30 Error exit from C programs _____ ____ ____ _ ________ ********* * error * ********* Usage error(format, arglist); /* Fatal error exit */ Description An error message is written to stderr and the program exits. If profiling was enabled, a subroutine call trace will be written to stderr. The exit status, $$exst, will be set to "error". Diagnostics Bugs C Runtime Support Library Page 3-38 exit Exit from C programs 3.31 Exit from C programs ____ ____ _ ________ ******** * exit * ******** Usage exit(status); /* Exit, no return */ exits(status); /* Exit with status */ $$fail(); /* Immediate exit */ extern int $$exst; /* Exit status value */ Description On exit, the following sequence occurs: 1. The user-supplied wrapup() function is called. 2. User-supplied finalizers are called. 3. Profiles (if requested) are printed. 4. All files are closed. 5. The program exits to the operating system. By calling exits() with an appropriate value, the program can pass an exit status code to the operating system monitor. The RT11 and RSX11 monitors define exit status codes differently; the value passed to exits() is not checked for consistancy. RT11 RSX Meaning 1. 1. IO_SUCCESS -- no message is printed 2. 0. IO_WARNING -- minor error 4. 2. IO_ERROR -- serious error 8. 4. IO_FATAL -- severe error Calling exit() with some other value is equivalent to calling exits(IO_SUCCESS). This is compatible with Unix programs that exit by calling exit() without parameters. Note that the program may also set a value into $$exst and exit via exit(): extern int $$exst; ... $$exst = IO_WARNING; exit(); C Runtime Support Library Page 3-39 exit Exit from C programs If the program calls, or jumps to, $$fail, it will immediately exit to the operating system without closing files, calling wrapup() or finalizers, or writing a profile file. Diagnostics Bugs C Runtime Support Library Page 3-40 fabs Floating absolute value 3.32 Floating absolute value ________ ________ _____ ******** * fabs * ******** Usage double fabs(val) double val; Description Return absolute value of a floating argument. Bugs C Runtime Support Library Page 3-41 fclear Clear file error flags 3.33 Clear file error flags _____ ____ _____ _____ ********** * fclear * ********** Usage fclear(iop); FILE *iop; Description Clear the error flags for an open file. This may be needed for interaction with the user's console terminal. Bugs C Runtime Support Library Page 3-42 fclose Close a currently-open file 3.34 Close a currently-open file _____ _ ______________ ____ ********** * fclose * ********** Usage fclose(iop); FILE *iop; Description Close the file. Returns 0 if ok, -1 if an error. The error code is saved in $$ferr. Note that stderr is never closed. On RT11-mode, the last block of a disk file which was open for output is filled with nulls. Bugs C Runtime Support Library Page 3-43 feof Test for end of file 3.35 Test for end of file ____ ___ ___ __ ____ ******** * feof * ******** Usage feof(iop); FILE *iop; Description Return 1 if end of file on iop, else zero. Bugs C Runtime Support Library Page 3-44 ferr Test for file error 3.36 Test for file error ____ ___ ____ _____ ******** * ferr * ******** Usage ferr(iop); FILE *iop; Description Return 1 if an error has been seen on the indicated file. Bugs Obsolete, use ferror() instead. C Runtime Support Library Page 3-45 ferror Test for file error 3.37 Test for file error ____ ___ ____ _____ ********** * ferror * ********** Usage ferror(iop); FILE *iop; Description Return 1 if an error has been seen on the indicated file. Bugs C Runtime Support Library Page 3-46 fflush Flush output buffers 3.38 Flush output buffers _____ ______ _______ ********** * fflush * ********** Usage fflush(iop); FILE *iop; Description Flush output buffers. This routine actually does I/O. $$ferr is set if anything unexpected happens. Bugs C Runtime Support Library Page 3-47 fget Input a binary record 3.39 Input a binary record _____ _ ______ ______ ******** * fget * ******** Usage fget(buffer, maxbytes, iop); char *buffer; int maxbytes; FILE *iop; Description Read a record from the indicated file. Maxbytes is the maximum record size. On RSX, the record is read by a direct call to the file service GET$ routine. Your program must not mix calls to fget() with calls to other I/O routines, such as fgets(). On RT11, the file must have been written by fput(). The actual number of bytes read is returned. Use feof() to test for end of file. Fget() is not present on Unix standard I/O libraries. Bugs C Runtime Support Library Page 3-48 fgetname Convert file name to Ascii 3.40 Convert file name to Ascii _______ ____ ____ __ _____ ************ * fgetname * ************ Usage char * fgetname(iop, buffer); FILE *iop; char *buffer; Description Convert the file name to Ascii and put it in the buffer. On native RSX (and RSTS/E emulation) the device name, file name, file type, and version are converted to Ascii. The UIC is converted if it was specified and differs from the job's default UIC. (Note that on VMS compatibility mode, the UIC is unavailable.) The version is converted to octal on native RSX and to decimal on VMS emulation. The result should be sufficient to delete the file. On RT11 modes, the file name passed to fopen() is copied to the buffer without further processing. If the file was opened by an fwild()/fnext() sequence, the correct file name is returned. (On RSTS/E, the PPN is returned as well.) Fgetname() returns a pointer to the buffer argument. Fgetname() is present in the Vax-11 C support library, but is not generally present on Unix implementations. Note that fgetname() returns a fully-qualified file specification including, where possible, the disk, directory, and version of the file. If only the actual file name is needed, the following code segment may be executed. As shown, it writes the file name and filetype (extension) to a global "buffer". getfilename(fd, buffer) FILE *fd; register char *buffer; { register char *tp; register char c; C Runtime Support Library Page 3-49 fgetname Convert file name to Ascii fgetname(fd, buffer); /* * Skip over node and device name */ while ((tp = strchr(buffer, ':')) != NULL) strcpy(buffer, tp + 1); /* * Skip over [UIC] or [PPN] if present */ c = EOS; switch (*tp) { case '[': c = ']'; break; case '(': c = ')'; break; case '<': c = '>'; break; } if (c != EOS && (tp = strchr(buffer, c)) != NULL) { strcpy(buffer, tp + 1); /* * Don't include version */ if ((tp = strchr(buffer, ';')) != NULL) *tp = EOS; } Bugs Various operating systems behave differently. C Runtime Support Library Page 3-50 fgets Read a string from a file 3.41 Read a string from a file ____ _ ______ ____ _ ____ ********* * fgets * ********* Usage char * fgets(buffer, maxbytes, iop); char *buffer; int maxbytes; FILE *iop; char * fgetss(buffer, maxbytes, iop); char *buffer; int maxbytes; FILE *iop; Description Fgets() reads a string into the buffer from the indicated file. Maxbytes is the maximum number of bytes to read. The string is terminated by a newline character, which is followed by a null. Fgets() normally returns buffer. It returns NULL on end of file or error. If the line being read is maxbytes long or longer, no newline is appended. Fgetss() is identical to fgets() except that the terminating newline is replaced by a null. (This is compatible with gets(), but fgetss() is not present in the Unix standard library.) Note that fgets keeps the newline, while fgetss() and gets() delete it. To delete the newline after executing fgets(), execute the following: buffer[strlen(buffer) - 1] = 0; Bugs Note that fgets() returns the next logical text line. Certain RSX-11 or RMS file formats, such as Runoff output files or task-builder load maps, often have multiple text lines packed into one logical record. Fgets() processes these correctly. Note, however, that the record location, as returned by ftell(), is the location of the physical record, as returned by the operating system. The "obvious" ftell/fgets sequence, C Runtime Support Library Page 3-51 fgets Read a string from a file rfa = ftell(fd); fgets(text, sizeof text, fd); will not work properly if multiple text lines are packed into one RSX-11 record. These routines do not understand some of the more baroque RSX-11 file formats, such as "Fortran carriage control" or VMS print-file format. The typeout program in the tools package, T.C, shows an example of complete record deblocking and "seek to byte" procedure. C Runtime Support Library Page 3-52 fileno Get logical unit number 3.42 Get logical unit number ___ _______ ____ ______ ********** * fileno * ********** Usage fileno(iop) FILE *iop; Description Return the logical unit number associated with the file. (On RT11, the channel number is returned.) Bugs C Runtime Support Library Page 3-53 fill Fill a Block of Memory With a Character 3.43 Fill a Block of Memory With a Character ____ _ _____ __ ______ ____ _ _________ ******** * fill * ******** Usage fill(addr, ch, count); char *addr; char ch; unsigned int count; Description: Fill the count characters of memory beginning at addr with the character ch. Note: To fill with zero bytes, you can use zero(), which is slightly faster. Bugs C Runtime Support Library Page 3-54 flun Get logical unit number 3.44 Get logical unit number ___ _______ ____ ______ ******** * flun * ******** Usage flun(iop) FILE *iop; Description Return the logical unit number associated with the file. (On RT11, the channel number is returned.) Bugs Obsolete -- use fileno() for transportability. C Runtime Support Library Page 3-55 fmkdl Mark file for deletion -- obsolete 3.45 Mark file for deletion -- obsolete ____ ____ ___ ________ __ ________ ********* * fmkdl * ********* Usage fmkdl(iop); FILE *iop; Description fmkdl() closes and deletes the specified file. Returns 0 on success, -1 on error. This routine is obsolete. New programs should call delete() instead. To delete an existing file, the program may execute: char buffer[80]; ... fgetname(iop, buffer); fclose(iop); delete(buffer); Bugs On RT11, the job is aborted with an error message if the file wouldn't parse. $$ferr is set to "file not found" if the program tries to delete something (like the line-printer) that it shouldn't. Note that RT11 does not flush the last buffer before deleting the file. On VMS compatibility mode, the file must be in the user's default directory. C Runtime Support Library Page 3-56 fopen C library file opener 3.46 C library file opener _ _______ ____ ______ ********* * fopen * ********* Usage FILE * fopen(name, mode); char *name; /* File to open */ char *mode; /* Open modes */ FILE * freopen(name, mode, iop); char *name; /* File to open */ char *mode; /* Open modes */ FILE *iop; /* I/O pointer */ Description Fopen opens a new or existing file in the indicated mode: r Read the existing file sequentially w Create and write the file sequentially a Append to the file n Not record oriented u RSX-mode "unbuffered i/o" RT11-mode: use .ttyin and .ttyout Either "r", "w", or "a" must be given. "n" and "u" are optional. "n" should be given for "binary" files. Note that "n" mode will create fixed-block records on RSX systems. Append mode does not work on native RT11. Note that "n" and "u" are not compatible with other Unix systems. Implementation Details On RSX, "u" mode files will be created with the "variable-length" attribute. On RSTS/RSX emulation, text files (neither "n" nor "u" specified) will be created with "stream" attribute. On RSX, if the record type bits in the record attribute byte (F.RATT in the FDB) is zero, the file will be read as if the "n" was specified. Note that, if the file contains carriage-return line-feed sequences, the entire C Runtime Support Library Page 3-57 fopen C library file opener sequence will be passed to the user's program. If record attributes are understandable, the carriage-return will be deleted from sequences. On RSX, if the "file" is being opened for write to the same device/unit as stderr (the user's "command console), the character stream is diverted to stderr. This avoids synchronization problems by funnelling all output through the same buffer. In addition, output to any terminal device is done via QIO's to the terminal, IO.WLB for normal mode, IO.WAL for "n" mode. On RT11, when opening a file for writing, a specific block allocation may be included in the Ascii file specification following standard RT-11 syntax: "DKn:file.nam[nnn]" where the "nnn" specifies the number of blocks to allocate to the file. After opening a file successfully, the actual file size (or number of blocks allocated) will be found in (FILE *)fd->io_size. If the RT11 library decides that the file is really the user's command terminal, single-character I/O will be performed (by calling .ttyin and .ttyout). Note that the "special-mode" bits must be set in the Job Status Word by the program if it requires true single-character or immediate return input. Output to the terminal will be performed without buffering, which is useful for screen updating, but otherwise expensive. Fopen() returns NULL on errors -- $$ferr gets an error code. On RT11, this will be a RSTS/E compatible code (described in iov), while on RSX, this will be the FCS error code. On RT11, the file name pointed to by the "io_name" field of the iov is either the file name string as passed to fopen() or an ascii string reconstructed from the 4-word Rad50 device block if the file was opened as part of a fwild/fnext sequence. By saving the ascii string, RSTS/E is able to re-parse logical device names and PPN's, which are not present on native RT11. On VMS compatibility mode, the device and directory of the file name argument are saved in the iov "io_dname" field for use by fgetname(). Note that "no buffer space available" (IE.NBF or E$$NSP) and "invalid lun" (IE.ILU or E$$NOC) may be generated by fopen. On RT11, if the file cannot be opened because the user's program has already opened the channel, an E$$ILU error will be returned. The same file may not be used for both reading and writing except if the program writes a disk file, then C Runtime Support Library Page 3-58 fopen C library file opener repositions and reads it using ftell()/fseek(). In this case, the program should call rewind() or freopen() to reinitialize the file before using fseek(). Except in the one specific case of the RT11 console terminal open in "u" mode, an open file must not be used for reading and writing at the same time. Freopen() substitutes the named file in place of the open file -- indicated by iop. The file currently open on iop is closed. Freopen returns iop. If the open failed, iop will be deallocated. Note that freopen loses any pending fwild/fnext status. Bugs Append mode cannot work on native RT11 given the design of the RT11 file system. The RT11 file system does not support files greater than 65535 blocks long. RT11 does not get the actual keyboard name of the console terminal, although this isn't too hard to do on RT11/RSTS/E. Freopen() cannot be used to assign a file to stderr as there is code throughout the i/o package for special treatment of stderr. For example, it cannot be closed by a user-written program. In RSX modes, the maximum number of files that may be simultaneously open is defined at assembly time by a macro (FSRSZ$) which is expanded when fopen.mac is assembled. The default FSRSZ$ parameter is 4. This may be modified by using the task builder /ACTFIL=n option. The default FSRSZ$ value may be specified when the RSX library is built by editing assembly parameter N$$FIL in RSX.MAC. C Runtime Support Library Page 3-59 fprintf Formatted Output Conversion 3.47 Formatted Output Conversion _________ ______ __________ *********** * fprintf * *********** Usage fprintf(iov, format, arg1, ...); FILE *iov; char *buffer; char *format; Description fprintf() converts and formats its arguments, writing the result to the indicated file. For information on formatting, please refer to the description of printf. Bugs C Runtime Support Library Page 3-60 fps Set floating point status (FPS) 3.48 Set floating point status (FPS) ___ ________ _____ ______ _____ ******* * fps * ******* Usage #include fps(status) unsigned int status; Description This routien sets the floating point status by simply executing the LDFPS instruction. This allows a user program to switch between roundoff and truncation modes or enable/disable floating point interrupts. Bit definitions are in the include file, "fps.h". For example, to enable rounding and all fpu error interrupts except underflow, do the following: #include fps(FIUV | FIV | FIC); Bugs The C library doesn't initialize the floating point status. This routine -- with appropriate parameters -- should be in all C main programs that require floating point operations. C Runtime Support Library Page 3-61 fput Output a binary record 3.49 Output a binary record ______ _ ______ ______ ******** * fput * ******** Usage fput(buffer, nbytes, iop); char *buffer; int nbytes; FILE *iop; Description The specified record is written to the file. The file must have been opened 'n' so newlines aren't stuffed here and there. On RT11, the file is only readable by fget. Nbytes is always returned. A call to ferr() after calling fput() is advised. Bugs On RT11, file close zeros the current output block. To prevent fget() from reading "zero length" records, fput writes "record count + 1" on the file. C Runtime Support Library Page 3-62 fread Input a record 3.50 Input a record _____ _ ______ ********* * fread * ********* Usage int fread(object, sizeof (*object), nitem, iop) int nitem; FILE *iop; Description Object points to a buffer that is to receive a specified number of items from the file. fread() returns the actual number of items read. This will be zero if an end-of-file or error was encountered. Bugs C Runtime Support Library Page 3-63 frec Return True if record-oriented file 3.51 Return True if record-oriented file ______ ____ __ _______________ ____ ******** * frec * ******** Usage frec(iop); FILE *iop; Description Return 1 if the file is record-oriented. Note: in this context, record-oriented files are not file-structured disks, nor are they the user's console terminal. Other terminals, along with devices such as line-printers, qualify, however. Bugs C Runtime Support Library Page 3-64 fscanf Formatted input conversion 3.52 Formatted input conversion _________ _____ __________ ********** * fscanf * ********** Usage fscanf(fd, fmt, pointer(s)) FILE *fd; /* Input file pointer */ char *fmt; /* Format string */ Description Fscanf() parses the input file according to the indicated format descriptor, storing the results in the pointer arguments. It returns the number of successfully assigned input items. See the description of scanf() for further documentation. Diagnostics Fscanf() returns -1 if an end of file condition exists and no data was stored. It returns -2 if a palpably incorrect format, such as "%" is encountered. Bugs C Runtime Support Library Page 3-65 fseek Reposition file pointer (seek) 3.53 Reposition file pointer (seek) __________ ____ _______ ______ ********* * fseek * ********* Usage fseek(iop, offset, param); FILE *iop; /* What device to seek */ long offset; /* New read position */ int param; /* Zero for abs. seek */ Description fseek() moves the file pointer to the indicated position. The position must have been returned by ftell() or equal zero for rewind. Param must be zero. The file/device must be seekable. fseek() returns zero if correct, EOF if an error occurs. If no error occurred, error and eof flags are reset. flseek() is an alternate entry with identical parameters and actions. Note that on RSX, fseek() can be used to open a file for update by a sequence such as: fd = fopen("file.nam", "a"); fseek(fd, 0L, 0); /* Rewind file */ If the file was opened on RSX using the 'n' mode switch, it will be opened using file attributes "fixed 512-byte records with no carriage control". The offset pointer is thus a virtual byte number and fseek may be used to freely reposition the file pointer. Bugs C Runtime Support Library Page 3-66 fspool Spool file to default print queue 3.54 Spool file to default print queue _____ ____ __ _______ _____ _____ ********** * fspool * ********** Usage fspool(fp); FILE *fp; /* Open file IOV */ Description This routine is called in lieu of fclose() when it is desired to spool the file to the system line printer. There is no control over the disposition or printout parameters. Fspool() returns zero if the file was spooled, it returns an error code if spooling could not be initiated. If called on native RT11, the file will be closed and an "illegal device error" (E$$NOD = 6) will be returned. If the program needs access to the power of the queue manager print spooler on native RSX, the RSX extensions library spwn() routine should be used to spawn a command line to MCR after closing the file as usual. If the program needs access to the power of the queue manager on RSTS/E, it should close the file and use the routines in the RSTS/E extensions library to execute the UU.SPL system function call. On RSTS/E V7.0, the file is spooled to any line printer (RSX mode) or to LP0: in RT11 mode. The particular line printer cannot be selected without modifying the source of fspool(). If the file was opened by calling fwild()/fnext(), internal buffers will not be freed, allowing the program to call fnext() for subsequent files. Bugs On RSTS/E RT11 mode, error codes will follow the description of the spooling system function call. C Runtime Support Library Page 3-67 ftell Get file position for subsequent seek 3.55 Get file position for subsequent seek ___ ____ ________ ___ __________ ____ ********* * ftell * ********* Usage long ftell(iop); FILE *iop; /* What device to seek */ Description ftell() returns the position of the read/write pointer of the indicated file. This value may be fed back to the file system by calling fseek(). Note that the value is a pointer to the record, not a block or byte pointer. On RSX, the program should flush the current record before calling ftell(). (Flush() is a noop on RT11.) If reading lines of text, the correct sequence is: position = ftell(fd); if (fgets(buffer, sizeof buffer, fd) != EOF) { /* * 'position' locates the record * read by the call to fgets() */ } Make sure you declare ftell() extern long ftell(); If you do not, it will return garbage. Bugs On both systems, the value returned is the position of the file pointer (RFA), as a byte offset from the start of the file. Note, however, that on RSX systems the pointer is to the start of the current record. It is not necessarily the case that the start of a text line equates to the start of a record. RSX supports many file record formats, including Fortran, print_file and "unformatted" (with embedded control information). The latter files may have multiple text lines embedded in each record. This is handled internally by the formatted read routines (i.e., fgets() and getc()). On RSX, the only way to be certain of the exact record/line C Runtime Support Library Page 3-68 ftell Get file position for subsequent seek correspondance is to use the fget() and fput() functions. The T utility program (in the tools library) shows another method of handling this problem. On RSTS/E RT11 mode, ftell will not process "large" files (with more than 65535 blocks) correctly. C Runtime Support Library Page 3-69 ftime Compute time of day (augmented) 3.56 Compute time of day (augmented) _______ ____ __ ___ ___________ ********* * ftime * ********* Usage #ifdef unix #include #include #else #include #endif long ftime(buf); struct timeb *buf; Description ftime returns the time of day in seconds. The time buffer receives the time of day, milliseconds since the current second, and timezone and Daylight Savings time indicators. The time buffer has the following format: struct timeb { long time; /* Time of day */ unsigned millitm; /* Milliseconds */ short timezone; /* Current timezone */ short dstflag; /* Daylight Savings */ }; The time value is the time since midnite, Jan 1, 1970, measured in seconds. The timezone value is the number of minutes that local time differs from GMT. Note that, on Unix, the time buffer definition is stored in the sys directory, while for Decus-C and Vax-11 C, it is stored in the default system library (C: or sys$library: respectively). Bugs The Unix time function returns GMT. Decus C returns local time. Timezone and dstflag are set to zero. C Runtime Support Library Page 3-70 ftty Test if terminal file 3.57 Test if terminal file ____ __ ________ ____ ******** * ftty * ******** Usage ftty(iop) FILE *iop; Description Return 1 if the file is a terminal-type device. In general, this means the user's command terminal. Bugs Obsolete -- use isatty(fileno(iop)) instead for transportability. C Runtime Support Library Page 3-71 fwild Wild-card file open 3.58 Wild-card file open _________ ____ ____ ********* * fwild * ********* Usage FILE * fwild(name, mode); char *name; /* File to open */ char *mode; /* Open modes */ FILE * fnext(iop); FILE *iop; /* I/O pointer */ Description Fwild() opens a new or existing file (whose file name may contain "wild-cards"). Open modes are identical to those given in fopen(). On return, the file name has been parsed, but no file has yet been opened. A NULL return means that the file name did not parse correctly. Fnext() opens the first or next file which was defined by a previous call to fwild(). If fnext() returns NULL, there are no (more) files that match the wild-card specification. fwild/fnext handle RSX file version numbers correctly on VMS compatibility mode (which uses the ODS2 disk structure). Fwild/fnext do not handle version numbers correctly on native RSX systems which use the FILES-11 (ODS1) disk structure. For example, a program can request "foo.*;3", "foo.*;*", "foo.*;0", and "foo.*;-1". Omitting a version number "foo.*" is equivalent to "foo.*;0". Note that version number 0 means the "newest" file, while version number -1 means the oldest. (Version numbers are not used on RT11 or RSTS/E.) For native RSX systems (using the FILES-11 disk structure), an explicit version number and the wildcard version number work correctly. Version numbers 0 and -1 work only if the directory has been reorganized by using the SRD utility program. If the directory has not been reorganized (such that the youngest version appears first in the directory), fnext() will yield unpredictable results. On RT-11, the wildcard filename match is handled C Runtime Support Library Page 3-72 fwild Wild-card file open internally to fwild/fnext. The parser will handle several forms of wild file specs, including imbedded '*' and the single character wildcard '%', and acts the same as the DIRECTORY wildcard handler. For convenience, a '?' acts the same as a '%' in a match string. Note: if a program executes fclose(), all file name information will be lost. The following sequence illustrates proper use of fwild()/fnext(): if (gets(name_buff) == NULL) exit(); if ((fd = fwild(name_buff, "r")) == NULL) error("Can't open %s\n", name_buff); for (count = 0; fnext(fd) != NULL; count++) { /* * Process each file */ while (fgets(buffer, sizeof buffer, fd) != NULL) { /* * Process each record */ } } /* * fnext() fails; the channel is closed. * count has the number of files processed. */ if (count == 0) error("No matching files found"); The following summarizes the types of wild-card processing available on the various implementations of the C support library: Environment Supports Native RSX "*" matches any filename, filetype, or version number. Version ;0 and ;-1 are supported on ODS2 systems. UIC's may not contain wildcards. RSX/VMS As above, note that version ;-1 means the "earliest" version. Note warning below. Directory identifiers may not be wildcarded. VMS systems support ODS2. RSX/RSTS Uses RSTS/E wildcard conventions: "*" replaces filename or filetype. "?" matches any character. PPN's may not be wildcarded. Version numbers are not supported on RSTS/E. C Runtime Support Library Page 3-73 fwild Wild-card file open Native RT11 "*" replaces any string, "%" or "?" match any non-blank character. RT11/RSTS Uses RSTS/E wildcard conventions noted above. Bugs On native RSX systems using ODS1 (FILES-11) disk structures, version numbers will be processed properly only if directories have been sorted (by using the SRD utility program, for example). If directories are not sorted, and fwild() is invoked with version number ;0 or ;-1, it will yield unpredictable results. The command language scan (CSI1$) on VMS compatibility mode does not parse version number -1 (because it has a different meaning on native VMS) and fwild() will consequently fail. If you want the oldest version, fwild() should be invoked with a file name of the type "foo.*" or "foo.*;0" and, before calling fnext() for the first time, you should set the correct bits in the IOV flag word as follows: if ((fd = fwild(file, "r")) == NULL) error("can't open file %s", file); if ((fd->io_flag & IO_VER) != 0 && version_minus_1_wanted) fd->io_flag |= IO_VM1; Flag bit IO_VER signals "version 0 or -1", while bit IO_VM1 signals version minus 1. Again, note that this must be done before the first call to fnext(). On native RT11 and all RSTS/E modes, fwild/fnext will fail if the device is not directory structured (even if no wildcard file is specified). If this is a problem, you should write: if ((fd = fwild(filename, mode)) != NULL) iswild = 1; else if ((fd = fopen(filename, mode) != NULL) iswild = 0; else error("cannot open the file"); The program must then test iswild to determine if it must call fnext() or if processing should be initiated directly. On all RSTS/E modes, there may be problems with logical name translation as file name strings must be parsed more than once. Thus, if a programer defines a logical C Runtime Support Library Page 3-74 fwild Wild-card file open name which is identical to a valid physical device name, a wildcard lookup may access the wrong unit. This problem is described in the RSTS/E documentation. Fwild/fnext was designed to work only with disk devices. It will not necessarily work correctly with other directory-structured devices, such as magtape. C Runtime Support Library Page 3-75 fwrite Output a record 3.59 Output a record ______ _ ______ ********** * fwrite * ********** Usage int fwrite(object, sizeof (*object), nitem, iop) int nitem; FILE *iop; Description Object points to a buffer that is contains a specified number of items to be written to the file. fwrite() returns the actual number of items written. This will be zero if an error was encountered. Bugs C Runtime Support Library Page 3-76 getchar Get characters 3.60 Get characters ___ __________ *********** * getchar * *********** Usage getchar(); getc(iop); FILE *iop; Description Getchar() reads one character from the standard input file. getc() reads one character from the indicated input file. Both return EOF on error or end of file. To continue reading from a terminal after EOF, the program may execute: clearerr(iop); Bugs C Runtime Support Library Page 3-77 gets Read a string from stdin 3.61 Read a string from stdin ____ _ ______ ____ _____ ******** * gets * ******** Usage char * gets(buffer); char *buffer; Description gets() reads a string into the buffer from the standard input (stdin). The string is terminated by a newline character, which is replaced in the buffer by a null. Gets() returns buffer or NULL on end of file or error. Bugs C Runtime Support Library Page 3-78 gettty Get control terminal name 3.62 Get control terminal name ___ _______ ________ ____ ********** * gettty * ********** Usage gettty(buffer); char *buffer; Description Store the device name of the control terminal in the buffer. If this cannot be done, a null string will be returned. Bugs On RSX modes, gettty() uses the GLUN$ executive directive to obtain the device name and unit number of stderr (which always is assigned to the control terminal). On RT11 modes, gettty() calls iovtoa to return the file name on which stderr was opened. This will not necessarily contain a valid unit number. C Runtime Support Library Page 3-79 getw Input a binary integer from a file 3.63 Input a binary integer from a file _____ _ ______ _______ ____ _ ____ ******** * getw * ******** Usage getw(iop); FILE *iop; Description getw() reads one (16-bit) word from the indicated file. The program must call feof() or ferr() to test for end of file or error. Bugs C Runtime Support Library Page 3-80 inchr Find Index of Character in a String 3.64 Find Index of Character in a String ____ _____ __ _________ __ _ ______ ********* * inchr * ********* Usage char * inchr(stng, chr) char *stng; /* String to search in */ char chr; /* Byte to search for */ Description If chr is in stng, return its index, i.e. the offset in bytes from the beginning of the string - inchr("abc",'b') == 1. If chr is not in stng, return -1. See also strchr(). Bugs C Runtime Support Library Page 3-81 index Find First Instance of a Character in a String 3.65 Find First Instance of a Character in a String ____ _____ ________ __ _ _________ __ _ ______ ********* * index * ********* Usage char * index(stng, chr) char *stng; /* String to search in */ char chr; /* Byte to search for */ Description If chr is in stng, return a pointer to it. If not, return NULL. Bugs Obsolete; use strchr() instead. C Runtime Support Library Page 3-82 iov I/O vector definition 3.66 I/O vector definition ___ ______ __________ ******* * iov * ******* Usage #include ... to be supplied ... Bits in iov.io_flag: #define _IOREAD 0000001 /* read */ #define _IOWRT 0000002 /* write */ #define _IONBF 0000004 /* Unbuffered, "u" mode */ #define _IOMYBUF 000010 /* I/O lib. owns buffer */ #define _IOEOF 0000020 /* End of file seen */ #define _IOERR 0000040 /* Error seen */ #define _IOSTRG 0000100 /* For sprintf */ #define _IORW 0000200 /* Open for read/write */ #define IO_CMD 0000400 /* User's command tty */ #define IO_APN 0001000 /* Append mode open */ #define IO_NOS 0002000 /* No newlines needed */ #define IO_NEWL 0004000 /* RSX TTY newline hack */ #define IO_FIL 0010000 /* Disk file */ #define IO_TTY 0020000 /* Terminal device */ #define IO_REC 0040000 /* Record device */ #define IO_OPN 0100000 /* Open file */ #define IO_EOR (IO_ERR | IO_EOF) Bits in iov.io_wflag: #define IO_WLD 0000001 /* fwild: wildcard file */ #define IO_VM1 0000002 /* fwild: version ;-1 */ #define IO_VER 0000004 /* fwild: ;0 or ;-1 */ #define IO_WF1 0000010 /* fwild first flag */ #define IO_NLH 0000020 /* Newlines hack bit */ Bits in iov.io_rsflag (RSTS native only) #define IO_ODT2 0100000 /* ODT mode (RSTS only) */ extern int $$ferr; /* Error word */ extern FILE *stdin; /* Standard input file */ extern FILE *stdout; /* Standard output file */ extern FILE *stderr; /* User's command tty */ extern int $$exst; /* Exit status */ Description Define the I/O vector structure used for communication C Runtime Support Library Page 3-83 iov I/O vector definition by all I/O routines in the C library. Note that it is different for RSX and RT11 modes. Note also that certain bits in IO_FLAG are only meaningful for one flavor of I/O. The RSX-mode IOV contains an entire file data block (FDB). Also, 'io_uic' contains the binary UIC of the directory via which the file is being accessed, not the 'owner' UIC. It is this UIC which is given when fgetname() is called. The RT11-mode IOV contains only enough information to read and write files plus a pointer to an Ascii string with the file name argument to fopen(). The file name is needed for fgetname() and to allow deleting files given the IOV pointer. The following files are defined here: stdin The standard input file. stdout The standard output file. stderr The error output file. Note: on RSX systems, stderr is opened on LUN 1. $$ferr (error word) is also defined here. This is set non-zero if an error occurred when performing I/O. On RSX, the standard I/O error code is returned. On RT11, an error code compatible with RSTS/E usage is returned: Global Value Meaning E$$ILF 02. 002 Illegal file name E$$NOR 04. 004 No room for user on device E$$FNF 05. 005 Can't find file or account E$$NOD 06. 006 Not a valid device E$$ILU 07. 007 I/O channel in use E$$NOO 09. 011 I/O channel not open E$$EOF 11. 013 End of file on device E$$FAT 12. 014 Fatal system I/O failure E$$ERR 13. 015 User data error on device E$$FND 16. 020 File already found (protected) E$$NOC 17. 021 Too many open files on unit. E$$NSP 32. 040 No memory space for buffer E$$FAT (12) is set only if an "impossible" error occurs. While this may indicate a bug in the RT11 library, it is more likely to be a user programming error (like passing garbage to an I/O routine). E$$ILU (7) is set if fopen tries to open a channel that is already in use. The perror() library routine may be used to print an C Runtime Support Library Page 3-84 iov I/O vector definition error message defined for the error code. $$exst (exit status) is used to transmit a termination code to the operating system. The value is set by calling exit() or exits(). The following exit status values are defined in stdio.h: Global #define RSX RT11 Meaning E$$XOK IO_SUCCESS 1 1 Normal E$$XWA IO_WARNING 0 2 Warning E$$XER IO_ERROR 2 4 Error E$$XFA IO_FATAL 4 8 Severe Error Bugs C Runtime Support Library Page 3-85 irand Random number modulus argument 3.67 Random number modulus argument ______ ______ _______ ________ ********* * irand * ********* Usage int irand(arg) int arg; Description Generate a pseudorandom number in the range 0 .. (arg-1). If arg is zero, generate a number in the range 0 .. 32767. Note that the algorithm is prone to nonrandom sequences when considering the next pseudorandom number. irand is equivalent to the following sequence: extern long rand; if (arg == 0) arg = 32767; return(((rand() >> 8) & 32767) % arg); Bugs C Runtime Support Library Page 3-86 isalloc Check If a Pointer Points to Allocated Memory 3.68 Check If a Pointer Points to Allocated Memory _____ __ _ _______ ______ __ _________ ______ *********** * isalloc * *********** Usage int isalloc(buff) char *buff; Description isalloc() returns 1 if buff is a pointer to a block of memory allocated by calloc(), malloc(), or realloc() that has not been freed (by free()); -1 if it is a (recently) freed allocated block; and 0 otherwise. isalloc(NULL) == 0. isalloc(p) will remain -1 after a call of free(p) at least until the next call to calloc(), malloc(), etc. Beyond that, its value is not predictable. Pointers for which isalloc() is non-zero are exactly those that may safely be passed to realloc(). The test done by isalloc() is definitive, unlike the tests done by, for example, free() and msize(), which will yield false positives at least 25% of the time. However, isalloc() is slower. Bugs Not portable. C Runtime Support Library Page 3-87 isalnum Return TRUE if alphanumeric argument 3.69 Return TRUE if alphanumeric argument ______ ____ __ ____________ ________ *********** * isalnum * *********** Usage isalnum(c); int c; Description Return non-zero if c is an alphanumeric character, 0 otherwise. Bugs C Runtime Support Library Page 3-88 isalpha Test for alphabetic argument 3.70 Test for alphabetic argument ____ ___ __________ ________ *********** * isalpha * *********** Usage isalpha(c); int c; Description Return non-zero if c is an alphabetic character, 0 otherwise. Bugs C Runtime Support Library Page 3-89 isascii Test for 7-bit Ascii character 3.71 Test for 7-bit Ascii character ____ ___ _____ _____ _________ *********** * isascii * *********** Usage isascii(c); int c; Description Return non-zero if c is a 7-bit Ascii character, 0 otherwise. Bugs C Runtime Support Library Page 3-90 isatty Test if terminal file 3.72 Test if terminal file ____ __ ________ ____ ********** * isatty * ********** Usage isatty(channel_number) int channel_number; Description Return 1 if the file open on this channel is a terminal-type device. In general, this means the user's command terminal. Note that the argument is a file descriptor, not a FILE * pointer. File descriptors are used on Unix to identify the channel on which the file is open. As Decus C does not support file descriptor I/O processing, the logical unit number assigned to a file by fopen() is used instead. Use isatty() as follows: if (isatty(fileno(fd))) ... Bugs Note that Decus C channel numbers are not related to Unix file descriptors. Specifically, isatty(0) does not necessarily check stdin. Use isatty(fileno(stdin)) instead. C Runtime Support Library Page 3-91 iscntrl Test for control character argument ;02 3.73 Test for control character argument ____ ___ _______ _________ ________ 02 *********** * iscntrl * *********** Usage iscntrl(c); int c; Description Return non-zero if C is a control character. Bugs C Runtime Support Library Page 3-92 isdigit Return TRUE if digit argument 3.74 Return TRUE if digit argument ______ ____ __ _____ ________ *********** * isdigit * *********** Usage isdigit(c); int c; Description Return 1 if c is an Ascii digit, 0 otherwise. Bugs C Runtime Support Library Page 3-93 isgraph Test for graphic alphabetic argument 3.75 Test for graphic alphabetic argument ____ ___ _______ __________ ________ *********** * isgraph * *********** Usage isgraph(c); int c; Description Return non-zero if c is a graphic character, 0 otherwise. Graphics characters include letters, digits, and punctuation. Space, tab, etc. are not graphics. Bugs C Runtime Support Library Page 3-94 islower Test for lower-case alphabetic argument 3.76 Test for lower-case alphabetic argument ____ ___ __________ __________ ________ *********** * islower * *********** Usage islower(c); int c; Description Return non-zero if C is a lower-case alphabetic character, 0 otherwise. Bugs C Runtime Support Library Page 3-95 isprint Return non-zero if printable argument 3.77 Return non-zero if printable argument ______ ________ __ _________ ________ *********** * isprint * *********** Usage isprint(c); int c; Description Return non-zero if c is a printable character, 0 otherwise. Printable characters include letters, digits, punctuation, and the space character. Tab, newline, etc. are not included. Bugs C Runtime Support Library Page 3-96 ispunct Return TRUE if punctuation argument 3.78 Return TRUE if punctuation argument ______ ____ __ ___________ ________ *********** * ispunct * *********** Usage ispunct(c); int c; Description Return non-zero if c is an Ascii punctuation, 0 otherwise. Bugs C Runtime Support Library Page 3-97 isspace Return non-zero if the character is "whitespace" 3.79 Return non-zero if the character is "whitespace" ______ ________ __ ___ _________ __ ____________ *********** * isspace * *********** Usage isspace(c); int c; Description Return non-zero if c is a whitespace character. These consist of space, backspace, newline, tab, and form-feed. The carriage return ('\r') is also included. Bugs C Runtime Support Library Page 3-98 isupper Return TRUE if Upper-case alphabetic argument 3.80 Return TRUE if Upper-case alphabetic argument ______ ____ __ __________ __________ ________ *********** * isupper * *********** Usage isupper(c); int c; Description Return 1 if c is an Upper-case alphabetic character, 0 otherwise. Bugs C Runtime Support Library Page 3-99 isxdigit Return non-zero if hexadecimal digit 3.81 Return non-zero if hexadecimal digit ______ ________ __ ___________ _____ ************ * isxdigit * ************ Usage isxdigit(c); int c; Description Return non-zero if C is a valid hexadecimal digit (0-9, A-F, a-f). Bugs This routine is not present in other C libraries. C Runtime Support Library Page 3-100 itoa Integer to Ascii 3.82 Integer to Ascii _______ __ _____ ******** * itoa * ******** Usage char * itoa(value, string) int value; char *string; Description itoa converts the value to a (signed) decimal string. The string is null-trailed. itoa returns a pointer to the trailing null. Note that the result can be computed (more flexibly) by executing sprintf(buffer, "%d", value); Bugs C Runtime Support Library Page 3-101 itoa8 Convert integer to octal Ascii 3.83 Convert integer to octal Ascii _______ _______ __ _____ _____ ********* * itoa8 * ********* Usage char * itoa8(value, buffer); Description: The value is converted to octal and stored in the buffer. A pointer to the trailing null is returned. Note that the result can be computed (more flexibly) by executing sprintf(buffer, "%o", value); Bugs: This routine does not generate leading zeros. If they are needed, use: sprintf(buffer, "%06o", value); C Runtime Support Library Page 3-102 itoax Convert an integer to hexidecimal Ascii 3.84 Convert an integer to hexidecimal Ascii _______ __ _______ __ ___________ _____ ********* * itoax * ********* Usage char * itoax(value, buffer); int value; char *buffer; Description: Convert the integer to hexidecimal ascii. The string is null-trailed. Values from 10 to 15 (decimal) are represented by "A" to "F". Itoax() returns a pointer to the trailing null. Note that the result can be computed (more flexibly) by executing sprintf(buffer, "%x", value); Bugs: C Runtime Support Library Page 3-103 kbin Single Character Terminal Input 3.85 Single Character Terminal Input ______ _________ ________ _____ ******** * kbin * ******** Usage int kbin(); Description Read one character from the console terminal. The input character is not echoed nor does the program delay until an entire line has been entered. Note the following: This routine is very inefficient, as it requests operating-system service for every character entered. Typing Control/C (or Control/Y on VMS) will cause the program to exit immediately (as if the main() routine exited), closing all files. On RT-11 (native and emulated), the operating system expands to a carriage return line feed sequence. This will be stripped by kbin() to just ('\r' in C). Thus, if the user program reads '\n', a was typed. Note that this is unlike the general C library. Bugs On RSX, this routine requires the command terminal having been assigned as logical unit number 1. In general, the input character will not have been echoed. On RSTS/E and native RT11, the operating system may already have echoed the character if you type the character before the read request has been made. C Runtime Support Library Page 3-104 kbinr Terminal Input Without Wait 3.86 Terminal Input Without Wait ________ _____ _______ ____ ********* * kbinr * ********* Usage int kbinr(); Description If a character has been typed on the console terminal, return it (without echoing or waiting). If no character is available, kbin() returns -1 (EOF). Note the following: This routine is very inefficient, as it requests operating-system service for every character entered. Typing Control/C (or Control/Y on VMS) will cause the program to exit immediately. On RT-11, the operating system expands to a carriage return line feed sequence. This will be stripped by kbin() to just ('\r' in C). Thus, if the user program reads '\n', a was typed. Note that this is unlike the general C library. Bugs On RSX-11M, this routine depends on the fact that the console terminal was assigned to LUN 1. On RSX-11M and VMS emulation mode, the typed character will not be echoed. On RSTS/E and RT11 modes, it may have already been echoed by the operating system if the terminal user typed before the program requests input. C Runtime Support Library Page 3-105 localtime Build time of day buffer 3.87 Build time of day buffer _____ ____ __ ___ ______ ************* * localtime * ************* Usage #include /* Define tm structure */ struct tm * localtime(tvec); long *tvec; /* Time value pointer */ struct tm { int tm_sec; /* Seconds */ int tm_min; /* Minutes */ int tm_hour; /* Hours */ int tm_mday; /* Day of month */ int tm_mon; /* Month 0 .. 11 */ int tm_year; /* Year - 1970 */ int tm_wday; /* Weekday, Sunday == 0 */ int tm_yday; /* Days since Jan 1 */ int tm_isdst; /* Daylight Saving if 1 */ }; Description localtime() converts a Unix time value to a vector of values. Bugs Decus C doesn't correct for time zone or daylight savings time. Leap year isn't done correctly. The routine will fail after Feb 28, 2100. Following Unix precedent, localt returns a pointer to a static buffer. C Runtime Support Library Page 3-106 malloc Allocate and free memory 3.88 Allocate and free memory ________ ___ ____ ______ ********** * malloc * ********** Usage char * malloc(size); /* NULL if no space */ unsigned size; /* Number of bytes */ mfree(p); free(p); char *p; /* Was allocated */ Description malloc() allocates the indicated number of bytes, returning a pointer to the first. If the allocation request cannot be satisfied, malloc returns NULL. The program image is expanded as needed. free() and mfree() return a buffer to free space. Nothing is returned. See also the description of realloc() and sbrk(). Diagnostics The program may abort if free() is passed a random pointer or if the program writes outside of an area reserved by malloc(). Note that only certain cases are trapped by this test and that free will accept invalid addresses, which will cause mysterious failures. The isalloc() function may be used to test whether a block of memory has been allocated by malloc(). Bugs C Runtime Support Library Page 3-107 maxmin Maximum and Minimum Routines 3.89 Maximum and Minimum Routines _______ ___ _______ ________ ********** * maxmin * ********** Usage max(a,b) int a; int b; min(a,b) int a; int b; unsigned maxu(a,b) unsigned a; unsigned b; unsigned minu(a,b) unsigned a; unsigned b; Description max() and min() return, respectively, the maximum and minimum of their two arguments, considered as signed integers. maxu() and minu() are the same but consider their arguments to be unsigned. Note: If you are interested in getting the fastest code possible and have some knowledge of the relative sizes of a and b, arrange for a to be chosen most often. (It's unlikely the difference will be noticable in virtually all cases.) Bugs C Runtime Support Library Page 3-108 memdmp Dump memory or registers 3.90 Dump memory or registers ____ ______ __ _________ ********** * memdmp * ********** Usage memdmp(start, end); /* Memory dump routine */ char *start; /* First to dump */ char *end; /* Last to dump */ regdmp(); /* Register dump */ Description Dump registers and/or memory. All registers are preserved. If memdmp is called with a zero argument, the stack will be dumped. Memdmp and regdmp are independent of the C I/O library. However, on RSX, they assume that the console terminal has been assigned as LUN 1. Bugs Condition codes are not preserved. C Runtime Support Library Page 3-109 msg Print a message on the command terminal 3.91 Print a message on the command terminal _____ _ _______ __ ___ _______ ________ ******* * msg * ******* Usage msg(text) char *text; Description Print a message on the console terminal. This routine does not use the standard library. Return: all registers are preserved. Bugs On RSX, this routine requires the command terminal having been assigned as logical unit number 1. C Runtime Support Library Page 3-110 msize Get Size of a Memory Block 3.92 Get Size of a Memory Block ___ ____ __ _ ______ _____ ********* * msize * ********* Usage unsigned int msize(buff) char *buff; Description msize() returns the size of a block of memory allocated by calloc(), malloc(), or realloc(). If buff did not, in fact, come from one of these routines, the program will crash about 75% of the time; the other 25% , nonsense will be returned. (This behavior is due to a simple-minded validation algorithm.) However, buff == NULL is valid and will return 0. Note that the value returned is the amount of memory that malloc() (or whoever) actually allocated, which may not be exactly the same as the program asked for. (Currently, all allocations are rounded up to an even number of bytes.) Bugs Not portable. C Runtime Support Library Page 3-111 peek Peek at a location in RSTS/E 3.93 Peek at a location in RSTS/E ____ __ _ ________ __ ______ ******** * peek * ******** Usage peek(location) int *location; Description Peek to a location in the RSTS/E monitor. The job will be aborted with a BPT if not running under RSTS/E. Bugs C Runtime Support Library Page 3-112 perror Print Library Error Message 3.94 Print Library Error Message _____ _______ _____ _______ ********** * perror * ********** Usage perror(text) char *text; Description An error message is written to stderr, using the current i/o library error (stored in $$ferr). Text is prepended to the message. Diagnostics Bugs C Runtime Support Library Page 3-113 printf Formatted print routine 3.95 Formatted print routine _________ _____ _______ ********** * printf * ********** Usage printf(format, arg1, ...) char *format; fprintf(iov, format, arg1, ...) FILE *iov; char *format; char * sprintf(buffer, format, arg1, ...); char *buffer; char *format; $$prnt(format, argvec, iov) char *format; int *argvec[]; FILE *iov; Description printf() converts, formats, and prints its arguments, under control of the first argument, writing output via putchar(). fprintf() writes its output to the indicated file. sprintf() writes its output to the indicated string buffer. $$prnt() is the internal print formatter which is called by printf, etc. sprintf() returns a pointer to the EOS at the end of the output buffer. This is not necessarily transportable. The format argument is a character string which contains two types of objects: plain characters, which are simply copied to the output stream, and conversion specifications, each of which causes conversion and printing of the next successive argument to printf. Each conversion specification is introduced by the character %. Following the %, there may be - an optional minus sign "-" which specifies left adjustment of the converted argument in the indicated field. - an optional digit string specifying field width; if C Runtime Support Library Page 3-114 printf Formatted print routine the converted argument has fewer characters than the field width, it will be blank-padded on the left (or right, if the left-adjustment indicator has been given) to make up the field width. If the field width is specified as '*' or '?', the next argument is used. (Note: '?' is obsolete.) If the width is specified with a leading zero, zeros are used for padding instead of blanks. This zero does NOT imply an octal field width. For example, assume the value 123 is to be printed: %d "123" %5d " 123" %-5d "123 " %05d "00123" - an optional period "." which serves to separate the field width from the next digit string; - an optional digit string (precision) which specifies the number of digits to appear after the decimal point for e- and f-conversion, or the maximum number of characters to be printed from a string. If the precision is specified as '*' or '?', the next argument is used. - a character which indicates the type of conversion to be applied. The conversion characters and their meanings are d Signed-decimal u Unsigned-decimal o Octal X Hexadecimal, 10-15 are represented by A-F x Hexadecimal, 10-15 are represented by a-f The integer argument is converted to decimal, octal, or hexadecimal notation respectively. Any of the conversion characters may be preceeded by 'l' to signal "long" integer argument. Note that the Unix usage of capital letters to represent long arguments is not supported. Note In order to eliminate the very large floating point conversion routines from most programs, a program which requires floating point conversion must request the double to ascii conversion routine explicitly. The following sequences show how this is done: C Runtime Support Library Page 3-115 printf Formatted print routine RSX: TKB task=source,LB:DTOA,LB:C/LB RT11: LINK source,C:DTOA,C:SUPORT,C:CLIB/BOT:2000 If this is not done, any use of the %f %e, or %g conversions will result in an error message. On RSTS/E, the library build procedure creates RTDTOA.OBJ and RXDTOA.OBJ in the library account. ** Floating point support has not yet ** ** been fully implemented. The float ** ** or double value must be the last ** ** or only argument to printf. Only ** ** single-precision conversion is ** ** presently available. ** f The argument is converted to decimal notation in the style "[-]ddd.dd" where the number of d's after the decimal point equals the precision specification for the argument. If precision is missing, 6 digits are given; if explicitly 0, no digits and no decimal point are printed. The argument should be float or double. "%lf" or "%F" must be used to signal "long (i.e. double) argument." This is a restriction of Decus C. e The float or double argument is converted in the style "[-]d.ddde+-dd" where there is one digit before the decimal point and the number after is equal to the precision specified for the argument; if the precision is missing, 6 digits are produced. "%le" or "%E" must be used to signal "long (i.e. double) argument." This is a restriction of Decus C. g Floating point: "%f" format if suitable, else "%e" format. "%lg" or "%G" must be used to signal "long (i.e. double) argument." This is a restriction of Decus C. c The argument character is printed. (Note that 'lc' takes a long integer argument.) r Remote format. The next printf() argument is the format. Note that this is not a subroutine. The current format is not processed further. For example: bug(args) { error("Error at %r", &args); } This routine might be called as follows: C Runtime Support Library Page 3-116 printf Formatted print routine bug("Error %d at %s\n", val, name); %r is not transportable to all implementations of the standard library. It does not word on Vax-11 C, for example. $$prnt may be used as shown below for similar functionality. s The argument is taken to be a string (character pointer) and characters from the string are printed until a null character or until the number of characters indicated by the precision specification is reached; however if the precision specification is 0 or missing all characters up to null are printed. If no recognizable character appears after the %, that character is printed; thus % may be printed by the use of the string %%. In no case does a non-existant or small field width cause truncation of a field; padding takes place only if the specified field width exceeds the actual width. Characters generated by printf() are printed by calling putchar(). $$prnt() is the internal print formatter called by all "top-level" print functions. It is functionally identical to the Unix and Vax-11 C _doprnt() library routine. Unfortunately, the leading '_' conflicts with RSX-11M file services library routine conventions, requiring the use of the Decus C unique "$$" prefix. If your programs wish to call $$prnt, a potentially transportable procedure would be: #ifdef decus $$prnt(format, args, iov); #else _doprnt(format, args, iov); #endif You should assume, however, that _doprnt() is not necessarily present on all implementations of the "standard library." Bugs e, f, and g conversion only work for single-precision floating point. Use of "%lf" etc. is not transportable and may change. It may also cause problems in the C compiler (as the standard says that subroutine calls take double (not short floating) arguments. C Runtime Support Library Page 3-117 profile Print profile data 3.96 Print profile data _____ _______ ____ *********** * profile * *********** Usage $$prof(); extern int $$prnl; extern char *$$pfil; Description $$prof is called by the run-time library when the program exits if any functions have been executed that were compiled with the profile option. A profile file is written to file "profil.out". This is defined by a global symbol $$pfil. By setting $$prnl to NULL, the profile file is supressed. By changing the value of $$prnl, the program can control the number of profile entries written on each line. The default value writes 4 entries per line. Changing $$prnl to N writes N entries on each line, simplifing post-processing (sorting) of the data. For example: $$prnl = 0; writes each entry on a separate line. The following example shows how to control the output file name: extern char *$$pfil; ... $$pfil = "ti:"; /* Output to ti: */ $$pfil = NULL; /* No profile output */ Data is written using the format string "%8s %6u". If more than one entry is written to a line, succeeding entries will be preceeded by one space. Note that, by writing the data one entry per line, the profile output may easily be sorted either by function name or by frequency count. C Runtime Support Library Page 3-118 profile Print profile data Bugs C Runtime Support Library Page 3-119 putc Output one character to a file 3.97 Output one character to a file ______ ___ _________ __ _ ____ ******** * putc * ******** Usage putchar(c); char c; putc(c, iop); char c; FILE *iop; Description Putchar() writes one character to the standard output file. Putc() writes one character to the named output file. Normally, the character is returned. EOF is returned on errors. Bugs C Runtime Support Library Page 3-120 puts Output a string to a file 3.98 Output a string to a file ______ _ ______ __ _ ____ ******** * puts * ******** Usage puts(s); char *s; fputs(s, iop); char *s; FILE *iop; fputss(s, iop); char *s; FILE *iop; Description puts() writes a string to the standard output. It appends a newline after the string. fputs() writes a string to the indicated file. No newline is appended. fputss() writes a string to the indicated file. A newline is appended. Bugs C Runtime Support Library Page 3-121 putw Output a binary integer to a file 3.99 Output a binary integer to a file ______ _ ______ _______ __ _ ____ ******** * putw * ******** Usage putw(word, iop); int word; FILE *iop; Description putw() writes one word to the indicated file. It returns EOF on error, 0 on success Bugs C Runtime Support Library Page 3-122 qset Add memory to the RT11 queue area 3.100 Add memory to the RT11 queue area ___ ______ __ ___ ____ _____ ____ ******** * qset * ******** Usage qset(number) int number; /* How many elements */ Description Allocate sufficient memory for the requested number of queue elements. If sufficient memory cannot be allocated, do nothing. Bugs This routine is ignored on RSX. C Runtime Support Library Page 3-123 r50toa Convert Radix-50 to Ascii 3.101 Convert Radix-50 to Ascii _______ ________ __ _____ ********** * r50toa * ********** Usage r50toa(buff, r5vec, r5cnt); char *buff; /* Output text buffer */ int *r5vec; /* Input rad50 buffer */ int r5cnt; /* How many rad50 words */ Description: Convert r5cnt words of radix 50 data to Ascii. All letters will be in upper-case. The output buffer will not be null-trailed, nor will blank fields be supressed. Bugs C Runtime Support Library Page 3-124 rand Random number generator 3.102 Random number generator ______ ______ _________ ******** * rand * ******** Usage long rand() extern long seed; /* Random number seed */ Description Generate a pseudorandom number. The algorithm is: seed = (69069 * seed + 1); return (rand & 0X8FFFFFFF); The algorithm is based on the mth$random function in the VMS common run-time library. Note that the algorithm is prone to nonrandom sequences when considering the next pseudorandom number. Bugs C Runtime Support Library Page 3-125 realloc Reallocate memory 3.103 Reallocate memory __________ ______ *********** * realloc * *********** Usage char * realloc(buff, size); char *buff; /* Buffer from malloc() */ unsigned size; /* New size for buff */ Description Realloc() changes the size of the block pointed to by buff, returning a pointer to the (possibly moved) block. The contents will be unchanged up to the lesser of the new and old sizes. Realloc() also works if buff points to a block freed since the last call of malloc(), realloc(), or calloc(); thus sequences of free(), malloc(), and realloc() can exploit the search strategy of malloc() to do storage compaction. See also the description of malloc(), calloc() and sbreak(). The following program segment illustrates use of realloc() to expand and compact storage. #ifndef vms static char *compact_work; #endif main() { /* * Initialize work element * for compact() */ #ifndef vms compact_work = malloc(1); #endif ... } char * compact(old_ptr, new_size) char *old_ptr; int new_size; C Runtime Support Library Page 3-126 realloc Reallocate memory /* * Reallocate the area allocated to old_ptr, * originally allocated by a call to malloc(), * so that it will contain new_size bytes (which * may be greater or less than the current size). * Return a pointer to the new area. * Note: error handling is not shown. */ { extern char *realloc(); free(old_ptr); #ifndef vms free(compact_work); compact_work = malloc(1); #endif return(realloc(old_ptr, new_size)); } compact_work must not be used on the native vax compiler (Vax-11 C) as the internal free memory buffers are organized in a different and incompatible manner. Diagnostics The program will abort if buff is not the address of a buffer allocated by malloc() or calloc(). Bugs C Runtime Support Library Page 3-127 rewind Rewind a file for re-reading 3.104 Rewind a file for re-reading ______ _ ____ ___ __________ ********** * rewind * ********** Usage rewind(iop); FILE *iop; Description Rewind the indicated file. Return -1 if failure, 0 if ok. On RT11, if the file was opened for output, it is closed and reopened for input. Diagnostics RT11 exits fatally if the file name won't parse. As the filename was stored by fopen(), this probably means that the user program has stored randomly in memory. Bugs C Runtime Support Library Page 3-128 rindex Find Last Instance of a Character in a String 3.105 Find Last Instance of a Character in a String ____ ____ ________ __ _ _________ __ _ ______ ********** * rindex * ********** Usage char * rindex(stng, chr) char *stng; /* String to search in */ char chr; /* Byte to search for */ Description If chr is in stng, return a pointer to the last instance it. If not, return NULL. Bugs Obsolete, use strrchr() instead. C Runtime Support Library Page 3-129 rstsys Execute a RSTS EMT 3.106 Execute a RSTS EMT _______ _ ____ ___ ********** * rstsys * ********** Usage int rstsys(emt) Description Execute a rsts emt, returning the error code. Bugs C Runtime Support Library Page 3-130 rtemt Execute a RT11 EMT 3.107 Execute a RT11 EMT _______ _ ____ ___ ********* * rtemt * ********* Usage int rtemt(emt, r0value) Description Execute a rt11 emt after loading r0. Bugs C Runtime Support Library Page 3-131 salloc Allocate local memory 3.108 Allocate local memory ________ _____ ______ ********** * salloc * ********** Usage char * salloc(n); /* NULL if no space */ Description Allocate the requested number of bytes on the run-time stack, returning a pointer to the first byte allocated. The storage will be reclaimed automatically when the function that called salloc() exits. Note that storage so allocated cannot be explicitly freed. salloc() returns NULL if allocating the requested space would cause the run-time stack to go below 1000 octal. Note: it is essential that salloc() be called with a "clean stack". I.e, the program must not execute subr(salloc(10), 20); Instead, it should execute temp = salloc(10); subr(temp, 20); Diagnostics Bugs C Runtime Support Library Page 3-132 sbrk Allocate memory from operating system 3.109 Allocate memory from operating system ________ ______ ____ _________ ______ ******** * sbrk * ******** Usage char * sbrk(amount) int amount; Description sbrk() allocates the indicated amount of memory from the operating system. The allocation is permanent. Diagnostics NULL is returned if the memory requested is not available. There is no "shortened" return. Bugs C Runtime Support Library Page 3-133 scanf Formatted input conversion 3.110 Formatted input conversion _________ _____ __________ ********* * scanf * ********* Usage scanf(fmt, pointer(s)) char *fmt; /* Format string */ fscanf(fd, fmt, pointer(s)) FILE *fd; /* Input file pointer */ char *fmt; /* Format string */ sscanf(buf, fmt, pointer(s)) char *buf; /* Input text buffer */ char *fmt; /* Format string */ $$scan(fmt, argp, iov) char *fmt; /* Format string */ int *ptr[]; /* Pointer vector */ FILE *iov; /* Input file des. */ Description Using the format string, these functions parse the input file (or given text file), storing the results in the pointer arguments. The three user-callable routines differ as follows: scanf Reads from the standard input file. fscanf Reads from the indicated file. sscanf Reads from the text buffer. $$scan() is an internal routine called by the above to actually parse the input text. It is functionally identical to the Unix and Vax-11 C _doscan() routine. Unfortunately, the leading '_' conflicts with RSX file control service routine naming conventions. The format string may contain control characters to direct the conversion of the input textual data: ' ' Blanks, tabs, or newlines are ignored in format strings. To match whitespace, use "%[ \t\n]". x An ordinary character (not %) must match the next input character. C Runtime Support Library Page 3-134 scanf Formatted input conversion % Conversion specifications consist of a '%', an optional '*' (to supress assignment), an optional maximum numeric field width, and a conversion specifier. Unless value assignment was supressed by the '*' format modifier, the next field is converted and stored in the variable pointed to by the corresponding argument. An input field is defined as a string of non-space characters, extending to the first inappropriate character or until the field width (if given) is exhausted. The following conversion characters are specified: % A single '%' is expected in the input, no assignment is done. d An integer of the specified class (decimal, o octal, or hexadecimal) is expected. The x corresponding argument should be an integer pointer. If the format specifer is given in upper-case, or preceeded by 'l', a long integer will be stored. For example, "%ld" is identical to "%D". Leading whitespace will be ignored. A null field is not converted. Scanf() returns a count of the number of fields converted, but does not indicate which fields were ignored. s A character string is expected. The input field will be terminated by a space, tab, or newline. The corresponding argument should point to a buffer large enough to contain the text and a terminating NULL. Leading whitespace will be ignored. c A single character is read. Leading white space is not supressed -- to read the next non-blank character, use "%1s". If a field width is given the corresponding argument is a pointer to a vector of characters and the indicated number of characters are read. e A floating-point number is converted and stored f appropriately. If the format indicator is g capitalized, or preceeded by 'l', a double- precision floating-point number will be stored. The floating-point format is the same as in the C language: an optionally signed string of digits possibly containing a decimal point, followed by an optional exponent field which consists of an 'E' or 'e' followed by an optionally signed integer. C Runtime Support Library Page 3-135 scanf Formatted input conversion [ ] A string not to be delimited by white-space characters. Unless the first character is '^', the format constitutes an acceptance list: the input field is all characters until the first character which is not in the set within brackets. Note that leading whitespace is not ignored. If the first character after the left bracket is '^', the format defines a stop list: the input field is all characters until the first character specified within the bracketed string. The corresponding argument points to a character vector. The result will be null-terminated. Scanf() returns the number of successfully matched and assigned input items. If the end of input was reached, EOF (-1) is returned. For example: main() { register int c; int i; char text[10]; c = scanf("%d%9s", &i, &text); printf("i = %d, text = %s\n", i, text); } If the input line is "150 foobar", the program will print: i = 150, text = foobar Diagnostics Scanf() returns -1 if an end of file (end of string) condition exists and no data was stored. It returns -2 if a palpably incorrect format, such as "%" is encountered. Bugs C Runtime Support Library Page 3-136 screen Screen I/O Primitives 3.111 Screen I/O Primitives ______ ___ __________ ********** * screen * ********** Usage scdown() /* Roll screen down */ scerln(line, column) /* Erase to end of line */ int line; /* Line number */ int column; /* Column number */ scerpg(line, column) /* Erase to end of page */ int line; /* Line number */ int column; /* Column number */ char * scget(buff, size, text) /* Prompt and read */ char *buff; /* Returned text */ int size; /* Buffer size */ char *text; /* Optional prompt */ int sclmargin(lmarg) /* Set left margin */ int lmarg; /* New left margin */ scout(line, column, text) /* Write text to screen */ int line; /* Line number */ int column; /* Column number */ char *text; /* Text to write */ scput(oldbf) /* Reset buffer mode */ char *oldbf; /* Previous buffer */ int scset(newbf, size, old) /* Set buffer mode */ char *newbf; /* New buffer */ char size; /* Size of new buffer */ char **old; /* Previous buffer save */ C Runtime Support Library Page 3-137 screen Screen I/O Primitives int scsettype(type) /* Force terminal type */ int type; /* Terminal type */ int sctype() /* Return terminal type */ Description Based on the "terminal independent screen procedures" in the VAX/VMS runtime library, these routines provide an efficient, operating-system independent, interface to (DIGITAL) video terminals. They work correctly with VT52 and VT100 (ANSI) terminals and do nothing disasterous if the terminal is not a video terminal. Note that they only work with the user's console (stderr) terminal. The following definitions should be noted: line The line on the screen to which the cursor is to be moved. The top of the screen is line one. If line is less than or equal to zero, the cursor does not move. column The column to which the cursor is to be moved. This value will be offset by the left-margin value (if one is set). The default left-hand margin is column one. If column (after offsetting) is less than or equal to zero, the cursor does not move. text A null-terminated string to be output. If text equals NULL, nothing is output and internal buffers are flushed. The routines are designed to operate in a buffered mode, allowing the program to format an entire screen of information and present this data with one call to the monitor-level I/O service. This is particularily efficient on multi-user or networked systems. The routines scput() and scset() establish and release buffer mode. Buffers can be chained together, allowing a subroutine to establish a buffer independently of its callers. Each buffer must be at least 12 bytes long. Longer buffers are more efficient. Although multiple buffers can be established, only one is active at any particular time. If a call to scset() C Runtime Support Library Page 3-138 screen Screen I/O Primitives establishes a new buffer, the contents of the previous buffer are copied to the new buffer and the previous buffer is set empty. If scput() releases a buffer, its contents are copied to any higher-level buffer. The first call to any routine determines the terminal type. Note that on native RT11, if the screen handler decides that the terminal may be a scope, it will send an "identify" request "/Z" to determine whether it is a VT52 or VT100. If the screen routine decides that the terminal is not a scope, cursor move operations are ignored and text is output to "stderr". If the screen handler decides that the terminal is a VT100, the "Enter ANSI mode" escape sequence will be sent to the terminal. Similarily, if the terminal is thought to be a VT52, the "Enter VT52 emulation mode" sequence will be sent. The screen handler will not record the current mode for subsequent resetting. Screen output will be to the "stderr" device (explicitly the console terminal). Input will be from the "stdin" device. If a local buffer has been established, the screen handler calls operating system service directly, bypassing the "standard" I/O library. This means that output formatting should use sprintf() to format a user buffer which is subsequently output using scout(). Furthermore, the newline '\n' character will not be expanded to a "carriage return/line feed" sequence. It is thus highly recommended that the user program perform all formatting by passing appropriate row and column values to scout(). The following routines are defined: scdown() The cursor is moved up one line on the screen. If the cursor was already at the top line on the screen, all lines are moved down one line, the top line is replaced with a blank, and the data that was on the bottom line is lost. (VMS Lib$Down_Scroll) scerln(line, column) Erase the screen from the indicated (or current) cursor position to the end of the current line. (VMS Lib$Erase_Line) scerpg(line, column) Erase the screen from the indicated (or current) cursor C Runtime Support Library Page 3-139 screen Screen I/O Primitives position to the end of the screen. (VMS Lib$Erase_Page) scget(buff, size, text) Output the prompt text, if given, then flush any buffered text. Read text input by the terminal user (from stdin) to the buffer. Scget() returns NULL on end of file or error. (Scget calls fgetss() to perform the read.) (VMS Lib$Get_Screen) Programs using scget() to read from the keyboard should not use the input redirection capabilities of the C library. sclmargin(lmarg) Define a new left margin (if lmarg is greater than zero). Sclmargin() returns the old lmarg value. After calling sclmargin(), an output request to column one will be written to column lmarg. scout(line, column, text) Move the cursor to the indicated line and column and output the text. If line or column are less than or equal to zero, the cursor is not moved. If text is equal to NULL, the internal buffers are flushed (possibly after cursor movement). (VMS Lib$Put_Screen) scput(oldbf) Scput() terminates the current buffering mode and reverts to the previous mode as specified in the parameter. If oldbuf is NULL, buffering is terminated and the current buffer is flushed to the screen. If oldbuf is not zero, it is taken as the location of a previous buffer (established by calling scset()) and the current buffer is copied into the previous buffer. The previous buffer is then made current. (VMS Lib$Put_Buffer) scset(newbf, size, old) Scset() establishes a new buffer for the screen routines. Newbf is a character array whose size is given in parameter size (Size must be at least 12 bytes.) Old is the address of a word which will be set to the previous buffer (if any). This is used for a subsequent call to scput(). Scset returns zero if correct, returning -1 if size was less than 12 bytes. (VMS Lib$Set_Buffer). C Runtime Support Library Page 3-140 screen Screen I/O Primitives A larger buffer will generally yield a more efficient program as the number of operating system requests will be minimized. For example, for a typeout program, a buffer size of 800 bytes might well be used. scsettype(type) This routine sets the terminal type, overriding the definition supplied by the operating system. scsettype() returns what it thought the type was (as if sctype were called). The type must be one of the following values: 0 Not a video terminal 65 VT52 or VT100 in VT52 mode 97 VT100 in ANSI mode If type has some other value, scsettype() does not change the type. sctype() This routine returns the terminal type. The following types are defined: 0 Not a video terminal 1 Unknown video terminal 1+64 VT52 1+96 VT100 type Note: On intitialization, a VT100 will be forced into VT52 or VT100 mode depending on the determined type. VT100-type terminals include newer terminals such as the VT125. It is not clear whether the algorithm used is correct for terminals developed since these routines were written. Note the following normal use of scset() and scput() char **oldbuf; char mybuf[100]; main() { /* * Setup */ scset(mybuf, sizeof mybuf, &oldbuf); /* * Usage */ scout(1, 1, "Stuff"); C Runtime Support Library Page 3-141 screen Screen I/O Primitives /* * Termination (force out last buffer) */ scout(0, 0, NULL); scput(oldbuf); } Bugs These routines are fairly inefficient if no buffer is supplied. Determining the terminal type turns out to be a somewhat painful process which is different for the various operating systems: On native RSX-11M and VMS compatibility mode, the QIO "get multiple characteristics function" is executed. If the terminal is a scope and can generate escape sequences, it is assumed to be a VT100, otherwise, if it is a scope, it is assumed to be a VT52. On all RSTS/E systems, the executive "get terminal characteristics" request is executed, the determination proceeding as above. On native RT11 systems, a peek sequence described in the RT11 Software Support manual is used to determine whether the terminal is a scope. (This may not work on the XM monitor.) If so, an "/Z" is sent to request identification and various tests are made on the returned text. Note that, if the terminal does not reply to the inquiry, the program will hang. These tests are valid for VT52 and VT100 terminals only. You will have to modify this routine if you have anything else (including a VT125). On RSX-11M systems (even emulated), if a local buffer is established by calling scset(), output will be done using the IO.WAL QIO function. While based on the VMS Run-time library screen I/O primitives, there are a few differences that may be of interest: The VMS library standard assumes that subroutines generally return a status code, permit missing parameters, and return error codes on being presented with invalid arguments. The routines described here do nothing when arguments are out of range. Also, there are no optional arguments (optionality is provided for by specifing zero or NULL argument values). Where C Runtime Support Library Page 3-142 screen Screen I/O Primitives appropriate, arguments have been ordered "line_no, col_no, other". A more significant difference is that the VMS library writes to the standard output device (SYS$OUTPUT: or TT:) while these routines write to the user's terminal (SYS$ERROR or CO:). scget() reads from the standard input. C Runtime Support Library Page 3-143 setcc Trap Control/C (RSTS/E RT11 mode only) 3.112 Trap Control/C (RSTS/E RT11 mode only) ____ _________ _______ ____ ____ _____ ********* * setcc * ********* Usage setcc(function); extern int function(); Description The function is defined as a CTRL/C trap routine. Executing setcc(0) disables CTRL/C trapping. Note: If the routine is reentered (because CTRL/C was typed during the execution of function()), the program aborts. Bugs Runs on RSTS/E RT11 mode only. C Runtime Support Library Page 3-144 setjmp Execute non-local goto 3.113 Execute non-local goto _______ _________ ____ ********** * setjmp * ********** Usage #include setjmp(env); jmp_buf env; /* Static save buffer */ longjmp(env, val) jmp_buf env; /* Was set by setjmp */ int val; /* Value to return */ Description: These routines are useful for dealing with errors and interrupts encountered in a low-level subroutine of a program. Setjmp() saves its stack environment in env for later use by unwind(). It returns 0. Longjmp(env) restores the environment saved by the last call of setjmp(env). It then returns in such a way that execution continues as if the call of setjmp() had just returned. All accessible data have values as of the time setjmp() was called. The return from setexit() will have the specified value. For example: #include jmp_buf env; ... main() { ... if (setjmp(&env) != 0) { err_exit(); /* Longjmp called */ } else { process(); /* Setjmp called */ } ... process() { ... longjmp(&env); The routine that called setjmp() must still be active when longjmp() is called. C Runtime Support Library Page 3-145 setjmp Execute non-local goto Bugs C Runtime Support Library Page 3-146 sleep Delay job a given number of seconds 3.114 Delay job a given number of seconds _____ ___ _ _____ ______ __ _______ ********* * sleep * ********* Usage sleep(delay); int delay; Description Sleep a specified number of seconds. Bugs On RSTS/E, the reader should refer to the description of SLEEP() in the operating system documentation. On native RSX-11M or RSX emulated by VMS, sleep() executes a mark-time (MRKT$) and wait sequence, using event flag 1. On native RT11, sleep() executes a .TWAIT executive request. Sleep flushes stdout and stderr. C Runtime Support Library Page 3-147 sprintf Formatted Numeric Conversion 3.115 Formatted Numeric Conversion _________ _______ __________ *********** * sprintf * *********** Usage char * sprintf(buffer, format, arg1, ...); char *buffer; char *format; Description sprintf() converts and formats its arguments, writing the result to the indicated string buffer. For information on formatting, please refer to the description of printf. sprintf() returns a pointer to the EOS byte at the end of the output buffer. Note, however, that this feature is not transportable to other C implementations. Bugs C Runtime Support Library Page 3-148 sscanf Formatted input conversion 3.116 Formatted input conversion _________ _____ __________ ********** * sscanf * ********** Usage sscanf(buf, fmt, pointer(s)) char *buf; /* Output buffer */ char *fmt; /* Format string */ Description sscanf() parses the input string, in buf, according to the indicated format descriptor, storing the results in the pointer arguments. It returns the number of successfully assigned input items. See the description of scanf() for further documentation. Diagnostics Sscanf() returns -1 if the end of the input string was detected and no data was stored. It returns -2 if a palpably incorrect format, such as "%" is encountered. Bugs C Runtime Support Library Page 3-149 strcat String Concatenate 3.117 String Concatenate ______ ___________ ********** * strcat * ********** Usage char * strcat(out, in); char *out; char *in; Description Append "in" to "out". Return out. Bugs C Runtime Support Library Page 3-150 strchr Find First Instance of a Character in a String 3.118 Find First Instance of a Character in a String ____ _____ ________ __ _ _________ __ _ ______ ********** * strchr * ********** Usage char * strchr(stng, chr) char *stng; /* String to search in */ char chr; /* Byte to search for */ Description If chr is in stng, return a pointer to it. If not, return NULL. strchr(NULL, anything) returns NULL. See also index(). Bugs C Runtime Support Library Page 3-151 strcmp String Compare 3.119 String Compare ______ _______ ********** * strcmp * ********** Usage int strcmp(s1, s2); char *s1; char *s2; Description Compare two strings, returning -1 if s1 < s2 0 if s1 == s2 +1 if s1 > s2 Bugs C Runtime Support Library Page 3-152 strcpy String copy 3.120 String copy ______ ____ ********** * strcpy * ********** Usage char * strcpy(out, in); char *out; char *in; Description Copy "in" to "out". Return out. Bugs It might be more useful if it returned out + strlen(in). (See cpystr()). C Runtime Support Library Page 3-153 streq String Equality Test 3.121 String Equality Test ______ ________ ____ ********* * streq * ********* Usage streq(a, b); char *a; char *b; Description Return TRUE if the strings are equal. Bugs C Runtime Support Library Page 3-154 strlen String length 3.122 String length ______ ______ ********** * strlen * ********** Usage int strlen(s); char *s; Description Return the length of the argument string. Bugs C Runtime Support Library Page 3-155 strncat String Concatenate 3.123 String Concatenate ______ ___________ *********** * strncat * *********** Usage char * strncat(out, in, count); char *out; char *in; unsigned int count; Description Append "in" to "out". Return out. At most, "count" bytes are moved from in. Note that "count" does not include the trailing null. Bugs C Runtime Support Library Page 3-156 strncmp String Compare With Count 3.124 String Compare With Count ______ _______ ____ _____ *********** * strncmp * *********** Usage int strncmp(s1, s2, count); char *s1; char *s2; unsigned int count; Description Compare at most count bytes between two strings, returning: -1 if s1 < s2 0 if s1 == s2 +1 if s1 > s2 Bugs C Runtime Support Library Page 3-157 strncpy String Copy With Count 3.125 String Copy With Count ______ ____ ____ _____ *********** * strncpy * *********** Usage char * strncpy(out, in, count); char *out; char *in; unsigned int count; Description Copy "in" to "out". Return out. At most, "count" bytes are moved from in. Note that "count" includes the trailing null. If strlen(in) is less than count, "out" is null-filled. If strlen(in) is greater than count, the output buffer will not be null-trailed. Bugs C Runtime Support Library Page 3-158 strneq String Equality Test With Count 3.126 String Equality Test With Count ______ ________ ____ ____ _____ ********** * strneq * ********** Usage int strneq(s1, s2, count); char *s1; char *s2; unsigned int count; Description Compare at most count bytes between two strings, returning TRUE if the the strings are equal. Bugs C Runtime Support Library Page 3-159 strrchr Find Last Instance of a Character in a String 3.127 Find Last Instance of a Character in a String ____ ____ ________ __ _ _________ __ _ ______ *********** * strrchr * *********** Usage char * strrchr(stng, chr) char *stng; /* String to search in */ char chr; /* Byte to search for */ Description If chr is in stng, return a pointer to the last (rightmost) occurrance of it. If not, return NULL. strchr(NULL, chr) returns NULL. Bugs C Runtime Support Library Page 3-160 swabb Byte swap (argument is a buffer pointer) 3.128 Byte swap (argument is a buffer pointer) ____ ____ _________ __ _ ______ ________ ********* * swabb * ********* Usage swabb(buffer); char *buffer; Description: Return buffer[0] and buffer[1] as a byte-swapped integer. Buffer need not be on any particular byte or word boundary. Bugs C Runtime Support Library Page 3-161 swabi Byte swap, (argument is an integer) 3.129 Byte swap, (argument is an integer) ____ _____ _________ __ __ ________ ********* * swabi * ********* Usage swabi(value); int value; Description Return value byte-swab'ed. Bugs C Runtime Support Library Page 3-162 time Compute time of day 3.130 Compute time of day _______ ____ __ ___ ******** * time * ******** Usage long time(0); long time(tloc); long *tloc; Description time returns the time of day in seconds. If tloc is non-null, the return value is also stored in the place to which tloc points. The value is the time since midnite, Jan 1, 1970, measured in seconds. Bugs The Unix time function returns GMT. This function returns local time. The leap year algorithm is only accurate in the range 1970 <= year < 2100 C Runtime Support Library Page 3-163 toascii Convert to 7-bit Ascii 3.131 Convert to 7-bit Ascii _______ __ _____ _____ *********** * toascii * *********** Usage toascii(c); int c; Description Remove the parity bit from c. Bugs C Runtime Support Library Page 3-164 tod Compute time of day 3.132 Compute time of day _______ ____ __ ___ ******* * tod * ******* Usage long tod(0); long tod(tloc); long *tloc; Description tod() returns the time of day in seconds. If tloc is non-null, the return value is also stored in the place to which tloc points. tod() is fairly fast. time() computes the "Unix time" but is much slower and larger. Bugs C Runtime Support Library Page 3-165 tolower Convert upper-case to lower-case 3.133 Convert upper-case to lower-case _______ __________ __ __________ *********** * tolower * *********** Usage tolower(c); int c; Description If c is a upper-case alphabetic, return it's lower-case equivalent. Otherwise, return c. Bugs C Runtime Support Library Page 3-166 toupper Convert lower-case alphabetic to upper-case 3.134 Convert lower-case alphabetic to upper-case _______ __________ __________ __ __________ *********** * toupper * *********** Usage toupper(c); int c; Description If c is a lower-case alphabetic, return it's upper-case equivalent. Otherwise, return c. Bugs C Runtime Support Library Page 3-167 trace Profile support entry module (with trace) 3.135 Profile support entry module (with trace) _______ _______ _____ ______ _____ ______ ********* * trace * ********* Usage #include extern FILE *$$flow; $$flow = fopen("trace.out", "w"); /* or $$flow = stderr; to trace to the console */ ... $$flow = NULL; /* Turn off flow trace */ Description This module is called whenever a function that was compiled with the profile option is executed. It checks that the stack will remain above 600 octal when the function executes and optionally prints a flow-trace. If $$flow is set to a file descriptor, the function name, location the function is called from, and the calling environment, are printed on each call to a function compiled with the profile option. The output format is: function_namecallerenvironment Where function_name is the name of the function being called, caller is the address of the calling program (actually, the return address), and environment is the R5 argument pointer (for local addressing within the routine being called). The information will be written to $$flow with a newline before and after. If profiling has been enabled and the program exits via error() or via an operating-system trap (such as an illegal memory reference), a register dump and subroutine trace will be written to stderr. See the description of calltrace() for details. Bugs C Runtime Support Library Page 3-168 traps Operating system trap handlers 3.136 Operating system trap handlers _________ ______ ____ ________ ********* * traps * ********* Usage Internal $$sstt:: ; RSX synchronous trap ; vector $$t410:: ; RT11 Entry after traps ; to vectors 4 and 10 Description This module contains code which is executed after a synchronous trap is detected by the operating system. All such traps are regarded as fatal errors and the program will be terminated. This code is enabled by executing any function, such as main(), for which profiling was enabled when the function was compiled. The following traps are processed: Illegal memory reference (trap through vector 4) Illegal instruction (trap through vector 10) BPT (assuming a debugging aid is not present) IOT Illegal TRAP (this may be a Fortran error) Illegal EMT (RSX only) Floating point exception (RSX only) Memory management violation Before exiting to the operating system, the registers at the time the trap occurred will be written, in octal, to stdout. Note also that a calling sequence traceback will be written to stdout by error(). If a trap occurred, the program will exit to the operating system with a "severe error" status. Note that some errors, such as stack overflow or random jumps into the operating system, may cause the C program to be terminated without the C library regaining control. C Runtime Support Library Page 3-169 traps Operating system trap handlers Internal The first call to pcsv$ will initialze trapping. On RSX11-M, the SVTK$ executive service will be called. On RT11, the .tprset monitor request will be executed. As .trpset only traps illegal memory reference (trap to 4) and illegal instruction (trap to 10), the other interesting vectors are initialized by absolute references (.ASECT). Diagnostics Bugs Internal Don't forget to handle floating-point when it's implemented. C Runtime Support Library Page 3-170 ungetc Push back a character onto an input file 3.137 Push back a character onto an input file ____ ____ _ _________ ____ __ _____ ____ ********** * ungetc * ********** Usage ungetc(c, iop); char c; FILE *iop; Description Push one character back on the indicated stream. Bugs C Runtime Support Library Page 3-171 unwind Execute non-local goto 3.138 Execute non-local goto _______ _________ ____ ********** * unwind * ********** Usage setexit(); unwind(); Description: These routines are useful for dealing with errors and interrupts encountered in a low-level subroutine of a program. setexit() saves its stack environment in a static place for later use by unwind(). It returns 0. Unwind() restores the environment saved by the last call of setexit(). It then returns in such a way that execution continues as if the call of setexit() had just returned. All accessible data have values as of the time unwind() was called. The return from setexit() will have the value 1. For example: if (setexit()) { /* Unwind called */ } else { /* Setexit setup called */ } The routine that called setexit() must still be active when unwind() is called. Bugs Obsolete -- use setjmp/longjmp instead. C Runtime Support Library Page 3-172 wdleng Expensive way to say sizeof(int) 3.139 Expensive way to say sizeof(int) _________ ___ __ ___ ___________ ********** * wdleng * ********** Usage wdleng() Description Return word length in bits. Bugs Assuming 8-bit bytes, this may be replaced by: #define wdleng() (sizeof (int) * 8) C Runtime Support Library Page 3-173 wrapup Dummy routine called on exit 3.140 Dummy routine called on exit _____ _______ ______ __ ____ ********** * wrapup * ********** Usage wrapup() Description This routine (which does nothing) is called on exit if the user's program does not provide a wrapup() routine. Wrapup will be called only once. Bugs C Runtime Support Library Page 3-174 zero Clear a block of memory 3.141 Clear a block of memory _____ _ _____ __ ______ ******** * zero * ******** Usage zero(addr, nbytes); char *addr; unsigned int nbytes; Description: Clear the block of core. No value is returned. Bugs