Alternate entries: .OPEN
Note: See "expl b lib open index" for explanations of individual actions. Explanations of individual actions are also given below.
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] );
open( 5, "myfile", "r" ); unit = open( argv[1] & 0777777, "wb" ); unit = open( stringptr, "rs" );
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.
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.
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.
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.
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.
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.
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.
The following items may appear as part of the "action" string when OPEN is invoked.
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.
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".
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" lets you process files that contain '*0' characters without confusing them with EOF marks.
x = open("fc**xx", "w"); y = open("fc**xx", "rzd");
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).
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.
Copyright © 2000, Thinkage Ltd.