## Reading and Writing From Files

A single file type and format is used for all mass storage files. Files store an ordered sequence of 8-bit bytes. OS-9 is not usually sensitive to the contents of files for most functions. A given file may store a machine language program, characters of text, or almost anything else. Data is written to and read from files exactly as given. The file can be any size from zero up to the maximum capacity of the storage device, and can be expanded or shortened as desired.

When a file is created or opened a “file pointer” is established for it. Bytes within the file are addressed like memory, and the file pointer holds the “address” of the next byte in the file to be written to or read from. The OS-9 “read” and “write” service functions always update the pointer as data transfers are performed. Therefore, successive read or write operations will perform sequential data transfers.

Any part of a file can also be read or written in non-sequential order by using a function called “seek” to reposition the file pointer to any byte address in the file. This is used when random access of the data is desired.

To expand a file, you can simply write past the previous end of the file. Reading up to the last byte of a file will cause the next “read” request to return an end-of-file status.

### File Usage in OS-9

Even though there is physically only one type of file, the logical usage of files in OS-9 covers a broad spectrum. Because all OS-9 files have the same physical type, commands such as copy, del, etc., can be used with any file regardless of its logical usage. Similarly, a particular file can be treated as having a different logical usage at different times by different programs. The main usage of files covered in this section are:

TEXT
RANDOM ACCESS DATA
EXECUTABLE PROGRAM MODULES
DIRECTORIES
MISCELLANEOUS

### Text Files

These files contain variable-length sequences (“lines”) of ASCII characters. Each line is terminated by a carriage return character. Text files are used for program source code, procedure files, messages, documentation, etc. The Text Editor operates on this file format.

Text files are usually read sequentially, and are supported by almost all high-level languages (such as BASIC09 READ and WRITE statements). Even though is is possible to randomly access data at any location within a text file, it is rarely done in practice because each line is variable length and it is hard to locate the beginning of each line without actually reading the data to locate carriage return characters.

The content of text files may be examined using the list command.

### Random Access Data Files

Random-access data files are created and used primarily from within high-level languages such as Basic09, Pascal, C, and Cobol. In Basic09 and Pascal, “GET”, “PUT”, and “SEEK” functions operate on random-access files.

The file is organized as an ordered sequence of “records”. Each record has exactly the same length, so given a record's numerical index, the record's beginning address within the file can be computed by multiplying the record number by the number of bytes used for each record. Thus, records can be directly accessed in any order.

In most cases, the high-level language allows each record to be subdivided into “fields”. Each field generally has a fixed length and usage for all records within the file. For example, the first field of a record may be defined as being 25 text characters, the next field may be two bytes long and used to hold 16-bit binary numbers, etc.

It is important to understand that OS-9 itself does not directly process or deal with records other than providing the basic file functions required by all high-level languages to create and use random-access files.

### Executable Program Module Files

These files are used to hold program modules generated by the assembler or compiled by high-level languages. Each file may contain one or more program modules.

OS-9 program modules resident in memory have a standard module format that, besides the object code, includes a “module header” and a CRC check value. Program module(s) stored in files contain exact binary copies of the programs as they will exist in memory, and not one byte more. OS-9 does not require a “load record” system commonly used by other operating systems because OS-9 programs are position-independent code and therefore do not have to be loaded into specific memory addresses.

In order for OS-9 to load the program module(s) from a file, the file itself must have execute permission and each module must have a valid module header and CRC check value. If a program module has been altered in any way, either as a file or in memory, its CRC check value will be incorrect And OS-9 will refuse to load the module. The verify command can be used to check the correctness of the check values, and update them to corrected values if necessary.

On Level One systems, if a file has two or more modules, they are treated as independent entities after loading and reside at different memory regions. On Level Two systems, two or more modules loaded from the same file comprise a “group”, are always assigned contiguous memory locations, and are treated somewhat collectively. (See the section called “Loading Multiple Programs”)

Like other files that contain “binary” data, attempts to “list” program files will result in the display of random characters on the terminal giving strange effects. The dump command can be used to safely examine the contents of this kind of file in hexadecimal and controlled ASCII format.

### Directory Files

Directory files play a key role in the OS-9 file system. They can only be created by the makdir command, and can be identified by the “d” attribute being set (see the section called “Examining and Changing File Attributes”). The file is organized into 32-byte records. Each record can be a directory entry. The first 29 bytes of the record is a string of characters which is the file name. The last character of the name has its sign bit (most significant bit) set. If the record is not in use the first character position will have the value zero. The last three bytes of the record is a 24-bit binary number which is the logical sector number where the file header record (see the section called “Physical File Organization”) is located.

The makdir command initializes all records in a new directory to be unused entries except for the first two entries. These entries have the names `.` and `..` along with the logical sector numbers of the directory and its parent directory, respectively (see the section called “Anonymous Directory Names”).

Directories cannot be copied or listed - the dir command is used instead. Directories also cannot be deleted directly (see the section called “Deleting Directory Files”).

### Miscellaneous File Usage

OS-9's basic file functions are so versatile it is possible to devise an almost unlimited number of special-purpose file formats for particular applications, which do not fit into any of the three previously discussed categories.

Examples of this category are COBOL Indexed Sequential (ISAM) files and some special word processor file formats which allow random access of text lines. As discussed in Sec. 3.9.1, most OS-9 utility commands work with any file format including these special types. In general, the dump command is the preferred method for examining the contents of unusually formatted files.

### Record Lockout (Level Two Only)

When a file is accessed by two or more processes simultaneously, the possibility exists that they may attempt to update the same record of the file at the same time, with unpredictable results. To avoid this potential problem, OS-9 Level Two automatically “locks” sections of all files opened in “update” mode. The lock covers any disk sectors containing the bytes last read by each process accessing the file. If another process attempts to access a locked portion of a file, the process is put to sleep until the area is no longer locked.

A lock is moved when the locking process reads or writes an area of the same file outside the previously locked section. They are terminated when the process associated with the lock closes its path to the file. Each process can lock one area per file (but cna have locks on more than one file).

An entire file can be locked by activating its “sharable” bit (see the section called “Examining and Changing File Attributes”). When this attribute is on, only one process may open a path to the file at any given time. Any other processes attempting to access the file will receive an error code.