TOC PREV NEXT INDEX DOC LIST MASTER INDEX



Files and I/O

This chapter describes file access and I/O as performed using Rational Apex. Sections include:


Predefined I/O Packages

Implementation-dependent aspects of the Ada-predefined I/O packages are described in Input/Output Packages in the Ada Compiler Reference Guide.

POSIX.5 describes how the predefined I/O packages should manage files and I/O, but leaves room for interpretations and implementation decisions. This chapter includes descriptions of how Rational Apex performs in comparison to POSIX.5.


Opening and Creating Files

This section discusses:

Form Parameter for Create and Open Procedures

POSIX.5 specifies that the Form parameter on Create and Open procedures that perform text I/O should have a specific set of legal values (POSIX.5 8.1.1.2). Apex supports those values as described in the following subsections:

Note: Form parameter is not supported on VxWorks or Rational Exec.

Syntax of the Form Parameter

The Form parameter can contain a string consisting of the following fields:

Field Defaults

Two default sets are defined for the Form parameter: the POSIX default set and the Apex default set. Both sets are shown in Table 3.

To select the POSIX default set, use pragma Main with its Posix_Compliant argument set to True. This is the default. In this case, the Ada-predefined I/O routines behave as required by POSIX.5 and as modified by the descriptions in this chapter.

The Apex default set is selected when Posix_Compliant is set to False. In this case, Ada-predefined I/O provides upward compatibility with Apex releases prior to 1.2.

Table 3 Default Values of Form Parameter
Field
POSIX defaults
Apex defaults
Append
False
False
Blocking
Program
Program
File_Descriptor
-11
-1a
File_Structure
Regular
Regular
Group
Read_Write_Execute
Read_Write
Other
Read_Write_Execute
Read
Owner
Read_Write_Execute
Read_Write
Page_Terminators
True
True
Replace
False
True
Resolve_Path
True
False
Terminal_Input
Lines
Lines
Truncate
Client_Dependent
Client_Dependent
1 Error file descriptor.

Descriptions

All fields are allowed for all Create and Open procedures in packages Text_Io, Sequential_Io, and Direct_Io, unless otherwise specified.

Each field can appear only once in any given Form parameter. If a field appears more than once, Use_Error is raised. Note that Owner, Group, and Other can all appear in the same Form parameter.

The field names can be abbreviated. The abbreviated names are treated in POSIX.5 terms as implementation-defined fields having the same functionality as the full POSIX.5 defined field names.


Warning: The subprograms of Posix_Supplement_To_Ada_Io do not recognize abbreviations. To ensure POSIX.5 compliance, it is recommended that your program use the full field names.

The valid fields are:

Append
specifies whether to write output at the end of the named file. If True, output is appended after the file is opened; otherwise, output is handled according to the Truncate field's value. Allowed only for the Open procedures and only in packages Text_Io and Sequential_Io. Operates as described by POSIX.5, and inAdding Output to Files.
Blocking
specifies whether tasks will perform blocking I/O on the named file. Tasks and Program are specified by POSIX.5. None is implementation-defined and means that all tasks will perform nonblocking I/O on this file. Program and None can be used on all file types while Tasks can be used only on files corresponding to TTY devices. Operates as described by POSIX.5, and in Using Blocking and Nonblocking I/O.
File_Descriptor
associates a UNIX file-descriptor value with an Ada file. The descriptor must designate an external file that has already been opened using POSIX.5 or UNIX calls. If the external file is not already open, using this field raises Use_Error. If the external file is already open and this field is specified, the Name parameter must still be specified but is ignored. Allowed only for the Open procedures. Operates as described by POSIX.5, and inOpening Files.
File_Structure
specifies the physical structure of the external file to be created. Allowed only for the Create procedures. Operates as described by POSIX.5.
Owner | Group | Other
specifies the access permissions for a created file. Allowed only for the Create procedures. Supported for all file structures. Any combination of Read, Write, and Execute is allowed in any order. For consistency, however, use only the combinations shown in the syntax. The Owner permission must be appropriate for the File_Mode parameter, as described in Owner Access Permissions for File Creation. Operates as described by POSIX.5.
Page_Terminators
specifies whether the created file will contain page terminators. Allowed in package Text_Io only. Operates as described by POSIX.5.
Replace
specifies whether to replace any existing file of the same name when Create is executed. Allowed only for the Create procedures. If True, any existing file is deleted and the new file is created (Ada83 LRM 14.2.1(3), Ada95 LRM A.8.2). If False, Use-Error is raised if a file with the same name already exists (POSIX.5 B.8.3). This is an implementation-defined field as described in Creating Files.
Resolve_Path
specifies whether the Name function should expand the filename to a full pathname. If True, Name returns a full pathname if it can be determined; otherwise, Name returns the name specified for the Open or Create. For a complete description of this field, see Determining a File's Name on page 118. This is an implementation-defined field.
Terminal_Input
specifies how to process terminal input. Allowed in package Text_Io only. Operates as described by POSIX.5.
Truncate
works in conjunction with the Append field to specify whether existing records should be removed from a file when it is opened or reset as described in Adding Output to Files on page 114.

Creating Files

The Create procedures in the predefined I/O packages always create a new file. If a file with the same name already exists when Create executes, setting the Form parameter's Replace field determines whether to replace the file or to raise an exception.

Owner Access Permissions for File Creation

The Create procedures allow you to set access permissions for a newly created file with the Form parameter's Owner, Group, and Other fields.

Permissions are granted only as allowed by the operating system. If higher access permission is requested than is available, Create grants only the highest allowed permission. No warning is generated.

If the Owner permissions are not appropriate for the value specified for the Mode parameter, the Create operation will create the file and then raise the Use_Error exception without opening the file. Specific cases include:

Note: By contrast, the UNIX open call using O_CREAT as the flag value opens the file even if the Owner permissions aren't appropriate. The Apex strategy, however, ensures consistent behavior for regular and FIFO files.

Opening Files

POSIX.5 allows files to be opened in two ways:

The former is achieved by calling Open without the Form parameter's File_Descriptor field, whether or not the file was previously opened by any other operation. The latter is achieved by calling Open with a File_Descriptor.

POSIX.5 does not clearly describe the impact during an Open of associating an Ada file with a file descriptor, and the effect of subsequent I/O operations on such files is not specified at all.

Apex attempts to make such files act as ordinary Ada files when the Ada-predefined I/O packages operate on them. The seek pointer and file flags are set as if the file is an ordinary, named Ada file. In particular, the Form parameter's Append, Blocking, Page_Terminator, Truncate, and Terminal_Input fields have the usual effect. Ada-predefined I/O might leave the file descriptor in a state different than it was before it was associated with an Ada file.

There are differences, however:


Using Special File Types

This section describes:

Using FIFO Special Files

All Ada-predefined I/O packages allow access to FIFO special files (POSIX.5 2.2.2.27). However, some I/O operations applied to FIFO files behave in unexpected ways or are not supported.

Unsupported operations that raise the Use_Error exception include:

Operations with unexpected results include:

Using Files Associated with Terminal Devices

The following Form-parameter field values, when applied to a file associated with a terminal device, affect the device in addition to the file:

Opening a terminal device with one of these field values might adversely affect other files already associated with the device. In Apex, the Ada-predefined I/O routines keep track of these side effects only as far as necessary to maintain internal consistency. A program that does not take the side effects into account is considered erroneous.


File I/O

This section describes:

Adding Output to Files

When Open or Reset is called on an existing file opened for output, you must decide how to apply new output:

POSIX.5 provides the Form parameter's Append field to specify whether to append new output after opening a file with an Out_File Mode.

POSIX.5 does not specify what to do, however, if Append is False, nor whether the Append field from the Open call applies to the resetting of the file with an Out_File Mode.

Apex provides the additional field, Truncate, where True corresponds to truncating existing content and False corresponds to overwriting, assuming that Append is False. Together, these fields affect the Open and Reset procedures as shown in Table 4.

Table 4 Effect of Append and Truncate Fields
Field values
Open behavior
Reset behavior
Append => True,
Truncate => True

Append
Truncate
Append => True,
Truncate => False

Append
Append
Append => False,
Truncate => True

Truncate
Truncate
Append => False,
Truncate => False

Overwrite
Overwrite

The default value of Truncate depends on the kind of I/O to be performed. For files opened by Sequential_Io or Text_Io, the default value is True; for files opened by Direct_Io, the default value is False.

Direct_Io does not support the Append field, but it does support Truncate.

The functions Page, Line, and Col return the page, line, and column numbers as counted since the last Reset or Open. This might correspond to the actual number of pages, lines, or columns in the file, unless Truncate is True and Append is False, in which case the returned values are correct.

Ada83 LRM 14.3(6), Ada95 LRM A.10 states that closing a file will implicitly terminate the current line and the current page; however, Apex does not write explicit end-of-line or end-of-page characters to a file when it is closed.

Note: When Text_Io opens a text file with existing content in Append mode, output appended to the file starts on a new line but not on a new page.

Using Blocking and Nonblocking I/O

Whether tasks perform blocking I/O on a given file is determined by the Form parameter's Blocking field on the Create or Open procedure for the file and by the Nonblocking_Io argument on pragma Main. Blocking and nonblocking I/O is also discussed in I/O in Tasking Programs.

Valid Blocking field values and their meanings are:

Blocking I/O on FIFO Files

When applied to FIFO files, the blocking behavior of Text_Io is unpredictable, so avoid using Text_Io for FIFO file operations. Instead, use Sequential_Io instantiated with a fixed-length string.

Table 5 Nonblocking I/O Summary
I/O routine
File mode
Blocking = tasks
Blocking = none
Create, Open, Reset
In_File or Inout_File
Never blocks
Never blocks
Create, Open, Reset
Out_File
Raises Device_Error if the operation would otherwise block, which should happen only when the file is a broken FIFO, pipe, or communication link.
Close, Delete
n/a
Raises Device_Error if the operation would otherwise block (should never happen).
Write, Put, Put_Line, Set_Col, Set_Line, New_Line, New_Page
Out_File or Inout_File
Causes the calling task to block if the output device is not immediately ready to accept data.
Raises Use_Error if the operation would otherwise block.
Read, Get, Get_Line, Set_Col, Set_Line, Skip_Line,
Skip-_Page,
End_Of_Line,
End_Of_Page

In_File or Inout_File
Causes the calling task to block if no data is immediately available from the input device.
Raises Data_Error if the operation would otherwise block.

Text_Io maintains input as well as output buffers, so Text_Io operations might delay output and read ahead upon input. To keep its input buffer full, Text_Io might actually access the external file even if a Get request could be satisfied solely from data that is already in the buffer. As a result, Text_Io will block more often than necessary upon input from a FIFO file, unless the writer and reader of the file maintain a strict data-exchange protocol.

Setting the Form parameter's Blocking field to None does not prevent this blocking behavior; it just replaces unexpected blocking with unexpected exceptions.

Flushing Text Files

Text files are normally written in units of entire lines, where a complete line includes a line terminator. Before Apex flushes a text file's buffer, explicitly with Flush_Text_Io or implicitly with Flush_All (both of Posix_Supplement_To_Ada_Io), it adds a line terminator to a nonempty buffer that does not already contain a line terminator. Subsequent output using Text_Io starts on a new line.


Warning: Flush_Text_Io and Flush_All on files opened using Text_Io, adds a line terminator without incrementing the line counter or resetting the column counter to 1. To avoid problems, use these procedures only after an entire line has been written using Put_Line or New_Line;. Otherwise, other Text_Io operations might behave in an unexpected manner.

Errors and Exceptions

The End_Error exception (and also End_Of_File = True, if supported) indicates that no more data will ever be available from a file. This exception is raised when, for example, the end of a regular file is reached, a communication link is closed, or a pipe is broken.

The Data_Error exception indicates that no more data is currently available.


Determining a File's Name

Apex supports two different approaches to identifying files using the Name functions found in all Ada-predefined I/O packages: the POSIX approach and the Apex approach.

Ada83 LRM 14.2.1(21), Ada95 LRM A.8.2 states that the Name function should return a string that uniquely identifies the file. To support this, POSIX.5 8.1.1.4(163) suggests that the Name function, when applied to an open file:

In standard Apex, the Name function:

The second approach is more efficient, because it does not have to scan the directory tree for the name of the current working directory.

You can select the approach that you prefer using the Resolve_Path field of the Form parameter. The POSIX.5 approach is achieved by setting Resolve_Path to True; setting it to False achieves the standard Apex approach.

The Name function is POSIX.5-compliant if Resolve_Path is True or if Resolve_Path is False, but files are always opened or created using an absolute pathname.

This field's default changes depending on various factors. Refer to Field Defaults, for more information.


I
/O Deviations from POSIX.5

The generic procedures Flush_Sequential_Io and Flush_Direct_Io of Posix_Supplement_To_Ada_Io are not implemented; calls to these procedures will result in semantic errors.


Rational Software Corporation 
http://www.rational.com
support@rational.com
techpubs@rational.com
Copyright © 1993-2002, Rational Software Corporation. All rights reserved.
TOC PREV NEXT INDEX DOC LIST MASTER INDEX TECHNOTES APEX TIPS