Table of Contents
This appendix describes how to read and write a record using the Data Set I/O API in a C application.
Using the Data Set I/O API provided by OpenFrame, applications written in C can perform read/write operations on data sets allocated by JCL DD statements.
It is recommended that the FCD Handling API library be used to perform read/write operations (I/O) on data sets opened by a main COBOL application within a sub-program written in C.
To write a program using the Data Set I/O API, you must include the tcppfh.h header file from the OpenFrame binary in the program and link the libtcppfh.so library during compilation.
The Data Set I/O API can be categorized as follows:
File Open/Close
API | Description |
---|---|
Opens a data set to process a record. | |
Closes the data set opened to process a record. |
Record Access
API | Description |
---|---|
Moves the internal record pointer for sequential processing. | |
Reads a record from the data set. | |
Writes a record to the data set. | |
Modifies the content of a record in the data set. | |
Deletes a record from the data set. |
PDS Member Handling
API | Description |
---|---|
Creates the list of PDS directories. | |
Reads the list of PDS directories. | |
Accesses members of PDS by using the directory list of data sets. | |
Accesses members of PDS by using the member name of the data set. | |
Adds, replaces, deletes, changes, or initializes members of PDS. |
Opens a data set to process a record. Opening a data set allocated by JCL DD statement is a preparatory step to process I/O, such as reading or writing actual records.
Prototype
int tcfh_open(tcfh_file_t *file, int open_mode, int flags);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be opened. |
open_mode (IN) | Data set open mode.
|
flags (IN) | Data set open option.
|
Return Value
If successfull, 0 is returned. If an error occurs, a negative error code is returned.
Note
To open a data set, you must provide the pointer to the file structure that contains information about the data set. This file structure is defined in the tcppfh.h header file.
/* -------------------------- file I/O block --------------------------- */ typedef struct tcfh_file_s { char file_name[8+2]; /* file name - SELECT clause */ char file_status[2]; /* file status - I/O interface */ uint8_t organization; /* organization - SELECT clause */ uint8_t access_mode; /* access mode - SELECT clause */ uint8_t open_mode; /* open mode - tcfh_open() */ uint8_t misc_flags; /* miscellaneous - SELECT clause */ /* 64 bit separating line */ char file_path[256]; /* file path - tcfh_open() */ /* 64 bit separating line */ int32_t file_handle; /* file handle - tcfh_open() */ int32_t relative_key; /* relative key - C(C++) program */ /* 64 bit separating line */ int16_t key_length; /* key length - DCL statement */ int16_t key_loc; /* key position - DCL statement */ int16_t rec_size; /* record size - DCL statement */ int16_t cur_reclen; /* current record length - I/O interface */ ... } tcfh_file_t;
The following is a list of entries that need to be specified in the file structure.
Entry | Description |
---|---|
file_name | DD name defined in JCL. |
organization | Data set structure.
|
acess_mode | Access mode.
|
When the data set is opened, the open mode must be specified as a parameter in the tcppfh_open() API. Supported data set open modes are as follows:
Macro | OPEN mode | Description |
---|---|---|
TCFH_OPEN_INPUT | 0 | INPUT mode. |
TCFH_OPEN_OUTPUT | 1 | OUTPUT mode. |
TCFH_OPEN_INOUT | 2 | INPUT/OUTPUT mode. |
TCFH_OPEN_EXTEND | 3 | EXTEND mode. |
When a data set is successfully opened, the values of entries (file_status, file_path, and file_handle) are set in the file structure.
Closes the data set opened for record processing. Closing a data set is the process of terminating the physical connection between an application and a data set after finishing I/O operations.
Prototype
int tcfh_close(tcfh_file_t *file, int flags);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be closed. |
flags (IN) | Option for closing data sets.
|
Return Value
If successful, 0 is returned. If an error occurs, a negative error code is returned.
Note
The following are some helpful tips about the tcfh_close() command.
Pass the file structure pointer provided by tcfh_open() API through the 'file' parameter of the tcfh_close() API.
A data set that is successfully closed through the tcfh_close() API can be reopened by using the tcfh_open() API.
Moves the internal record pointer to the next record to start reading from a relative data set or indexed data set. For a relative data set, the next location is set by specifying a relative record number in the relative_key field of the file structure. For an indexed data set, it is set by specifying the key value in the 'key' parameter of the tcfh_start() API.
Prototype
int tcfh_start(tcfh_file_t *file, char *key, int keylen, int flags);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be processed. |
key (IN/OUT) | Key value for an indexed data set. |
keylen (IN) | Key length for an indexed data set. |
flags (IN) | Data set START option.
|
Return Value
If successful, 0 is returned. If an error occurs, a negative error code is returned.
Note
Consider the following when using the START command.
Data set must be opened in INPUT or INOUT mode to perform the START command.
To verify the status of the file structure, the START command must be executed first.
For an RRDS data set, the file structure's relative key field is used as RRN.
Reads a data set's record sequentially or randomly by specifying a key.
For random record access of a relative data set, the relative record number is specified in the relative_key field of the file structure, and the key value of an indexed data set is specified in the 'key' parameter of the tcfh_read() API.
The TCFH_READ_NEXT macro in the 'flags' parameter of the tcfh_read() API is specified for sequential record access and the TCFH_READ_DEFAULT macro for random record access.
When using the READ command to read from a data set with variable length records, the record length can be obtained by checking the file structure's cur_reclen field. The record length is the length of record data copied to the buffer specified in the 'buf' parameter of the tcfh_read() API. This is the length of the data portion of the record excluding RDW.
Prototype
tcfh_read(tcfh_file_t *file, char *key, int keylen, char *buf, int buflen, int flags);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be processed. |
key (IN/OUT) | Key value for an indexed data set. |
keylen (IN) | Key length for an indexed data set. |
buf (OUT) | Buffer that stores the data record. |
buflen (IN) | Size of the data record buffer. |
flags (IN) | Data set READ option.
|
Return Value
If successful, 0 is returned. If an error occurs, a negative error code is returned.
Note
Consider the following when using the READ command.
The data set must be opened in either INPUT or INOUT mode to run the READ command.
After running the command, the file_status of the file structure can be used to check the status of the file.
For an RRDS data set, the relative_key field of the file structure is used as the RRN.
The length of the record data that is read can be determined by reading the cur_reclen field of the file structure.
Writes a new record into a data set. For a sequential data set, the record is added at the end. For a relative data set, the record is inserted at the location given by the relative record number specified in the file structure's relative_key field. For an indexed data set, a record is stored in the key order specified in the 'key' parameter of the tcfh_write() API.
When using the WRITE command to write to a data set with variable length records, the length of record is specified by the 'buflen' parameter of the tcfh_write() API. The record length is the length of record data in the buffer specified in the 'buf' parameter of the tcfh_write() API. This is the length of the data portion of the record excluding RDW.
Prototype
tcfh_write(tcfh_file_t *file, char *key, int keylen, char *buf, int buflen, int flags);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be processed. |
key (IN/OUT) | Key value for an indexed data set. |
keylen (IN) | Key length for an indexed data set. |
buf (OUT) | Buffer that contains the data record. |
buflen (IN) | Size of the data record buffer. |
flags (IN) | Data set WRITE option. |
Return Value
If successful, 0 is returned. If an error occurs, a negative error code is returned.
Note
Consider the following when using the WRITE command.
The data set must be opened in OUTPUT, INOUT, or EXTEND mode to use the WRITE command.
If the data set is opened in INOUT mode, sequential write operations cannot be performed.
After the command is executed, the file_status of the file structure can be used to check the status of the file.
For an RRDS data set, the relative_key field of the file structure is used as the RRN.
Modifies an existing record in a data set. For a relative data set, the record given by the relative record number specified in the file structure's relative_key field is modified. For an indexed data set, a record that fits the key order specified in the 'key' parameter of the tcfh_rewrite() API is modified.
When using the REWRITE command to modify a record in a data set with variable length records, the length of the record to be modified is specified by the 'buflen' parameter of the tcfh_rewrite() API. The record length is the length of record data in the buffer specified in the 'buf' parameter of the tcfh_rewrite() API. This is the length of the data portion of the record excluding RDW.
Prototype
tcfh_rewrite(tcfh_file_t *file, char *key, int keylen, char *buf, int buflen, int flags);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be processed. |
key (IN) | Key value for an indexed data set. |
keylen (IN) | Key length for an indexed data set. |
buf (IN) | Buffer that contains the data record. |
buflen (IN) | Size of the data record buffer. |
flags (IN) | Data set REWRITE option. |
Return Value
If successful, 0 is returned. If an error occurs, a negative error code is returned.
Note
Consider the following when using the REWRITE command.
The data set must be opened in INOUT mode to use the REWRITE command.
For sequential accesses, the record to be modified must be read with READ first before REWRITE.
After running the command, the file_status of the file structure can be used to check the status of the file.
For an RRDS data set, the relative_key field of the file structure is used as the RRN.
Deletes a record from a data set for either a relative data set or an indexed data set. For a relative data set, the record given by the relative record number specified in the file structure's relative_key field is deleted. For an indexed data set, a record that matches the key order specified in the 'key' parameter of the tcfh_delete() API is deleted.
Prototype
int tcfh_delete(tcfh_file_t *file, char *key, int keylen, int flags);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be processed. |
key (IN) | Key value for an indexed data set. |
keylen (IN) | Key length for an indexed data set. |
flags (IN) | Data set DELETE option. |
Return Value
If successful, 0 is returned. If an error occurs, a negative error code is returned.
Note
Consider the following when using the DELETE command.
The data set must be opened in INOUT mode to use the DELETE command.
For sequential accesses, the record to be deleted must be READ before DELETE.
After running the command, the file_status of the file structure can be used to check the status of the file.
For an RRDS data set, the relative_key field of the file structure can be used as the RRN.
Creates the list of PDS directories.
Prototype
int tcfh_bldl(tcfh_file_t *file, char *filter);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be processed. |
filter (IN) | Filter for members to include in the PDS list. If you want to create a list of all members of the data set, use an Asterisk (*) or a null value. If you want to create a list only with members that begin with the letters "ABC", set this parameter to "ABC". |
Return Value
If successful, the number of members in the directory list is returned. If an error occurs, a negative error code is returned.
Note
The followings are some helpful tips about the BLDL command:
After running the command, the file_status of the file structure can be used to check the status of the file.
Reads the list of PDS directories. This command can be used after executing the tcfh_bldl() command first.
The TCFH_READ_NEXT macro in the 'flags' parameter of the tcfh_read() API is specified for sequential record access and the TCFH_READ_DEFAULT macro is specified for random record access.
When using the READ command to read from a data set with variable length records, the record length can be obtained by checking the file structure's cur_reclen field. The record length is the length of record data copied to the buffer specified in the 'buf' parameter of the tcfh_read() API. This is the length of the data portion of the record excluding RDW.
Prototype
int tcfh_bldl_info(tcfh_file_t *file, int number, tcfh_membstat_t *stat);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be processed. |
number (IN) | Path to the directory. |
stat (OUT) | Key length for an index data set. |
Return Value
If successful, 0 is returned. If an error occurs, a negative error code is returned.
Note
To retrieve the member information, you must specify a pointer to the file structure, where the member information is stored. The file structure is defined in the tcfh.h header file.
/* -------------------------- file I/O block --------------------------- */ typedef struct tcfh_membstat_s { char member[64]; int64_t size; char lastmoddt[8+2]; /* last modified date */ char lastmodtm[6+2]; /* last modified time */ } tcfh_membstat_t;
The information provided in the file structure is as follows:
Item | Description |
---|---|
member (OUT) | Name of the member in PDS. |
size (OUT) | Size of the Unix file where the member is specified. |
lastmoddt (OUT) | Last modification date of the member. |
lastmodtm (OUT) | Last modification time of the member. |
Accesses members of PDS. This command can be used after executing the tcfh_bldl() command first.
Prototype
int tcfh_find_by_bldl(tcfh_file_t *file, int num);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be processed. |
num (IN) | Key value for an index data set. |
Return Value
If successful, 0 is returned. If an error occurs, a negative error code is returned.
Note
The following are some helpful tips about the FIND command:
After running the command, the file_status of the file structure can be used to check the status of the file.
Accesses members of PDS. This command can be used regardless of the use of tcfh_bldl().
Prototype
int tcfh_find_by_name(tcfh_file_t *file, char *name);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be processed. |
name (IN) | Name of the member to be accessed. |
Return Value
If successful, 0 is returned. If an error occurs, a negative error code is returned.
Note
The followings are some helpful tips about the FIND command.
After running the command, the file_status of the file structure can be used to check the status of the file.
Adds, replaces, deletes, changes, or initializes members of PDS.
Prototype
int tcfh_stow(tcfh_file_t *file, char *name, int flags);
Parameters
Parameter | Description |
---|---|
file (IN/OUT) | File structure that stores information about the data set to be processed. |
name (IN) | Name of the member to be processed. When changing a member name, a slash (/) is used to split the name into before and after modification. (Example: "BEFORE/AFTER") |
flags (IN) | Data set STOW option.
|
Return Value
If successful, 0 is returned. If an error occurs, a negative error code is returned.
Note
Consider the following when using the STOW command.
The WRITE command must precede when adding or replacing a member.
After running the command, the file_status of the file structure can be used to check the status of the file.
After performing read/write on a data set, check the current status of the data set in the file_status field of the file structure that contains information about the data set. The file_status field contains the status code on the data set.
The following describes the status codes of a data set.
Code | Description |
---|---|
00 | Job executed successfully. |
02 | For an index file, duplicate keys found in a data set where duplicate keys are allowed. |
10 | There is no next record. (That is, EOF read) |
22 | For an index file or relational file, a duplicate key error has occurred. |
23 | The record corresponding to the key cannot be found. (A member cannot be found in case of the FIND command.) |
37 | The specified open mode is not supported. |
38 | Attempted to open a file that is already closed with lock. |
39 | Attribute of the data set is invalid. |
41 | Attempted to open a file that is already open. |
42 | Attempted to close a file that is already closed. |
43 | READ does not precede the REWRITE or DELETE command in the sequential mode. |
44 | The length of record to be rewritten is not the same as that of the existing one. |
47 | READ or START command executed when the mode is not INPUT or INOUT. |
48 | WRITE command executed when the mode is not OUTPUT, INOUT, or EXTEND. |
49 | DELETE or REWRITE command executed when not in INOUT mode. |
99 | System error occurred. |