Miscellaneous Facilities | Handling C-ISAM Files |
The Callable File Handler, ExtFH, is a loadable file handling subsystem with an open architecture. This means it can be used independently with a variety of programming languages, enabling you to create powerful file processing tools, as well as sophisticated database applications.
This chapter describes the call interface to the file handler and the special features available.
The Callable File Handler (ExtFH) enables programs to perform complex file operations that are not usually directly supported by your language syntax.
Using the interface described in this chapter, you can access ExtFH directly from your program using your language's calling convention. All input and output can be performed without language dependent I/O syntax.
The Callable File Handler provides many benefits, such as:
You can use the call interface to create sophisticated applications, for example, file conversion programs, file reorganization utilities and file restoration utilities are all possible uses. You could even write your own database management system using the Callable File Handler.
You can write your own file handler and run it in place of ExtFH, as long as it conforms to the call interface defined in this chapter.
ExtFH can be used on the following environments:
ExtFH can be called from most languages using that particular language's calling convention. Several example programs are provided with this COBOL system, in addition to the examples shown in this chapter.
If you want to share files between languages, you need to be aware that different languages use different data types. When creating a file, you should, therefore, avoid using a data type in a record that cannot be processed by the reading language.
The Callable File Handler handles all the standard COBOL file organizations: sequential, line sequential, relative and indexed. Not all file handler operations are possible or appropriate with all file organizations. The section Operation Codes later in this chapter indicates which operation codes are valid for which file organizations.
In addition to the standard COBOL organizations, the following file types are also supported:
By default, the file handler can handle files that are up to a maximum of 2 Gigabytes in size. However, if you need to create larger indexed files, you can use the IDXFORMAT Compiler directive to create IDXFORMAT"8" files. These files comprise a single file (as opposed to the usual .idx and .dat files).
Even with IDXFORMAT"8" files, however, the COBOL run-time system currently imposes a limit on file size of 2 Gigabytes. To enable you to create large files despite this limit, a striping option is provided which, used in conjunction with IDXFORMAT"8" files allows logical files of up to 256 Gigabytes in size. These large logical files comprise up to 256 physical files (the base file and the "stripes"). (See the section File Striping in this chapter for more information.)
You can use all of the following standard file handling features of this COBOL system with IDXFORMAT"8" files:
Note: You cannot use the UNIX file handler utilities (fhutils) with large indexed files.
With IDXFORMAT"8" files, you can only use the Callable SORT Module with indexed files. To use the Callable SORT module with IDXFORMAT"8" files, you need to compile your program using the Compiler directive CALLSORT"EXTSMLFS". Your program also needs to access the module:
The file operations performed by ExtFH broadly fit into the following categories:
The file position indicator identifies the current record during certain input/output sequences. The setting of the file position indicator is affected only by CLOSE, OPEN, START and READ operations. It has no affect on files opened in OUTPUT or EXTEND mode, unless the "update-on-write" bit is set in flags. By default, the file position indicator does not move onto locked records.
Your programs may already be using the Callable File Handler. If your COBOL program uses Micro Focus COBOL syntax for all its file handling, the Callable File Handler is used in the following cases:
The COBOL syntax defining a file (the SELECT statement and the FD statement) cause the Compiler to create the data areas needed to define the file and to hold the file records.
To call the File Handler explicitly, you must follow these steps before the first call:
Note: Because areas of the FCD are used internally by the file handler, the FCD returned when the file is opened must be used for all subsequent accesses for that file.
See the section File Control Description later in this chapter for more details.
You must then follow these steps for each operation:
Unless specifically stated, you must not alter fields between calls.
Use the following syntax to call the Callable File Handler from COBOL:
call "EXTFH" using opcode fcd
where opcode
is a PIC X(2) COMP-X field specifying the
operation code.
Use the following syntax to call the Callable File Handler from "C":
EXTFH(op_code,&fcd);
You must set up and initialize the data areas used by the Callable File Handler before the call.
See the Programmer's Guide to Writing Programs for details of how to call COBOL programs from "C".
A demonstration program is provided which illustrates calling the Callable File Handler from "C"; the following are provided in your \demo directory:
extfhwr.cbl | A COBOL program that creates a file. |
extfhrd.c | A "C" program that reads this file using the Callable File Handler. |
extfhmak | A make file for the above. |
ExtFH uses four data areas during file I/O operations:
These are described in detail in the following sections.
The File Control Description (FCD) is a 100-byte area in your program that contains information about the file in use. Your program must complete the appropriate fields in the FCD before calling ExtFH. After performing the specified operation, ExtFH completes the appropriate fields in the FCD before passing control back to the calling program.
Note: All unused or reserved areas of the FCD must be set to binary zeros.
The FCD used on the call to open a file must be the one used on all subsequent calls to that file. You can, however, open the same file more than once, using a different FCD for each open.
The supplied copyfile XFHFCD.CPY contains a COBOL definition of the FCD.
The structure of the FCD is defined below.
Bit 7 is always the most significant (leftmost) bit.
When using COBOL, this and the following pointers are USAGE POINTER items, set using a statement of the form:
set pointer to address of data item
where:
pointer |
is one of these fields |
data item |
is the relevant data area. |
When using other languages, a 32-bit pointer (far or long) must be used.
Offset and size are in bytes.
The record area is a data area into which records are read, and from which records are written. It contains the data for the current file record.
Note: The size of the record area must be four bytes larger than the largest record in the file.
The record length fields in the FCD always contain true record lengths, not the length of the record area. (See offsets 38, 48 and 50 in the FCD.)
The following COBOL code shows how the FCD is set up to point to the record area:
01 record-area pic x(85). . . . set record-pointer of fcd to address of record-area . . .
The filename area is a data area that contains the name of the file in use, as recognized by the operating system. It can contain drive and/or path information as well as the actual name of the file. If the actual name is shorter than the length of the buffer specified in the FCD, it must be terminated by a space. This data area must be filled before the first operation on the file.
OS/2:
Any name conforming to OS/2's High Performance File System (HPFS) can be
handled, provided it does not contain embedded spaces.
The following COBOL code shows how the FCD is set up to point to the filename area:
01 filename-area pic x(65) value "master.dat". . . . set filename-pointer of fcd to address of filename-area . . .
The Key Definition Block is used by ExtFH to hold index key information during operations on indexed files. It consists of three data areas:
The Global Information area tells ExtFH the size of the Key Definition area and how many keys are in the file.
All unused or reserved areas must be initialized to binary zeros.
The structure is shown below.
Offset
|
Size
|
Description of the Field
|
---|---|---|
0 | 2 | Length of the Key Definition Block |
2 | 4 | Reserved. Must be set to binary zeros |
6 | 2 | Number of keys |
8 | 6 | Reserved. Must be set to binary zeros. |
The Key Definition area describes the keys used in the indexed file. It follows the Global Information area and consists of one Key Definition for each key in the file. You must define all keys before their components.
The order of defining the keys is important. The ordinal position of the key is used to identify it. For example, if you have an indexed file with a prime key and two alternate keys, the Key Definition area would contain three key definitions. The prime key is key 0, the first alternate is key 1, and the second alternate is key 2. All unused or reserved areas must be initialized to binary zeros.
The structure of a Key Definition is shown below.
Offset
|
Size
|
Description of the Field
|
---|---|---|
0 | 2 |
Component count.
For ordinary keys, the component count is 1. For split keys, the component count is the number of components making up the split key. |
2 | 2 | Offset to first Component Definition area for this
key.
This offset is relative to the start of the Global Information area, starting at 0. |
4 | 1 |
Key flags:
Bit 7 - Reserved. Must be set to binary zeros |
5 | 1 |
Compression flags:
Bits 7-3
- Reserved. Must be set to binary zeros |
6 | 1 | Sparse character.
If bit 1 of the key flags (offset 4) is set, the key is suppressed if it is entirely made up of this character. |
7 | 9 | Reserved. Must be set to binary zeros. |
The Component Definition area follows the Key Definition area. It contains one component definition for each key component. Each key consists of one component, unless defined as a split key, when each component of the key requires its own Component Definition. The Component Definitions define the location in the record and length of the key component.
All unused or reserved areas must be initialized to binary zeros.
The structure of a Component Definition is shown below.
Offset
|
Size
|
Description of the Field
|
---|---|---|
0 | 2 | Reserved. Must be set to binary zeros. |
2 | 4 | Offset of component in the record (starting at 0). |
6 | 4 | Length of the component (in bytes). |
There are two types of operation codes: standard and special. The operation codes are documented in the following sections. Each section contains the operation-name and function, and the following entries (as appropriate):
Opcode | A 2-character operation code specifying an exact operation. | ||||||||||||
Operation | The operation performed by the chosen opcode. | ||||||||||||
File Types | Any of the following:
|
||||||||||||
Input fields | The offset values of fields in the FCD to be set before calling. | ||||||||||||
Output fields | The offset values of fields set by ExtFH during the call. | ||||||||||||
Rules | Any additional information required. |
The standard operation codes are listed before the special operation codes. A summary of all the operation codes supported by the Callable File Handler is given below.
Op Code
|
Description
|
File Type
|
---|---|---|
00 | OPEN INPUT | L S R I |
01 | OPEN OUTPUT | L S R I |
02 | OPEN I/O | L S R I |
03 | OPEN EXTEND | L S R I |
04 | OPEN INPUT WITH NO REWIND | L S |
05 | OPEN OUTPUT WITH NO REWIND | L S |
08 | OPEN INPUT REVERSED | L S |
80 | CLOSE | L S R I |
81 | CLOSE WITH LOCK | L S R I |
82 | CLOSE WITH NO REWIND | L S |
84 | CLOSE REEL/UNIT | L S |
85 | CLOSE REEL/UNIT FOR REMOVAL | L S |
86 | CLOSE REEL/UNIT WITH NO REWIND | L S |
8D | READ(sequential) WITH NO LOCK | L S R I |
D8 | READ (sequential) WITH LOCK | L S R I |
D9 | READ (sequential) WITH KEPT LOCK | L S R I |
F5 | READ (sequential) | L S R I |
8C | READ PREVIOUS WITH NO LOCK | R I |
DE | READ PREVIOUS WITH LOCK | R I |
DF | READ PREVIOUS WITH KEPT LOCK | R I |
F9 | READ PREVIOUS | R I |
8E | READ (random) WITH NO LOCK | R I |
DA | READ (random) WITH LOCK | R I |
DB | READ (random) WITH KEPT LOCK | R I |
F6 | READ (random) | R I |
8F | READ (direct) WITH NO LOCK | L S R I |
D6 | READ (direct) WITH LOCK | L S R I |
D7 | READ (direct) WITH KEPT LOCK | L S R I |
C9 | READ (direct) | L S R I |
F1 | READ (position) | L S R I |
E1 | WRITE BEFORE | L S |
E2 | WRITE AFTER | L S |
E3 | WRITE BEFORE TAB | L S |
E4 | WRITE AFTER TAB | L S |
E5 | WRITE BEFORE PAGE | L S |
E6 | WRITE AFTER PAGE | L S |
EC | WRITE BEFORE mnemonic name | S |
ED | WRITE AFTER mnemonic name | S |
F3 | WRITE | L S R I |
F4 | REWRITE | L S R I |
E8 | START equal to full length prime key | R I |
E9 | START equal to (any key/record number) | R I |
EA | START greater than (>) | R I |
EB | START not less than (>=) | R I |
FE | START less than (<) | R I |
FF | START less than or equal to (<=) | R I |
90 | STEP NEXT WITH NO LOCK | L S R I |
D4 | STEP NEXT WITH LOCK | L S R I |
D5 | STEP NEXT WITH KEPT LOCK | L S R I |
CA | STEP NEXT | L S R I |
92 | STEP FIRST WITH NO LOCK | L S R I |
D0 | STEP FIRST WITH LOCK | L S R I |
D1 | STEP FIRST WITH KEPT LOCK | L S R I |
CC | STEP FIRST | L S R I |
F7 | DELETE | vS R I |
F8 | DELETE file | L S R I |
0E | UNLOCK | L S R I |
DC | COMMIT (UNLOCKs all files) | L S R I |
DD | ROLLBACK (UNLOCKs all files) | L S R I |
Standard I/O operations are identified by x"FA" in the most significant byte of the operation code. The least significant byte indicates the specific operation, as shown in the following sections.
Terminates the processing of files and reels/units with optional rewind and locking where appropriate. For record sequential files, the terms "reel" and "unit" are interchangeable; the treatment of sequential disk files is logically equivalent to the treatment of a file on tape or similar sequential media.
Op Code
|
Operation
|
File Type
|
---|---|---|
80 | CLOSE | L S R I |
81 | CLOSE WITH LOCK | L S R I |
82 | CLOSE WITH NO REWIND | L S |
84 | CLOSE REEL/UNIT | L S |
85 | CLOSE REEL/UNIT FOR REMOVAL | L S |
86 | CLOSE REEL/UNIT WITH NO REWIND | L S |
None
Offset 0 | User file status |
See the section The CLOSE Statement in the Procedure Division section of your Language Reference.
Releases all record locks in all files held by this run unit. This operation code always requires use of the FCD.
Op Code
|
Operation
|
File Types
|
---|---|---|
DC | COMMIT (UNLOCK all files) | L S R I |
Always requires FCD used by the file
None
See the section The COMMIT Statement in the Procedure Division section of your Language Reference.
Logically removes a record from a disk file. It can be specified only for files with relative or indexed organization.
Op Code
|
Operation
|
File Types
|
---|---|---|
F7 | DELETE | vS R I |
Offset 43 | Non-sequential access to relative record number (R) |
Offset 56 | Non-sequential access to record pointer (I) |
Offset 0 | User file status |
See the section The DELETE Statement in the Procedure Division section of your Language Reference.
Physically removes the specified file from the physical devices on which it resides.
Op Code
|
Operation
|
File Types
|
---|---|---|
F8 | DELETE FILE | L S R I |
Offset 5 | File organization |
Offset 11 | Filename length |
Offset 34 | File format |
Offset 60 | Pointer to the filename area |
Filename area |
Offset 0 | User file status |
See the section The DELETE FILE Statement in the Procedure Division section of your Language Reference.
Initiates the processing of files. It also performs checking and/or writing of labels and other I/O operations.
Op code
|
Operation
|
File Types
|
---|---|---|
00 | OPEN INPUT | L S R I |
01 | OPEN OUTPUT | L S R I |
02 | OPEN I-O | L S R I |
03 | OPEN EXTEND | L S R I |
04 | OPEN INPUT WITH NO REWIND | L S |
05 | OPEN OUTPUT WITH NO REWIND | L S |
08 | OPEN INPUT REVERSED | L S |
Offset 5 | File organization |
Offset 6 | Access mode |
Offset 7 | Open mode. Must be set to 128 before opening a file. |
Offset 11 | Length of filename |
Offset 24 | Lock mode flags |
Offset 25 | Other flags |
Offset 34 | File format |
Offset 38 | Maximum record length |
Offset 47 | Recording mode |
Offset 50 | Minimum record length |
Offset 60 | Pointer to the filename area |
Offset 64 | Pointer to the key definition block (I) |
Offset 78 | Data compression |
Offset 91 | Interlanguage locking |
Filename area
Key definition block (I)
Offset 0 | User file status |
Offset 7 | Open mode |
FCD | Use for all subsequent accesses to this file |
See the section The OPEN Statement in the Procedure Division section of your Language Reference.
With ExtFH you can assign several FCDs to the same physical file and have them all open at the same time.
The operating system counts it as just one open file.
The physical file is not closed until every logical file assigned to it has been closed.
UNIX:
You can prevent this behavior in UNIX systems by setting the
same_proc_excl_detection RTS tunable to TRUE.
For sequential access, READ makes available the next or previous logical record from a file. For random access, READ makes available a specified record from a disk file.
Op Code
|
Operation
|
File Types
|
---|---|---|
8D | READ (sequential) WITH NO LOCK | L S R I |
D8 | READ (sequential) WITH LOCK | L S R I |
D9 | READ (sequential) WITH KEPT LOCK | L S R I |
F5 | READ (sequential) | L S R I |
8C | READ PREVIOUS WITH NO LOCK | R I |
DE | READ PREVIOUS WITH LOCK | R I |
DF | READ PREVIOUS WITH KEPT LOCK | R I |
F9 | READ PREVIOUS | R I |
8E | READ (random) WITH NO LOCK | R I |
DA | READ (random) WITH LOCK | R I |
DB | READ (random) WITH KEPT LOCK | R I |
F6 | READ (random) | R I |
8F | READ (direct) WITH NO LOCK | L S R I |
D6 | READ (direct) WITH LOCK | L S R I |
D7 | READ (direct) WITH KEPT LOCK | L S R I |
C9 | READ (direct) | L S R I |
F1 | READ (position) | L S R I |
Offset 43 | Relative record number (R) if READ random or direct |
Offset 52 | Key identifier (I) |
Offset 56 | Pointer to the record area |
Offset 0 | User file status |
Offset 48 | Current record length |
Offset 72 | Relative byte address |
Record area |
See the section The READ Statement in the Procedure Division section of your Language Reference.
Releases all record locks in all files held by this run unit.
Op Code
|
Operation
|
File Types
|
---|---|---|
DD | ROLLBACK (UNLOCKs all files) | L S R I |
None
None
See the section The ROLLBACK Statement in the Procedure Division section of your Language Reference.
Provides a basis for logical positioning in a relative or indexed file, for subsequent retrieval of records.
Op Code
|
Operation
|
File Types
|
---|---|---|
E8 | START equal to full length prime key | R I |
E9 | START equal to (any key/record number) | R I |
EA | START greater than (>) | R I |
EB | START not less than (>=) | R I |
FE | START less than (<) | R I |
FF | START less than or equal to (<=) | R I |
Offset 43 | Relative record number (R) |
Offset 52 | Key identifier (I) |
Offset 54 | Effective key length (I) |
Offset 56 | Pointer to the record area |
Offset 0 | User file status |
See the section The START Statement in the Procedure Division section of your Language Reference.
Steps to the next physical record. This operation enables very fast access to a record.
Op Code
|
Operation
|
File Types
|
---|---|---|
90 | STEP NEXT WITH NO LOCK | L S R I |
D4 | STEP NEXT WITH LOCK | L S R I |
D5 | STEP NEXT WITH KEPT LOCK | L S R I |
CA | STEP NEXT | L S R I |
92 | STEP FIRST WITH NO LOCK | L S R I |
D0 | STEP FIRST WITH LOCK | L S R I |
D1 | STEP FIRST WITH KEPT LOCK | L S R I |
CC | STEP FIRST | L S R I |
Offset 56 | Pointer to the record area |
Offset 0 | User file status |
STEP operations are a method of sequentially retrieving records in a relative or indexed file without having to read via a key or relative record number. Generally, this is a faster method of accessing data in the file.
A STEP NEXT operation returns the record that is physically stored immediately after the one that was last retrieved in the file (either by a STEP or READ operation).
If you are using relative byte addressing and you have specified that the current record pointer should be updated to the record you have just accessed, STEP operations are relative to this new position.
The relative byte address is returned on every STEP operation, so if you need to update the current record pointer to the record just retrieved, you can use the READ (direct) operation using the address returned.
Note: The current record pointer is not affected by STEP operations.
Releases all re cord locks held by the run unit on a named file.
Op Code
|
Operation
|
File Types
|
---|---|---|
0E | UNLOCK | L S R I |
None
Offset 0 | User file status |
See the section The UNLOCK Statement in the Procedure Division section of your Language Reference.
Releases a logical record for an output or input-output file. For sequential files, it can also be used for vertical positioning of lines in a logical page. The REWRITE operation logically replaces a record existing in a disk file. The WRITE operation releases record locks and writes records.
Op Code
|
Operation
|
File Types
|
---|---|---|
E1 | WRITE BEFORE | L S |
E2 | WRITE AFTER | L S |
E3 | WRITE BEFORE TAB | L S |
E4 | WRITE AFTER TAB | L S |
E5 | WRITE BEFORE PAGE | L S |
E6 | WRITE AFTER PAGE | L S |
EC | WRITE BEFORE mnemonic name | S |
ED | WRITE AFTER mnemonic name | S |
F3 | WRITE | L S R I |
F4 | REWRITE | L S R I |
Offset 43 | Relative record number (R) |
Offset 48 | Current record length |
Offset 52 | Line count (WRITE only) |
Offset 56 | Pointer to the record area |
Offset 0 | User file status |
Offset 72 | Relative byte address |
See the sections The REWRITE Statement and The WRITE Statement in the Procedure Division section of your Language Reference.
Special operations must be identified by the hexadecimal code x"00" in the most significant byte of the operation code. The least significant byte indicates the operation, as shown in the following sections.
Returns information on keys for the specified file in the format of the Key Definition Block for index files and general file information for all file types supported.
Op Code
|
Operation
|
File Types
|
---|---|---|
06 | Return file information | vS vR I |
Offset 5 | File organization (can be x"FF") |
Offset 11 | Length of filename |
Offset 60 | Pointer to the filename area |
Offset 64 | Pointer to the key definition area (I) |
Offset 0 | User file status |
Offset 5 | File organization |
Key definition block (I)
Offset 34 | File format |
Offset 38 | Maximum record length |
Offset 47 | Recording mode |
Offset 50 | Minimum record length |
Offset 72 | File size |
Offset 78 | Data compression routine |
Creates a new .idx file, containing only header information for the file to allow new indexes to be added.
Op Code
|
Operation
|
File Types
|
---|---|---|
07 | Open new index | I |
as open
as open
Gets the next physical record from the index data file.
Op Code
|
Operation
|
File Types
|
---|---|---|
08 | Get next record | I |
offset 56 | pointer to record area |
offset 0 | user file status |
offset 48 | current record length |
offset 72 | relative byte offset |
Adds key value to the index for the key specified
Op Code
|
Operation
|
File Types
|
---|---|---|
09 | Add key value | I |
offset 52 | key identifier |
offset 56 | pointer to record area |
offset 0 | user file status |
Ensure all data for a specific file is flushed to disk.
Op Code
|
Operation
|
File Types
|
---|---|---|
0C | Flush File | L S R I |
None
None
Unlocks a specific record in a file.
Op Code
|
Operation
|
File Types
|
---|---|---|
0F | Unlock record | I |
Offset 56 | Pointer to the record area |
None
When you read or write a record, you obtain its relative byte address. Using this address, you can re-read, re-write or delete the record without using keys and indexes. This is a fast method of accessing records, but has limitations that you should be aware of:
It is possible, however, to update the file position indicator so it points to the record you accessed using relative byte addressing. A subsequent READ returns you to the record after the one you accessed using the relative byte address operation.
To update the file position indicator, you should set Bit 5 of the configuration-flags (offset 93) in the FCD before calling the Callable File Handler to perform the relative byte address operation.
The relative byte address of a record is returned in offset 72 of the FCD (or offset 13, if bit 4 of offset 93 is set) on all operations that involve specific records. To use this address, simply save the contents of this field after a READ operation. Note that if the operation is unsuccessful, the value in the relative byte address is undefined.
Once you have obtained the relative byte address of a record, you can perform a number of operations. These are outlined in the following sections.
You can read a specific record from a file in two ways using the relative address:
Perform a READ (random) WITH NO LOCK, READ (random) WITH LOCK, READ (random) WITH KEPT LOCK or READ (random) operation on the file.
Both of the above methods provide a way of switching the current key-of-reference to a different key. For example, if READ (sequential) operations are performed via the primary key, you can start reading via the first alternate key from the current record using the following steps:
You can re-write a record to a specific address by specifying that address in the relative byte address field of the FCD and setting bit 6 of the configuration flags in the FCD (offset 93).
If you want to update the file position indicator, set bit 5 of the configuration flags in the FCD (offset 93).
You can delete a record at a specific address by specifying that address in the relative byte address field of the FCD and setting bit 6 of the configuration flags in the FCD (offset 93).
A set of operations is provided that enables you to recreate an index file using only the information in the data file.
To recreate an index file, your program must:
COBOL Example
78 close-file value x"fa80". 78 open-new-index value x"0007". 78 get-next-rec value x"0008". 78 add-key-value value x"0009". . . . . . . move open-new-index to fh-opcode perform extfh-op move get-next-rec to fh-opcode perform extfh-op perform until fcd-status (1:1) not = "0" perform varying fcd-key-id from 0 by 1 until fcd-key-id = key-count or fcd-status (1:1) not = "0" move add-key-value to fh-opcode perform extfh-op end-perform move get-next-rec to fh-opcode perform extfh-op end-perform move close-file to fh-opcode perform extfh-op . . . . . .
extfh-op. call "EXTFH" using fh-opcode, fcd if fcd-status of fcd (1:1) "1" move 1 to return-code end-if.
C Example
#define XFH_CLOSE_FILE 0xFA80 #define XFH_OPEN_NEW_INDEX 0x0007 #define XFH_GET_NEXT_REC 0x0008 #define XFH_ADD_KEY_VALUE 0x0009
main() {
put2ws(op_code,XFH_OPEN_NEW_INDEX); EXTFH(op_code,&fcd);
put2ws(op_code,XFH_GET_NEXT_REC); EXTFH(op_code,&fcd); while(status[0] == '0'); { get2ws(fcd.key_count,num_keys); i=0; while(i num_keys && status[0] == '0') { put2ws(fcd.key_id,i++); put2ws(op_code,XFH_ADD_KEY_VALUE); EXTFH(op_code,&fcd); }
put2ws(op_code,XFH_GET_NEXT_REC); EXTFH(op_code,&fcd); }
put2ws(op_code,XFH_CLOSE_FILE); EXTFH(op_code,&fcd); }
When I/O operations are performed using COBOL syntax in a Micro Focus COBOL program, an FCD is created for each file. This FCD can be accessed by your program if you compile it with the FCDREG Compiler directive.
To access the FCD, set up a FCD definition in the Linkage Section of your program. An example FCD definition is supplied with this COBOL system in a file called xfhfcd.cpy. This file is located in $COBDIR\source for DOS, Windows, and OS/2 systems and in $COBDIR/cpylib for UNIX systems. This definition (that takes up no physical memory) can then be mapped onto the FCD you want to read or alter using the following SET statement in your program:
set address of fcd to address of fh--fcd of indexfile
where the parameters are:
fcd |
The Linkage Section definition of the FCD. |
fh--fcd of indexfile |
(note the double hyphen). The pointer special register
automatically allocated to the file with FD-name indexfile . |
Following this SET operation, the data items defined in the Linkage
Section group item fcd
become the fields of the FCD
of the file referenced in the SET statement.
Similarly, you can access the Key Definition Block by:
set address of kdb to address of fh--keydef of indexfile
where the parameters are:
kdb |
The Linkage Section definition of the Key Definition Block. |
fh--keydef of indexfile |
The pointer special register automatically allocated
to the file with FD-name indexfile to point to its
Key Definition Block. |
The following program turns on key compression in a file by setting bits in the file's Key Definition Block.
$set fcdreg select masterfile assign to ..... organization is indexed record key is rec-key alternate key is m-alt-key-1 with duplicates alternate key is m-alt-key-2 alternate key is m-alt-key-3 with duplicates. select indexfile assign to ..... organization is indexed record key is rec-key alternate key is t-alt-key-1 with duplicates. . . . . . .
working-storage section. . . .
linkage section. 01 key-def-block. 03 filler pic x(6). 03 key-count pic 9(4) comp-x. 03 filler pic x(6). 03 key-def occurs 1 to 4 times depending on key-count. 05 filler pic x(5). 05 key-compression pic 9(2) comp-x. 05 filler pic x(10). . . . procedure division. * set appropriate key compressions: * * +-- trailing space compression * |+-- leading character compression * ||+-- duplicate key compression * ||| * 7 = 00000111 - all compressions * 6 = 00000110 - leading character & trailing space * 2 = 00000010 - leading character compression * 1 = 00000001 - duplicate key compression set address of key-def-block to address of fh--keydef of masterfile move 4 to key-count move 6 to key-compression (1) move 7 to key-compression (2) move 6 to key-compression (3) move 7 to key-compression (4) open I-O masterfile . . . set address of key-def-block to address of fh--keydef of indexfile move 2 to key-count move 4 to key-compression (1) move 1 to key-compression (2) open input indexfile . . .
When using the C language, set the bits in key_compression[0].
You can create your own file handler and use it in place of the Callable File Handler.
UNIX:
Under the UNIX operating system, you can create an RTS that is linked to
your own file handler(s) rather than the default file handler(s) supplied
with this COBOL system. The default file handlers for the various types of
file organization and record format are:
File Type | Default File Handler | |
Fixed-length Records | Variable-length Records | |
line-sequential | lsfile | lsfilev |
sequential | sqfile | sqfilev |
indexed | ixfile | ixfilev |
relative | rlfile | rlfilev |
The file handlers you link to the RTS instead of any of the default file handlers shown here must conform to the format of the call interface described in this chapter.
UNIX :
To link your own file handler(s) to the RTS on UNIX systems, you must
include the -m option on the cob command line. See your Object
COBOL User Guide for details.
You can make programs use your file handler for processing COBOL I/O syntax by using the CALLFH Compiler directive when compiling your programs. For example, if you have a file handler called USERFH, compile your programs with the directive:
callfh"userfh"
This causes all COBOL I/O operations to be compiled into calls to USERFH.
If you use CBL_EXIT_PROC, you must set the priority to 200, so when the application calling your file handler terminates, your file handler shuts down properly.
UNIX:
On UNIX systems, this COBOL system can intercept calls to the fixed or
variable indexed, relative and sequential file handlers enabling access to
your own file handlers and the default file handlers used by this COBOL
system.
The module ufhtab.o, included in your $COBDIR/src/rts directory, and the following interceptor functions provide this functionality:
uixfile() | for indexed fixed format File Handlers | |
uixfilev() | for indexed variable format File Handlers | |
usqfile() | for sequential fixed format File Handlers | |
usqfilev() | for sequential variable format File Handlers | |
urlfile() | for relative fixed format File Handlers | |
urlfilev() | for relative variable format File Handlers |
To enable File Handler vectoring, you link the ufhtab.o module to your run-time system and map the appropriate interceptor function either to its corresponding default File Handler listed in the section "Operation" earlier in this chapter, or to your own equivalent File Handler.
If you do not want all calls to the File Handler to be intercepted and you now want some calls that were previously mapped to your own file handler to use one of the default file handlers used by this COBOL system, you simply map the call back to the default file handler using the -m cob option.
For example, to intercept all fixed length index file calls and to use the default File Handlers used by this COBOL system for the remaining calls, type:
cob -xvo rts32 $COBDIR/ufhtab.o user-module -m uixfile=user-file-handler -m urlfile=rlfile -m usqfile=sqfile -m uixfilev=ixfilev -m urlfilev=rlfilev -m usqfilev=sqfilev -e ""
The Callable File Handler trace facility traces the operations on one or more files, as specified by you, logging all activity to a trace file. If you are having problems using the Callable File Handler, you can make a trace file containing the operations causing the problem, and send it to Micro Focus Technical Support together with the relevant data files.
XFHTRACE is the trace module for the Callable File Handler.
32-bit:
Tracing is not available for line sequential, fixed length sequential and
relative files.
UNIX:
Tracing is not available for C-ISAM files.
Before using the trace facility, you must make a copy of all the data files involved to send in with the trace file. Without the original files, Micro Focus will not be able to simulate the events which occurred at your site.
So, to take a trace:
To enable tracing, either enable the trace option in the ExtFH configuration file, or set the XFHTRACE environment variable to one of the following:
When a trace is started, a file called xfhtrace.xfh is produced, overwriting any previous version. This is the trace file. It remains open until the application terminates.
You can specify a configuration file for XFHTRACE containing the following:
A list of the files that you want to trace. If you know which files are causing the problem, limiting the trace helps keep the trace file size to a minimum.
Enables you to specify a filename other than xfhtrace.xfh.
Example
set xfhtrace=xfhtrace.cfg
xfhtrace.cfg contains:
[XFH-TRACEFILENAME] p:\data\trace.xfh [XFH-TRACEFILES] p:\data\order.dat p:\data\sales.dat
In this example, the trace file is called p:\data\trace.xfh and only file I/O performed on order.dat and sales.dat is recorded in the trace file.
The Callable File Handler configuration file enables you to configure settings for all files or for individual files. The settings for an individual file override any global settings.
The default configuration filename is extfh.cfg . You can use a different file by setting the EXTFH environment variable:
DOS, Windows and OS/2:
set extfh=filename.cfg
UNIX:
EXTFH=filename.cfg export EXTFH
Global settings are listed under the tag [XFH-DEFAULT]. Individual settings are listed under a tag containing the name of the file to which they apply. The file handler expects filenames appearing in extfh.cfg to be exactly the same (ignoring case) as the name with which it attempts to open the file, so if the file handler attempts to open the file using the full pathname, you must specify the full pathname in extfh.cfg. Note that a "\" (backslash) character appearing within extfh.cfg is treated as an escape character and so, for each backslash character in the pathname you must specify two backslash characters ("\\" instead of "\").
Specifies the amount of cache allocated to the data (.dat) part of an indexed file, or a relative file.
DataCache=cache-size
cache-size | The size of the cache in bytes. Can be any value between 0 and 32768. |
Default: | 0 |
If you set this attribute to 0, no caching is performed.
Specifies whether extra checking is performed, to ensure data integrity, when reading an indexed file.
FastRead={on|off}
Default: | off |
Switching this option on increases the time it takes to read a record, but only on fixed length, non-compressed, indexed files.
Specifies the amount of cache allocated to an index file(.idx).
IndexCache=cache-size
cache-size | The size of the cache in bytes. Can be any value between 4096 and 65535. |
Default: | 16384 |
The optimal size is usually between 16384 and 32768, but this depends on the number and size of keys.
Specifies that the Callable File Handler will check that the key definition in your application matches that of the indexed file being opened.
KeyCheck={on|off}
Default: | on |
All key position and attributes must match, otherwise a 3/9 error is returned.
If KeyCheck is off, the Callable File Handler opens the file regardless of whether the keys match or not. If you access a key which has no corresponding key in the data file, a 3/9 error is given.
Specifies the type of record locking.
LockType=integer
Default: | 0 |
0 | Programs can read locked records, but not access them in other ways. This is the standard method with this COBOL system. |
1 | Programs cannot access locked records at all. This is as in languages other than COBOL. |
2 | Creates a new file with the same base name as the file being opened but with a .lck extension. Any record locks are recorded in this file. On Windows NT this enables the file handler to read and write to files up to 4 Gigabytes in size regardless of whether the file is shared or locked. On UNIX and OS/2 it enables the file handler to read and write to files up to 2 Gigabytes in size regardless of whether the file is shared or locked. |
On UNIX systems, you can specify LockType=2 for an IDXFORMAT"8" file as long as the file is opened I-O and does not use striping.
Enables DOS and Windows applications to detect file and record locks when accessing files on UNIX NFS systems.
NFSFileLock={on|off|HP}
HP | Enables DOS and Windows applications to detect file and record locks on Hewlett Packard (HP) UNIX systems. |
Default: | off |
Specifies the size of the nodes to be used for the index part of an indexed file.
NodeSize={512|1024|4096}
Default: | 1024, with the following restrictions:Maximum key size greater than 1016 bytes, node size is 4096Maximum key size greater than 120 bytes, node size is at least 1024 |
It is usually advisable to use the default values. However, if file size is an issue, smaller node sizes result in a smaller index file, but with a small increase in processing time as the tree depth is greater.
Specifies that on DOS and Windows an OPEN INPUT statement opens the file with read/write access (default is read-only) provided that a LOCK MODE clause is specified.
OpenInputShared={on|off}
Default: | off |
Specifies whether you are able to detect that a record has been locked by a separate OPEN statement issued from within the same run unit.
RUnitLockDetect={on|off}
Default: | off for 16-bit systems on for 32-bit systems |
Note: Locks set within a given run unit will only be detected, even if RUnitLockDetect is on, if this is supported by the operating system.
Specifies whether you wish to trace I/O to a trace file.
Trace={on|off}
Default: | off |
This attribute can only be set on for all files. It is ignored if specified for an individual file. See the section Trace Facility for further details.
If extfh.cfg contains:
[XFH-DEFAULT] DataCache=0 IndexCache=22000 KeyCheck=off NodeSize=512 [test.dat] DataCache=1024 [test1.dat] KeyCheck=on
then the following attributes are set for all files (where applicable):
the following alternative attribute is set for test.dat:
and the following alternative attribute is set for test1.dat:
By default, the file handler can handle files that are up to a maximum of 2 Gigabytes in size. To handle larger files, a file striping option is available which allows logical files of up to 256 Gigabytes in size. These large logical files comprise up to 256 physical files (the base file plus the "stripes").
File striping is only available if you use the IDXFORMAT Compiler directive to specify a large indexed file type (IDXFORMAT"8"). Note that IDXFORMAT"8" files comprise a single file (rather than the .idx and .dat files created for other types of indexed file).
You cannot enable file striping on a global basis as this could lead to the operating system running out of file handles so you need to decide which files you want to use striping on.
The striping option is enabled for a particular file via the file handler's configuration file which, by default, is called extfh.cfg. See the section Configuring the Callable File Handler in this chapter for full details on the file handler configuration file.
Notes:
Striping options are specified in the file handler configuration file (extfh.cfg, by default). The options are not case sensitive.
striping={on/off}
Default: | off |
This option specifies whether a file is a striped file.
StripeNameType={0/1}
Default: | 0 |
With file striping, a file comprises the base file (the filename specified by the program) and a number of stripe files.
This option specifies the file naming convention used to name the stripes.
If StripeNameType is set to 0, the stripe files use the same filename as the base file, but with a stripe number appended to the basename, before the file extension. For example, if the file test.dat has 3 stripes, the base file and its stripes are called:
test.dat - base file
test01.dat - stripe number 1
test02.dat - stripe number 2
test03.dat - stripe number 3
If the basename is too long to accommodate the stripe file number, then characters are removed from the right of the basename. For example, if the file testfile.dat has 3 stripes, the file and its stripes are called:
testfile.dat - base file
testfi01.dat - stripe number 1
testfi02.dat - stripe number 2
testfi03.dat - stripe number 3
If StripeNameType is set to 1, the stripe files use the same filename as the base file but with a stripe number appended to the filename, after the file extension. Note that the base file becomes stripe 0 and is renamed. For example, if the file test.dat has 3 stripes, the base file and its stripes are called:
test.dat.00
test.dat.01
test.dat.02
MaxStripeSize=n
Default: | 1 Gigabyte (1073741824 bytes) |
Minimum: | 65536 |
Maximum: | as default |
This option specifies the maximum size in bytes of an individual stripe.
Although the file handler itself does not impose this limit, we recommend that you do not exceed an individual stripe size of 1 Gigabyte.
Note: If you use the LOCKTYPE Compiler directive to set LOCKTYPE"1" (programs cannot access locked records at all), it is possible to set a maximum individual stripe size of 4 Gigabytes, provided that this is supported by the operating system.
MaxStripeFiles=n
Default: | 16 |
Minimum: | 1 |
Maximum: | 255 |
This option specifies the number of stripe files, not including the base file. By default, 17 files are created, the base file and 16 stripes.
MaxStripeDigits=n
Default: | 2 |
Minimum | 1 |
Maximum | 5 |
This option specifies the number of digits to be appended to the name of the base file when naming the stripes. For example, 2 would give test01.dat and 5 would give test00001.dat or tes0001.dat depending on the filename limitations of the operating system.
Stripe-x=path,n
Default: | disabled |
x | the stripe number |
path | is an alternate path to the stripe |
n | is the size to be allocated for this stripe. This size will remain the default for subsequent stripes until another stripe-x. |
This option specifies an alternate path and size for a stripe file. Once set, the new path and size apply to all stripes until changed by another Stripe-x option. The number following Stripe- is the stripe number and must not be prefixed by a 0 character.
Example 1
test.dat has 2 stripes, each of the same size:
[test.dat] Striping=on Stripe-1=dir2 Stripe-2=dir3
This causes test.dat to be in the current directory, test01.dat to be in dir2 and test02.dat to be in dir3.
Example 2
test.dat has 5 stripes:
[test.dat] Striping=on Stripe-0=dir1 (this is the path for the base file + stripes 1 to 3) Stripe-4=dir2
This causes test.dat to be in dir1, test01.dat to be in dir1, test02.dat to be in dir1, test03.dat to be in dir1, test04.dat to be in dir2 and test05.dat to be in dir2.
Example 3
test.dat has 3 stripes:
[test.dat] Striping=on Stripe-0=dir1,100000000 Stripe-1=dir2,200000000
This causes test.dat to be in dir1 with a file size of 100000000 bytes and test01.dat to be in dir2 with a file size of 200000000 bytes.
You can use file striping with Fileshare but should you should be aware of the following:
The extfh.cfg file must be located in the same directory as the Fileshare Server or, if the EXTFH environment variable has been set to point to the extfh.cfg file, it must have been set in the Fileshare Server session.
You must use the expanded name of the file in the extfh.cfg configuration file. The expanded name is the pathname that you can see if you press F2 at the Fileshare Server to switch tracing on, for example:
[/u/username/file.dat] Striping=on
You can specify file striping on an alternate filename (specified in the database reference file using filename mapping). In this case, the expanded filename is not required. For example, if the database reference file contains the following line:
/f file1.dat /af file2.dat
you can specify the following in the extfh.cfg file:
[file2.dat] Striping=on
Remember that the backslash character is treated as an escape character within the extfh.cfg file so on Windows NT platforms you must specify two backslash characters for each backslash character in the pathname, for example:
[d:\\fsrvr\\file.dat] Striping=on
StripeNameType=1 (the default is StripeNameType=0) only works with Fileshare if the base filename does not have an extension. If you specify StripeNameType=1 for a file that has an extension, the file is created but will not be striped.
The program callfdem.cbl in the\cobol\demo directory of your COBOL system's installation directory illustrates the use of the Callable File Handler.
UNIX:
This sample program is not available on UNIX systems.
The sample program performs the same functions as extfile: OPEN, CLOSE, READ, and WRITE operations on a file declared as external. The difference is that callfdem performs these operations by calling the Callable File Handler. In doing so, it illustrates the basic process of filling in the fields in the File Control Description (FCD), and calling ExtFH. You can use callfdem to create a copyfile for the FCD, if you want.
Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names
used herein are protected by international law.
Miscellaneous Facilities | Handling C-ISAM Files |