データセットI/O API

本付録では、データセットI/O APIを使用して、C言語で作成されたアプリケーション・プログラムでデータセットのレコードを読み書きする方法について説明します。

1. 概要

OpenFrameが提供するデータセットI/O APIを使用して、C言語で作成されたアプリケーション・プログラムで、JCLのDD文で割り当てられたデータセットのレコードを読み書きすることができます。

メインCOBOLアプリケーション・プログラムでオープンされたデータセットを、Cで作成されたサブプログラムで読み書きするなどのI/Oを行う場合は、FCD Handling APIライブラリを使用することをお勧めします。

データセットI/O APIを使用してプログラムを作成するには、OpenFrameバイナリと一緒に配布されるtcfh.hヘッダー・ファイルをユーザー・プログラムに含める必要があり、ユーザー・プログラムをコンパイルする際、libtcfh.soライブラリをリンクする必要があります。

データセットI/O APIは、以下のように分類できます。

  • ファイルのオープンとクローズ

    API 説明

    tcfh_open()

    レコード処理のためにデータセットを開きます。

    tcfh_close()

    レコード処理のために開いていたデータセットを閉じます。

  • レコード・アクセス

    API 説明

    tcfh_start()

    順次処理のために内部レコード・ポインターを移動させます。

    tcfh_read()

    データセットで1つのレコードを読み取ります。

    tcfh_write()

    データセットに1つのレコードを書き込みます。

    tcfh_rewrite()

    データセットにある1つのレコードの内容を変更します。

    tcfh_delete()

    データセットにある1つのレコードを削除します。

  • PDSメンバーの処理

    API 説明

    tcfh_bldl()

    データセットのディレクトリ一覧を構成します。

    tcfh_bldl_info()

    データセットのディレクトリ一覧を検索します。

    tcfh_find_by_bldl()

    データセットのディレクトリ一覧を使用してメンバーにアクセスします。

    tcfh_find_by_name()

    データセットのメンバー名を使用してメンバーにアクセスします。

    tcfh_stow()

    データセット・メンバーの追加、取り替え、変更、削除、初期化を行います。

2. ファイルのオープンとクローズ

2.1. tcfh_open()

レコード処理のためにデータセットを開きます。データセットを開く操作は、JCLのDD文で割り当てられたデータセットに対して、実際にレコードを読み書きするなどのI/Oを行うための準備作業です。

  • プロトタイプ

    int tcfh_open(tcfh_file_t *file, int open_mode, int flags);
  • パラメータ

    パラメータ 説明

    file(入出力)

    オープンするデータセットの情報を保存するファイル構造体です。

    open_mode(入力)

    データセットのオープン・モードです。

    • INPUT

    • OUTPUT

    • INOUT

    • EXTEND

    flags(入力)

    データセットのオープン・オプションです。

    • NO REWIND

  • 戻り値

    正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 参考

    データセットを開くためには、オープンするデータセットの情報を保存したファイル構造体のポインターを提供する必要があります。このファイル構造体は、tcfh.hヘッダー・ファイルに定義されています。

    /* -------------------------- 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;

    前述したファイル構造体で、データセットを開く際に指定が必要な項目は以下のとおりです。

    項目 説明

    file_name

    JCLに記述されたDD名です。

    organization

    データセットの構造です。

    • 0: 順次

    • 1: 相対

    • 2: 索引

    acess_mode

    アクセス・モードです。

    • 0: 順次

    • 1: 任意

    • 2: 両方

    データセットを開くとき、tcppfh_open() APIのパラメータでオープン・モードを指定する必要があります。以下は、サポートされるデータセットのオープン・モードです。

    マクロ オープン・モード 説明

    TCFH_OPEN_INPUT

    0

    INPUTモードです。

    TCFH_OPEN_OUTPUT

    1

    OUTPUTモードです。

    TCFH_OPEN_INOUT

    2

    INPUT/OUTPUTモードです。

    TCFH_OPEN_EXTEND

    3

    EXTENDモードです。

    データセットが正常に開かれた場合、ファイル構造体のfile_status、file_path、file_handleなどの値が設定されます。

2.2. tcfh_close()

レコード処理のために開いていたデータセットを閉じます。データセットを閉じる操作は、アプリケーションでデータセットを読み書きするなどのI/Oを行った後、アプリケーションと物理的なデータセットとの接続を切断する作業です。

  • プロトタイプ

    int tcfh_close(tcfh_file_t *file, int flags);
  • パラメータ

    パラメータ 説明

    file(入出力)

    閉じるデータセットの情報を保存したファイル構造体です。

    flags(入力)

    データセットのクローズ・オプションです。

    • WITH LOCK

  • 戻り値

    正常に実行された場合は0が返され、エラーが生じた場合は負数のエラーコードが返されます。

  • 参考

    以下は、CLOSEコマンドを使用時の注意事項です。

    • tcfh_close() APIのfileパラメータには、tcfh_open() APIに提供されたファイル構造体のポインターを渡します。

    • tcfh_close() APIを使用して正常に閉じたデータセットは、tcfh_open() APIを使用して再オープンすることができます。

3. レコード・アクセス

3.1. tcfh_start()

相対データセット、または索引データセットで次に読み取るレコードの位置に内部レコード・ポインターを移動させます。移動させるレコードの位置は、相対データセットの場合は、ファイル構造体のrelative_keyフィールドに相対レコード番号を指定し、索引データセットの場合は、tcfh_start() APIのkeyパラメータにキー値を指定します。

  • プロトタイプ

    int tcfh_start(tcfh_file_t *file, char *key, int keylen, int flags);
  • パラメータ

    パラメータ 説明

    file(入出力)

    処理するデータセットの情報を保存したファイル構造体です。

    key(入出力)

    索引データセットのキー値です。

    keylen(入力)

    索引データセットのキー長です。

    flags(入力)

    データセットのSTARTオプションです。

    • EQUAL

    • GTEQ

  • 戻り値

    正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 注意事項

    以下は、STARTコマンドを使用時の注意事項です。

    • データセットをINPUTまたはINOUTモードで開いた場合にのみ、STARTコマンドを実行できます。

    • コマンドを実行した後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。

    • 相対データセットの場合、RRNはファイル構造体のrelative_keyフィールドを使用します。

3.2. tcfh_read()

データセットのレコードを順次に読み取るか、キーを指定してランダムに読み取ります。

ランダムにレコードを読み取る際、相対データセットの場合は、ファイル構造体のrelative_keyフィールドに相対レコード番号を指定し、索引データセットの場合は、tcfh_read() APIのkeyパラメータにキー値を指定します。

順次にデータセットのレコードを読み取る場合は、tcfh_read() APIのflagsパラメータにTCFH_READ_NEXTマクロを指定し、ランダムにレコードを読み取る場合は、TCFH_READ_DEFAULTマクロを指定します。

可変長レコード・データセットの場合は、READコマンドを使用してデータセットのレコードを読み取るとき、ファイル構造体のcur_reclenフィールドを調べて読み取ったレコードの長さを取得することができます。取得したレコード長は、tcfh_read() APIのbufパラメータに指定されたバッファーにコピーされたレコード・データの長さ、つまり、RDWを除いたレコードのデータ部分の長さです。

  • プロトタイプ

    tcfh_read(tcfh_file_t *file, char *key, int keylen, char *buf, int buflen,
              int flags);
  • パラメータ

    パラメータ 説明

    file(入出力)

    処理するデータセットの情報を保存したファイル構造体です。

    key(入出力)

    索引データセットのキー値です。

    keylen(入力)

    索引データセットのキー長です。

    buf(出力)

    レコード・データを保存するためのバッファーです。

    buflen(入力)

    レコード・データのバッファー・サイズです。

    flags(入力)

    データセットのREADオプションです。

    • DEFAULT

    • NEXT

  • 戻り値

    正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 注意事項

    以下は、READコマンドを使用時の注意事項です。

    • データセットをINPUTまたはINOUTモードで開いた場合にのみ、READコマンドを実行できます。

    • コマンドを実行した後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。

    • 相対データセットの場合、RRNはファイル構造体のrelative_keyフィールドを使用します。

    • 読み取ったレコードのデータ長は、ファイル構造体のcur_reclenフィールドで取得します。

3.3. tcfh_write()

データセットに新しいレコードを記録します。順次データセットはデータセットの最後にレコードを記録し、相対データセットはファイル構造体のrelative_keyフィールドに指定された相対レコード番号の位置に記録します。索引データセットは、tcfh_write() APIのkeyパラメータに指定されたキー順にレコードが保存されます。

可変長レコード・データセットの場合は、WRITEコマンドを使用してデータセットのレコードを記録するとき、記録するレコードの長さをtcfh_write() APIのbuflenパラメータに指定します。指定するレコードの長さは、tcfh_write() APIのbufパラメータで指定されたバッファーに保存されているレコード・データの長さ、つまり、RDWを除いたレコードのデータ部分の長さを指定します。

  • プロトタイプ

    tcfh_write(tcfh_file_t *file, char *key, int keylen, char *buf, int buflen,
               int flags);
  • パラメータ

    パラメータ 説明

    file(入出力)

    処理するデータセットの情報を保存したファイル構造体です。

    key(入出力)

    索引データセットのキー値です。

    keylen(入力)

    索引データセットのキー長です。

    buf(出力)

    レコード・データを保存しているバッファーです。

    buflen(入力)

    レコード・データの長さです。

    flags(入力)

    データセットのWRITEオプションです。

  • 戻り値

    正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 注意事項

    以下は、WRITEコマンドを使用時の注意事項です。

    • OUTPUT、INOUTまたはEXTENDモードで開いた場合にのみ、WRITEコマンドを使用できます。

    • INOUTモードで開いた場合、順次アクセスによる書き込みはできません。

    • コマンドを実行した後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。

    • 相対データセットの場合、RRNはファイル構造体のrelative_keyフィールドを使用します。

3.4. tcfh_rewrite()

データセットにある既存のレコードの内容を変更します。相対データセットは、ファイル構造体のrelative_keyフィールドに指定された相対レコード番号の位置にあるレコードを変更します。索引データセットは、tcfh_rewrite() APIのkeyパラメータで指定されたキー順に合ったレコードが変更されます。

可変長レコード・データセットの場合は、REWRITEコマンドを使用してデータセットのレコードを変更するとき、変更するレコードの長さをtcfh_rewrite() APIのbuflenパラメータに指定します。指定するレコードの長さは、tcfh_rewrite() APIのbufパラメータに指定されたバッファーに保存されているレコード・データの長さ、つまり、RDWを除いたレコードのデータ部分の長さを指定します。

  • プロトタイプ:

    tcfh_rewrite(tcfh_file_t *file, char *key, int keylen, char *buf, int buflen,
                 int flags);
  • パラメータ

    パラメータ 説明

    file(入出力)

    処理するデータセットの情報を保存したファイル構造体です。

    key(入力)

    索引データセットのキー値です。

    keylen(入力)

    索引データセットのキー長です。

    buf(入力)

    レコード・データを保存しているバッファーです。

    buflen(入力)

    レコード・データの長さです。

    flags(入力)

    データセットのREWRITEオプションです。

  • 戻り値

    正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 注意事項

    以下は、REWRITEコマンドを使用時の注意事項です。

    • データセットをINOUTモードで開いた場合にのみ、REWRITEコマンドを使用できます。

    • 順次アクセスの場合、REWRITEコマンドの実行前に、READコマンドで変更するレコードを読み取ります。

    • コマンドを実行した後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。

    • 相対データセットの場合、RRNはファイル構造体のrelative_keyフィールドを使用します。

3.5. tcfh_delete()

相対データセットまたは索引データセットのレコードを削除します。相対データセットの場合は、ファイル構造体のrelative_keyフィールドに指定された相対レコード番号の位置にあるレコードを削除します。索引データセットの場合は、tcfh_delete() APIのkeyパラメータで指定されたキー順に合ったレコードが削除されます。

  • プロトタイプ

    int tcfh_delete(tcfh_file_t *file, char *key, int keylen, int flags);
  • パラメータ

    パラメータ 説明

    file(入出力)

    処理するデータセットの情報を保存したファイル構造体です。

    key(入力)

    索引データセットのキー値です。

    keylen(入力)

    索引データセットのキー長です。

    flags(入力)

    データセットのDELETEオプションです。

  • 戻り値

    正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 注意事項

    以下は、DELETEコマンドを使用時の注意事項です。

    • データセットをINOUTモードで開いた場合にのみ、DELETEコマンドを使用できます。

    • 順次アクセスの場合、DELETEコマンドの実行前に、READコマンドで削除するレコードを読み取る必要があります。

    • コマンドを実行した後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。

    • 相対データセットの場合、RRNはファイル構造体のrelative_keyフィールドを使用します。

4. PDSメンバーの処理

4.1. tcfh_bldl()

PDSのディレクトリ一覧を構成します。

  • プロトタイプ

    int tcfh_bldl(tcfh_file_t *file, char *filter);
  • パラメータ

    パラメータ 説明

    file(入出力)

    処理するデータセットの情報を保存したファイル構造体です。

    filter(入力)

    リストを構成するメンバーに制限を与える値です。データセットのメンバー全体をリストで構成する場合は、アスタリスク(*)またはNULL値を指定します。「ABC」で始まるメンバーのみを構成する場合は、filterに「ABC」値を指定します。

  • 戻り値

    正常に実行された場合はディレクトリ一覧を構成したメンバーの数を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 参考

    以下は、BLDLコマンドを使用時の注意事項です。

    • コマンドの実行後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。

4.2. tcfh_bldl_info()

PDSのディレクトリ一覧を検索します。tcfh_bldl()を実行した後に使用できます。

データセットのレコードを順次に読み取る場合は、tcfh_read()のflagsパラメータにTCFH_READ_NEXTマクロを指定し、ランダムに読み取る場合は、TCFH_READ_DEFAULTマクロを指定します。

可変長レコード・データセットの場合は、READコマンドを使用してデータセットのレコードを読み取るとき、ファイル構造体のcur_reclenフィールドを調べて読み取ったレコードの長さを取得できます。取得したレコード長は、tcfh_read()のbufパラメータで指定されたバッファーにコピーされたレコード・データの長さ、つまり、RDWを除いたレコードのデータ部分の長さです。

  • プロトタイプ

    int tcfh_bldl_info(tcfh_file_t *file, int number, tcfh_membstat_t *stat);
  • パラメータ

    パラメータ 説明

    file(入出力)

    処理するデータセットの情報を保存したファイル構造体です。

    number(入力)

    ディレクトリ一覧での相対アドレス値です。

    stat(出力)

    索引データセットのキー長です。

  • 戻り値

    正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 参考

    メンバー情報を検索するには、メンバーの情報を保存したファイル構造体のポインターを提供する必要があります。このファイル構造体は、tcfh.hヘッダー・ファイルに定義されています。

    /* -------------------------- 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;

    上記のファイル構造体で情報を提供する項目は以下のとおりです。

    項目 説明

    member(出力)

    PDSのメンバー名が記述されます

    size(出力)

    メンバーが保存されたUNIXファイルのサイズを表示します。

    lastmoddt(出力)

    メンバーの最終修正日付を表示します。

    lastmodtm(出力)

    メンバーの最終修正時刻を表示します。

4.3. tcfh_find_by_bldl()

PDSのメンバーにアクセスします。tcfh_bldl()を実行した後に使用できます。

  • プロトタイプ

    int tcfh_find_by_bldl(tcfh_file_t *file, int num);
  • パラメータ

    パラメータ 説明

    file(入出力)

    処理するデータセットの情報を保存したファイル構造体です。

    num(入力)

    索引データセットのキー値です。

  • 戻り値

    正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 参考

    以下は、FINDコマンドを使用時の注意事項です。

    • コマンドの実行後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。

4.4. tcfh_find_by_name()

PDSのメンバーにアクセスします。tcfh_bldl()の実行に関係なく使用できます。

  • プロトタイプ

    int tcfh_find_by_name(tcfh_file_t *file, char *name);
  • パラメータ

    パラメータ 説明

    file(入出力)

    処理するデータセットの情報を保存したファイル構造体です。

    name(入力)

    アクセスするメンバー名を指定します。

  • 戻り値

    正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 参考

    以下は、FINDコマンドを使用時の注意事項です。

    • コマンドの実行後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。

4.5. tcfh_stow()

PDSにメンバーを追加、取り替え、削除、初期化、およびメンバー名を変更します。

  • プロトタイプ

    int tcfh_stow(tcfh_file_t *file, char *name, int flags);
  • パラメータ

    パラメータ 説明

    file(入出力)

    処理するデータセットの情報を保存したファイル構造体です。

    name(入力)

    処理するメンバー名を記述します。スラッシュ(/)記号を使って変更前と変更後のメンバー名を区切ります。

    (例: "BEFORE/AFTER" )

    flags(入力)

    データセットのSTOWオプションです。

    • TCFH_STOW_ADD

    • TCFH_STOW_DELETE

    • TCFH_STOW_CHANGE

    • TCFH_STOW_REPLACE

    • TCFH_STOW_INITIALIZE

  • 戻り値

    正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。

  • 注意事項

    以下は、STOWコマンドを使用時の注意事項です。

    • メンバーを追加、取り替える場合、WRITEコマンドが先に実行される必要があります。

    • コマンドの実行後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。

5. ファイル・ステータス・コード

データセットの読み書きを実行した後、データセットの状態を確認するには、データセットの情報を保存しているファイル構造体のfile_statusフィールドを調べます。file_statusフィールドには、データセットの状態コードを保存されています。

以下は、データセットのステータス・コードについての説明です。

コード 説明

00

作業が正常に完了した場合です。

02

索引ファイルの場合、重複キーが許可されているデータセットに重複キーが発生した場合です。

10

次のレコードがない場合です。(ファイルを最後まで読み取った場合)

22

索引ファイルや相対ファイルに対し、重複キー・エラーが発生した場合です。

23

キーに該当するレコードが見つからなかった場合です。

37

指定されたオープン・モードがサポートされない場合です。

38

ロックされたファイルを開こうとした場合です。

39

データセットの属性が正しく指定されていない場合です。

41

すでに開いているファイルを開こうとした場合です。

42

すでに閉じられているファイルを閉じようとした場合です。

43

順次モードでREWRITEまたはDELETEコマンドの実行前のコマンドがREADコマンドでない場合です。

44

INPUT/INOUT以外のモードで、READ/STARTコマンドを実行した場合です。

47

INPUT/INOUT以外のモードで、READ/STARTコマンドを実行した場合です。

48

OUTPUT/INOUT/EXTEND以外のモードで、WRITEコマンドを実行した場合です。

49

INOUT以外のモードで、DELETE/REWRITEコマンドを実行した場合です。

99

システム・エラーが発生した場合です。