OPEN - open a file or string for I/O.

Alternate entries: .OPEN

Note: See "expl b lib open index" for explanations of individual actions. Explanations of individual actions are also given below.

Usage:

B:
   ret = open( [unit,] filename, action
               [,media ,size, bufsize] );
     or
   ret = open( [unit,] string, action
               [,offset, eos, maxlength]);
C:
   int open([int unit,] const char *filename,
            const char *action [, int media,
            int size, int bufsize] );
     or
   int open([int unit,] char *string,
            const char *action [, int offset, int eos,
            int maxlength] );

Examples:

open( 5, "myfile", "r" );
unit = open( argv[1] & 0777777, "wb" );
unit = open( stringptr, "rs" );

Where:

unit
is an optional argument specifying the number of the unit to be opened. If "unit" is not given, OPEN supplies a unit number. If the indicated "unit" is already open, the current state of the unit is saved on a stack. When the unit is closed, the previous state is restored so that the unit behaves as if there was no interruption.
filename
is an ASCII string containing the name of the file to be opened. A null string is taken as the name of the standard input or output unit (i.e. the device/file currently open on unit 0 or 1). "filename" may be qualified by an altname in quotes, but not by permissions. If the 's' action is used, "filename" is taken as a pointer to a string (see the description of the 's' action below). See "expl b lib acc.fil" for a discussion of file access/create conventions.
action
is an ASCII string of characters chosen from the characters in the list given at the end of this explain file.
media
is a media code of the form "0mmrr" which may be specified for output files. The default is 00600 (Media 6 ASCII, report code zero).
size
specifies the initial and maximum sizes of an output file. This is used if it is necessary to create the file. If "size" is zero, the file will not be created if it is not found. If file creation is performed, the upper 18 bits of "size" give the maximum file size; normally these bits are zero, implying unlimited maximum size. The lower 18 bits give the initial size. If "size" is not given, it defaults to one (unlimited maximum size, initial size one).
bufsize
specifies the number of words to be read/written in each I/O call. For a tape, this is the block size and should not exceed 4096; otherwise, other software may not be able to read the tape. See the Notes section for more on reading tapes. If the specified "bufsize" is less than or equal to 63, it is assumed to specify the size in llinks; for example, a value of 20 indicates 20 llinks (20*320 words). If the specified "bufsize" is greater than or equal to 64, it is assumed to specify the size in words; for example, a value of 320 indicates 320 words (one llink). For a disk, "bufsize" must be multiple of 320, and cannot exceed 20160 (63 llinks) for sequential disk files. The default is 320*8.
maxlength
is the maximum size of the string, either for output or input. For more information, see "Special Rules for Strings" below.
ret
receives the non-negative number of the unit just opened, if OPEN is successful. If the open fails, OPEN will usually terminate your program with an error message and an unconditional abort. The exception occurs when you specify the 'f' action for the OPEN. In this case, "ret" receives a negative status code indicating why the open was unsuccessful. See "status returned" below.

Description:

OPEN is used to prepare an I/O unit either for file input/output or for core-to-core I/O using strings. When OPEN successfully opens an I/O unit, it makes that unit the current read/write unit unless the 'u' action is specified.

If neither 's', 'l', 'i', nor 'b' is specified in the "action" string, it is assumed that the file should be accessed sequentially. Action 'i' without 'b' indicates that the file is to be accessed according to its mode. After OPEN returns, it is up to the programmer to determine whether the file is sequential or random, and to take action appropriate to the mode. The library function FILDES is useful in determining the mode of a file.

Media and Size

The arguments "media" and "size" are significant only when opening files for output. The media and report code of an output file may be specified in a word of the form "0mmrr", where "mm" is the media and "rr" the report code. Possible values for "mmrr" are given below.

0000 : media 0; variable length BCD.
0100 : media 1; COMDKs, and binary records.
0200 : media 2; card image (80 column fixed length) BCD.
0372 : media 3; BCD print image.
0400 : media 4; byte stream file.
0600 : media 6; standard TSS ASCII.
0773 : media 7; ASCII print image.
1200 : media 10; card image ASCII.

Note that the report code "rr" is intended for print image media. It may however be specified for any media code, and may have any value in the range 00-77 (octal).

If you write a media 1 file with character stream routines the output will be written in COMDK format. Variable length binary records may be written with the record output routines.

To minimize load module size, the I/O package is arranged to avoid loading the routines to write any media other than 6. To force the loading of the appropriate set of routines, your function MAIN must include a statement of the form

extrn wr.mcN;
  or
extrn wr.m10;

where "N" is the media code to be written. You use "wr.m10" in order to write ASCII card images (media 10). For example, if you wish to write media 3 you must say

extrn wr.mc3;

One may change the media or report code on an output unit with a call to the function SET.MC. The above remarks on the force loading of appropriate routines again apply.

Status Returned

If the open is successful, OPEN returns a non-negative number which is the unit number of the file or string just opened. That unit is also set as the current read or write unit, provided the 'u' action was not specified.

If there is an error on file create or access, OPEN aborts the program with an error message unless you have specified the 'f' action. If the status is returned, a message is only printed if you have also specified the 'm' action.

In case of error, the status returned is the negative of the file system status. For example, "permissions denied" would result "ret" receiving a value of -3. OPEN makes use of the standard facilities for posting errors. Therefore, a call to .STRER obtains any error messaged posted for the unit, as in

if( (unit = open(argv[1],"rf")) < 0 )
   error( "%s: %s*n", argv[1], .strer(-unit) );

You could also obtain the posted error message with

.strer(.errno)

but this is less dependable. For example, if the user presses BREAK between the time of the OPEN error and the time you call .STRER, the value of .ERRNO may reflect an error that occurred in code executed to handle the BREAK.

In addition to the regular file system statuses, and those faked by ACC.FIL, OPEN may also return a status of -055. This will be returned if the 'f' action is specified for a tape, and the tape is positioned at a partial (i.e. end of data) label.

OPEN returns a "duplicate AFTname" status if you try to open a file that would have the same AFTname as a file the program has already opened. For example, you will get this status if you try

unit1 = open("fc**xx","w");
unit2 = open("fc**xx","r");

You can use the "zd" option to override this check.

Special Rules for Strings

If the 's' action is specified, OPEN opens "filename" for core-to-core I/O. In this case, the arguments have a quite different interpretation.

"offset" is taken as a character offset from the beginning of the string and indicates where I/O is to begin. This applies to strings open for either reading or writing. If you specify an offset when you open a string for appending, OPEN first determines the current end of the string by searching for the first '*0', and then applies the offset from this point; in other words, the offset is taken from the current end of the string. This behavior is different from previous versions of the B library. The default offset is zero.

"eos" is a flag indicating whether or not a final '*0' is to be written to the string upon closing. If "eos" is zero the '*0' is written on closing, and if it is non-zero the '*0' is not written. This is useful in a program that wants to "fill in the blanks" in a string containing several fields. Opening a string for append has the natural interpretation; it is equivalent to opening for writing with an offset of the length of the string.

"maxlength" specifies a maximum length for the string. The effect of this argument depends on whether you are reading, writing, or appending.

Reading
If you do not specify a "maxlength" when reading from a string, the end of the string is determined by the first '*0' character found.

If you do specify a "maxlength" value, the string is assumed to be exactly that number of characters long. In particular, this means that internal '*0' characters are NOT considered to mark the end of the string.

If you are using a routine like GETC to read from the string, the function will return zero if it reads a '*0' character or if it has reached the end of the string. You can use the EOF function to determine whether you have really reached end-of-string or just a '*0' character.

Writing
If you do not specify a "maxlength" when writing to a string, the I/O routines do not impose any limit on the length of the string. It is up to your program to make sure that the memory area containing the string has enough space to hold the data that you write to it.

If you do specify a "maxlength" value, it limits the number of characters that you can write to the string. By default, if you write more characters to the string than "maxlength", the extra characters are simply discarded without raising any error condition. However, if you open the string with the error recovery option ("e"), you will get a "physical EOF" error if you try to write past the end of the string.

If you specify a "maxlength" and a non-zero value for "eos", no '*0' is written on the end of the string; this means that you can write up to "maxlength" characters. If you specify a zero value for "eos", the I/O routines will write a '*0' to the end of the string, so you can only write up to "maxlength-1" characters.

When you open a string for both reading and writing, the length of the string is established at the time the string is opened. In particular, if you do not specify a "maxlength", OPEN determines the length of the string by the position of the first '*0' and that is taken to be the end of the string, even if you overwrite the '*0' character in a subsequent write operation. This is a change from earlier implementations of B, where the length of the string was determined dynamically instead of at the time of opening.

Appending
When you open a string for appending, OPEN determines the current end of the string by finding the first '*0' in the string. After this, "maxlength" has the same effect as for writing.

Note that if you REWIND a string that has been opened for appending, the operation goes all the way back to the beginning of the string, not to the original end of the string.

Functions like REWIND, .SEEK, and .TELL work on strings that have been opened for I/O. If a string is currently in the EOF state, you must .SEEK somewhere to reset the EOF flag.

Actions

The following items may appear as part of the "action" string when OPEN is invoked.

a
Append. The unit is to be opened for writing, and the file is positioned to write at the end of the file.
b
random Block. The file is to be accessed for random I/O, presumably via the functions READ or WRITE. Normally, the "o" option is also specified.
c
Create sequential. If a permfile needs to be created, create it as a sequential file even if the access mode is random (action 'b'). This is only needed in very rare cases.
d
avoid Duplicate altnames. This instructs OPEN to generate a unique altname for a permfile if a conflict occurs with a name currently in the AFT. See "expl b lib acc.fil" for more details. This option is applicable in TSS only.

The "d" option should be used with care. If the file is already in the AFT, the open operation will fail with a "file busy" status. Without "d", OPEN checks the AFT for permanent files that have the same altname, and removes those files before trying the open operation.

e
Error recovery. If an I/O error occurs on the unit any time after it has been opened, control returns to the user. Normally OPEN sets up the I/O unit so that the program EXITs with an error message if an I/O error occurs. If a program specifies error recovery, it must check for error statuses on all subsequent I/O calls (READ, WRITE, PUTCHAR etc.).
See the "f" option of OPEN to recover from errors that may arise during the OPEN operation itself.
f
Filact recovery. This specifies that in the event of an error in file access, OPEN is to return control to the user, together with a status code. The default action is to EXIT with an error message.
g
This indicates that a tape file is to be processed as an unlabelled tape.
h
Here. Does not rewind the file on access. This is really only meaningful if applied to a disk or tape filecode in batch, or to a file in the AFT in TSS which has been opened previously without "h" and closed at a point where it should be reopened. This option is rarely used.
i
Ignore. If used with the 'b' option, the file is accessed as a random file even if created sequential. If used without 'b', the file is accessed "asis"; that is, it is accessed sequentially or randomly depending on the file. The option combination "li" is not valid.

Files in the AFT cannot have their mode changed from random to sequential or vice versa. The "i" option is often used in conjunction with "zi".

j
This indicates that the file is organized in standard system format, even though the file is accessed with the 'b' option.
k
Keep. If a file is being opened, it will be kept in the AFT after the unit is closed, no matter what. See also "expl b lib .remove" and "expl b lib .leave".
l
Linked. The file must be linked (sequential), or access fails. (Obsolete option. This is the default unless explictly overridden by the 'i' action.)
m
Messages. Error messages are to be printed on access and I/O errors even if control is returned to the user.
n
Non-concurrent. The file is to be accessed in non-concurrent mode. The default is to request concurrent access. The "n" option is not normally used.
o
Other. The file is being opened for some other purpose than character or record I/O (e.g. task job). No buffer is allocated, and no flush or eof takes place on close. The routines READ and WRITE may be used on the file. See also the "zi" option of OPEN.
p
Permfile. A quick access name is not taken to refer to a file already in the AFT, even if such a file is present. This action is incompatible with the "d" action.
r
Read. The file is opened for reading.
s
String. The "filename" argument is taken as a pointer to a string to be opened for read, write, or append (depending on the other actions specified).
t
Transient. If a file is being opened, it will be removed from the AFT when closed, no matter what. See also "expl b lib .remove".
u
keep Unit. Do not change the current read or write unit even if the open is successful.
v
This is normally used with the 'w' action, and specifies that the file is to accessed with "load" access. This bypasses the FMS concurrency protections, and allows a TSS user to write a protected file.
w
Write. The file is opened for writing and set into write mode. If you want to read the existing contents as well as write new data to the file, specify "wr".
x
eXecute. The file is to be accessed with execute permissions. This should be used with the non-concurrent ('n') option. You must have special privileges to open a file with the execute action. This action is seldom used.
za
Opens an output file in "capped mode". Any time you issue an I/O call to write on this file, the library automatically seeks to the end of file before performing the write. In this way, you can be sure that any data you write to the file is appended to the end of the file's contents, even if you previously used "seek" operations to move to the middle of the file.
zb
Sets a flag so that seek integers (returned by .TELL) take the form of a byte offset from the beginning of the file. If you do not specify this option, seek integers have two parts: the upper 14 bits represent the number of a block within the file and the lower 22 bits represent a character offset within that block.

For this option to work, the file format must be Media~4, with each record other than the last completely filling the block. The B and C libraries write Media~4 in this manner using the character handling functions, but other languages may create Media~4 files in different formats.

zc
When input functions reach end-of-file on this stream, they will return a value of -1. If you do not specify "zc", input functions will return zero instead. Using -1 as EOF is standard in C; thus the C library function "fopen" always invokes OPEN using "zc" as a default. C programs that invoke OPEN directly rather than through "fopen" should specify "zc" explicitly.

"zc" lets you process files that contain '*0' characters without confusing them with EOF marks.

zd
Doesn't not check for duplicate aftnames in the files already open. Normally when OPEN opens a file, it checks to see if you already have an open file with that aftname. "zd" avoids this check, and simply tries to open the file. This lets you get away with operations like
x = open("fc**xx", "w");
y = open("fc**xx", "rzd");
zg
Sets a flag for output units, so that every time the output buffer is flushed, an EOF record is written after the end of the flushed output. This option is not normally used; however, it may be needed when another program is simultaneously reading a file that this program is writing.
zi
Must be specified if you intend to perform use seek argument operations to read or write on a sequential file.
zl
Sets the default buffer size for disk files to 56 llinks.
zo
Sets the default buffer size of a disk file to one llink.
zw

Says you don't care about the contents of the file. ACC.FIL will remove temporary files of the same name from the AFT if necessary to create a file of the correct initial size. "zw" is implied automatically when you use the "b" option or "w" without "wr". "zw" should be used in all cases when the old file contents will not be needed (e.g. when you intend to overwrite the existing contents).

Notes:

There is a special restriction on "bufsize" if you are reading or writing a tape and intend to use one of the character-oriented I/O functions ("putchar" or "getchar", and the functions that behave as if they call "putchar" or "getchar", e.g. "printf", "scanf", etc.). In this case, either your records must all be shorter than 4096 characters, or the value of "bufsize-2" must be less than 4096 characters. You can have large records or a large buffer, but not both. If you are reading/writing ASCII characters, 4096 characters is 1024 words. If you are reading/writing BCD characters, 4096 characters is a little more than 682 words. If you try to write long records using a long buffer, you may be able to write to the tape but will not be able to read it.

See Also:

expl b lib acc.fil

expl b lib fildes

expl b lib getc

expl b lib eof

expl b lib rewind

expl b lib open index

Copyright © 2000, Thinkage Ltd.