FCD Handling API

본 부록에서는 FCD Handling API의 인터페이스를 사용하여 Main COBOL 애플리케이션 프로그램에서 OPEN된 데이 터 셋을 C로 작성된 서브 프로그램에서 읽기/쓰기를 수행하는 방법에 대해서 설명한다.

1. 개요

OpenFrame과 함께 제공되는 FCD(File Control Description) Handling API 인터페이스를 사용하면, Main COBOL 애플리케이션 프로그램에서 Open된 데이터셋을 C로 작성된 서브 프로그램에서 읽기/쓰기 등의 I/O를 수행할 수 있다. 단, Main COBOL 애플리케이션 프로그램이 MF-COBOL 컴파일러로 컴파일되어야 한다.

FCD Handling API 라이브러리는 데이터셋에 대한 정보를 담고 있는 구조체로 FCD를 사용하는데 이 FCD는 MF-COBOL 컴파일러로 컴파일된 실행 바이너리가 실행되면서 데이터셋을 Open할 때 생성하는 메모리 구조체이다. 따라서, 본 문서에서 설명하는 Tmax FCD Handling API 라이브러리는 MF-COBOL 컴파일러로 컴파일된 실행 바이너리에서만 같이 사용할 수 있다.

처음부터 C로 작성된 애플리케이션 프로그램에서 데이터셋에 대한 I/O를 할 때에는 본 문서에서 설명하는 FCD Handling API 라이브러리를 사용할 것이 아니라 C File Handler 라이브러리를 사용할 것을 권장한다.

FCD Handling API를 사용해서 프로그램을 작성하려면 OpenFrame 바이너리와 함께 배포되는 tfcd.h 헤더 파일을 C로 작성된 서브 프로그램에 포함해야 하고, 해당 서브프로그램을 컴파일 할 때 libtfcd.so 라이브러리를 링크해야 한다.

Tmax FCD handling API의 인터페이스는 다음과 같이 분류할 수 있다.

  • File Open Session

    API 설명

    tfcd_open()

    FCD 구조체에 기술된 데이터셋을 Open한다.

    tfcd_close()

    FCD 구조체에 기술된 데이터셋을 Close한다.

  • Record Access

    API 설명

    tfcd_start()

    RELATIVE 데이터셋 또는 INDEXED 데이터셋에서 다음 번에 읽을 레코드 위치로 이동시킨다.

    tfcd_read()

    순차적으로 데이터셋의 레코드를 읽거나 키를 지정해서 랜덤하게 레코드를 읽는다.

    tfcd_write()

    데이터셋에 새로운 레코드를 기록하거나(WRITE) 또는 기존의 레코드를 다시 쓴다. (REWRITE)

    tfcd_writea()

    레코드의 맨 앞에 ASA 제어문자를 지정해서, 데이터셋에 새로운 레코드를 기록한다.

    tfcd_delete()

    데이터셋에 있는 기존의 레코드를 삭제한다. (RELATIVE/INDEXED)

  • Special Operations

    API 설명

    tfcd_is_file_open()

    FCD 구조체에 기술된 데이터셋이 Open된 상태인지 확인한다.

    tfcd_get_status()

    데이터셋에 I/O를 수행한 후 오류가 발생했는지 확인하기 위해 상태 코드를 가져온다.

    tfcd_get_file_name()

    FCD 구조체에 기술된 데이터셋의 DD명을 가져온다.

    tfcd_get_rec_len()

    FCD 구조체에 기술된 데이터셋의 레코드 길이를 가져온다.

    tfcd_set_file_name()

    FCD 구조체에 기술된 데이터셋의 DD 이름을 지정한다.

    tfcd_set_relative_key()

    FCD 구조체에 기술된 데이터셋의 상대 키를 지정한다. (RELATIVE)

    tfcd_set_key_id()

    FCD 구조체에 기술된 데이터셋의 KEY ID를 지정한다. (INDEXED)

    tfcd_set_rec_len()

    FCD 구조체에 기술된 데이터셋의 레코드 길이를 지정한다.

2. File Open Session

2.1. tfcd_open()

FCD 구조체에 기술된 데이터셋을 Open한다. 데이터셋을 Open하는 작업은 JCL에서 DD문으로 할당된 데이터셋에 대해 실제 레코드를 읽기/쓰기 등의 I/O를 하기 위해 준비하는 과정이다.

데이터셋을 Open할 때 지정하는 OPEN 모드는 다음과 같은 매크로가 tfcd.h 헤더 파일에 정의되어 있다.

#define TFCD_OPEN_INPUT             0   /* OPEN INPUT */
#define TFCD_OPEN_OUTPUT            1   /* OPEN OUTPUT */
#define TFCD_OPEN_INOUT             2   /* OPEN I-O */
#define TFCD_OPEN_EXTEND            3   /* OPEN EXTEND */

성공적으로 데이터셋을 Open한 경우에는 tfcd_get_status()로 확인할 수 있는 상태 코드에 00 값이 저장된다. 단, 이미 Open된 데이터셋에 대해 다시 Open을 시도하면 오류가 발생한다.

  • 프로토타입

    int tfcd_open(void *fcd, int open_mode, int flags);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    open_mode (입력)

    데이터셋 OPEN 모드이다.

    • INPUT

    • OUTPUT

    • INOUT

    • EXTEND

    flags (입력)

    데이터셋을 Open할 때 지정할 수 있는 여러 가지 속성이다.

    • NO REWIND

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다. 성공적으로 데이터셋을 Open했는지는 상태 코드 값을 확인해야 한다.

2.2. tfcd_close()

FCD 구조체에 기술된 데이터셋을 Close한다. 데이터셋을 Close하는 작업은 애플리케이션에서 데이터셋에 대한 읽기/쓰기 등의 I/O를 수행한 후에 응용 프로그램과 물리적인 데이터셋과의 연결을 끊는 과정이다.

성공적으로 데이터셋을 Close한 후에는 tfcd_get_status()로 확인할 수 있는 상태 코드에 00 값이 저장된다. 한 번 Close된 데이터셋은 tfcd_open() API를 사용해서 다시 Open할 수 있다.

  • 프로토타입

    int tfcd_close(void *fcd, int flags);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    flags (입력)

    데이터셋을 Close할 때 지정할 수 있는 여러 가지 속성이다.

    • WITH LOCK

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다. 성공적으로 데이터셋을 Close했는지는 상태 코드 값을 확인해야 한다.

3. Record Access

3.1. tfcd_start()

RELATIVE 데이터셋 또는 INDEXED 데이터셋에서 다음 번에 읽을 레코드 위치로 이동시킨다. 이동시킬 레코드의 위치는 RELATIVE 데이터셋의 경우에는 tfcd_set_relative_key() API를 호출해서 상대 레코드 번호를 지정해 주거나, INDEXED 데이터셋의 경우에는 레코드 포인터 안에 있는 키 위치에 키 값을 미리 저장해 준다.

START API를 실행시킬 때 키 값과 동일한 레코드를 찾거나 키 값보다 크거나 같은 레코드를 찾도록 지정할 수 있는데, 다음과 같은 매크로가 tfcd.h 헤더 파일에 정의되어 있다.

#define TFCD_START_DEFAULT          0   /* START */
#define TFCD_START_EQUAL            1   /* START (equal to full length) */
#define TFCD_START_GTEQ             2   /* START (not less than) */

VSAM 데이터셋의 경우 해당 데이터셋의 기본 RECORD KEY 이외에 ALTERNATE RECORD KEY를 추가 정의할 수 있는데, ALTERNATE RECORD KEY를 이용해서 Start API를 실행하고 싶은 경우 tfcd_set_key_id() API를 호출해서 다음 번 Start API에서 사용할 KEY ID를 지정한다. KEY ID는 Main COBOL 애플리케이션 프로그램의 SELECT 문에서 ALTERNATE RECORD KEY를 지정한 순서대로 번호가 부여된다.

  • 프로토타입

    int tfcd_start(void *fcd, char *record, int flags);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    record (입력/출력)

    이동시킬 레코드의 위치가 저장된 레코드 버퍼 포인터이다.

    flags (입력)

    데이터셋을 Start할 때 지정할 수 있는 여러 가지 속성이다.

    • EQUAL

    • GTEQ

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다. 성공적으로 데이터셋을 START 했는지는 상태 코드값을 확인해야 한다.

3.2. tfcd_read()

순차적으로 데이터셋의 레코드를 읽거나 키를 지정해서 랜덤하게 레코드를 읽는다. 랜덤하게 레코드를 읽는 때는 RELATIVE 데이터셋인 경우에는 tfcd_set_relative_key() API를 호출해서 상대 레코드 번호를 지정해 주거나, INDEXED 데이터셋의 경우에는 레코드 포인터 안에 있는 키 위치에 키 값을 미리 저장해 준다.

VSAM 데이터셋의 경우 해당 데이터셋의 기본 RECORD KEY 이외에 ALTERNATE RECORD KEY를 추가 정의할 수 있는데, ALTERNATE RECORD KEY를 이용해서 랜덤하게 레코드를 읽을 경우 tfcd_set_key_id() API를 호출해서 다음 번 READ API에서 사용할 KEY ID를 지정한다. KEY ID는 Main COBOL 애플리케이션 프로그램의 SELECT 문에서 ALTERNATE RECORD KEY를 지정한 순서대로 번호가 부여된다.

Read API를 실행시킬 때 순차적으로 레코드를 읽을 것인지 랜덤하게 레코드를 읽을 것인지 지정하는 매크로가 tfcd.h 헤더 파일에 다음과 같이 정의되어 있다.

#define TFCD_READ_DEFAULT           0   /* READ */
#define TFCD_READ_NEXT              1   /* READ (sequential) */

가변 길이 레코드 데이터셋의 경우 Read API를 사용해서 데이터셋의 레코드를 읽었을 때, tfcd_get_rec_len() API를 호출해서 읽은 레코드 길이를 얻을 수 있다. 이때 얻은 레코드의 길이는 RDW를 제외한 레코드의 데이터 부분의 길이이다.

  • 프로토타입

    int tfcd_read(void *fcd, char *record, int flags);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    record (입력/출력)

    데이터셋에서 읽어 들인 레코드가 저장될 레코드 버퍼 포인터이다.

    flags (입력)

    데이터셋을 Read할 때 지정할 수 있는 여러 가지 속성이다.

    • DEFAULT

    • NEXT

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다. 성공적으로 데이터셋을 READ했는지는 상태 코드값을 확인해야 한다.

3.3. tfcd_write()

데이터셋에 새로운 레코드를 기록하거나(Write) 또는 기존의 레코드를 다시 쓴다. (Rewrite)

순차 데이터셋의 경우에는 데이터셋의 마지막에 레코드를 기록하고, RELATIVE 데이터셋의 경우에는 tfcd_set_relative_key() API를 호출해서 저장될 상대 레코드 번호를 지정한다. INDEXED 데이터셋의 경우에는 레코드 포인터 안에 있는 키 순서에 맞게 레코드가 저장된다.

Write API를 실행시킬 때 새로운 레코드를 기록하는 것인지, 기존의 레코드 내용을 갱신하는 것인지를 지정하는 매크로가 tfcd.h 헤더 파일에 다음과 같이 정의되어 있다.

#define TFCD_WRITE_DEFAULT          0   /* WRITE */
#define TFCD_WRITE_REWRITE          1   /* REWRITE */

가변 길이 레코드 데이터셋의 경우 Write API를 사용해서 데이터셋의 레코드를 기록하기 전에 기록하려는 레코드의 길이를 tfcd_set_rec_len() API를 호출해서 지정할 수 있다. 이때 레코드의 길이는 RDW를 제외한 레코드의 데이터 부분의 길이를 지정한다.

  • 프로토타입

    int tfcd_write(void *fcd, char *record, int flags);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    record (입력)

    데이터셋에 기록할 레코드가 저장되어 있는 레코드 버퍼 포인터이다.

    flags (입력)

    데이터셋을 Write할 때 지정할 수 있는 여러 가지 속성이다.

    • WRITE

    • REWRITE

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다. 성공적으로 데이터셋을 WRITE했는지는 상태 코드값을 확인해야 한다.

3.4. tfcd_writea()

레코드의 맨 앞에 ASA 제어문자를 지정해서 데이터셋에 새로운 레코드를 기록한다. Writea API를 실행할 때 지정하려고 하는 ASA 제어문자의 종류를 지정하는 매크로가 tfcd.h 헤더 파일에 다음과 같이 정의되어 있다.

#define TFCD_WRITEA_AFTER           0   /* AFTER */
#define TFCD_WRITEA_BEFORE          1   /* BEFORE */

#define TFCD_WRITEA_TAB             2   /* TAB */
#define TFCD_WRITEA_PAGE            4   /* PAGE */
#define TFCD_WRITEA_MNEMONIC        8   /* MNEMONIC */
  • 프로토타입

    int tfcd_writea(void *fcd, char *record, int lcount, int flags);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    record (입력)

    데이터셋에 기록할 레코드가 저장되어 있는 레코드 버퍼 포인터이다.

    lcount (입력)

    레코드를 출력하기 전에 이동시킬 라인 수이다.

    flags (입력)

    데이터셋을 WRITE할 때 지정할 수 있는 여러 가지 속성이다.

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다. 성공적으로 데이터셋을 WRITE했는지는 상태 코드값을 확인해야 한다.

3.5. tfcd_delete()

RELATIVE 데이터셋이나 INDEXED 데이터셋의 경우 방금 전에 읽은 레코드를 삭제한다.

  • 프로토타입

    int tfcd_delete(void *fcd, char *record, int flags);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    record (입력)

    데이터셋에서 삭제할 레코드가 저장되어 있는 레코드 버퍼 포인터이다.

    flags (입력)

    데이터셋을 DELETE할 때 지정할 수 있는 여러 가지 속성이다.

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다. 성공적으로 데이터셋을 DELETE 했는지는 상태 코드값을 확인해야 한다.

4. Special Operations

4.1. tfcd_is_file_open()

FCD 구조체에 기술된 데이터셋이 Open된 상태인지 확인한다. Main COBOL 애플리케이션 프로그램에서 Open한 데이터셋에 대한 DD 이름을 바꾸기 전에 데이터셋이 Open된 상태인지를 확인하기 위해 사용한다.

  • 프로토타입

    int tfcd_is_file_open(void *fcd);
  • 파라미터

    파라미터 설명

    fcd (입력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

  • 반환값

    데이터셋이 Open된 상태이면 1 Open된 상태가 아니면 0 값이 반환된다.

4.2. tfcd_get_status()

데이터셋에 I/O를 수행한 후 오류가 발생했는지 확인하기 위해 데이터셋 상태 코드를 가져온다. 일반적으로 상태 코드의 값이 스페이스이면 데이터셋에 대한 I/O 기능이 성공적으로 수행된 것을 의미한다.

데이터셋 I/O를 수행하다가 심각한 시스템 오류나 OpenFrame 라이브러리 오류가 발생한 경우라면, 오류 메시지와 함께 프로그램이 종료되지만, END OF FILE 등과 같은 일반적인 데이터셋 I/O 오류의 경우에는 프로그램이 종료되지 않고, 적당한 상태 코드 값이 설정된 후에 I/O 함수가 정상 반환된다. 따라서 I/O 함수를 수행한 이후에는 반드시 tfcd_get_status() 함수로 오류가 발생했는지를 확인해야 한다.

데이터셋 I/O 함수에서 설정될 수 있는 데이터셋의 상태 코드 값은 MicroFocus Server Express 온라인 매뉴얼을 참고한다.

  • 프로토타입

    int tfcd_get_status(void *fcd, char *status);
  • 파라미터

    파라미터 설명

    fcd (입력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    status (출력)

    데이터셋의 상태 코드를 담을 버퍼이다.

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다.

4.3. tfcd_get_file_name()

FCD 구조체에 기술된 데이터셋의 DD 이름을 가져온다. 데이터셋이 Open된 데이터셋이나 Close된 데이터셋이나 모두에게 사용할 수 있는 API이다.

  • 프로토타입

    int tfcd_get_file_name(void *fcd, char *file_name);
  • 파라미터

    파라미터 설명

    fcd (입력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    file_name (출력)

    데이터셋의 DD 이름을 담을 버퍼이다.

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다.

4.4. tfcd_get_rec_len()

FCD 구조체에 기술된 데이터셋의 레코드 길이를 가져온다. 고정 길이 데이터셋이 처음 Open된 시점에 전체 데이터셋의 고정 레코드 길이를 얻을 때 사용할 수도 있고, 가변 길이 데이터셋 레코드를 READ API로 읽은 후에 읽은 레코드의 길이를 얻을 때에도 사용된다.

가변 길이 레코드 데이터셋의 경우 레코드의 길이는 RDW를 제외한 레코드의 데이터 부분의 길이이다.

  • 프로토타입

    int tfcd_get_rec_len(void *fcd, int *reclen);
  • 파라미터

    파라미터 설명

    fcd (입력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    reclen (출력)

    데이터셋의 레코드 길이를 담을 버퍼이다.

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다.

4.5. tfcd_set_file_name()

FCD 구조체에 기술된 데이터셋의 DD 이름을 지정한다. Main COBOL 애플리케이션 프로그램에서 Open했던 데이터셋의 DD 이름을 바꾸어, 새로운 데이터셋을 Open하기 위해 사용한다. 본 API를 사용하기 전에 Open되어 있는 데이터셋은 Close API를 사용하여 Close 상태로 변경해야 한다.

  • 프로토타입

    int tfcd_set_file_name(void *fcd, char *file_name);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    file_name (입력)

    데이터셋에 지정할 DD 이름이다.

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다.

4.6. tfcd_set_relative_key()

FCD 구조체에 기술된 데이터셋의 상대 키를 지정한다 (RELATIVE). RELATIVE 데이터셋의 경우 tfcd_set_relative_key()로 지정한 상태 키 위치에 새로운 레코드가 저장되거나, 저장되어 있던 기존 레코드가 읽힌다.

  • 프로토타입

    int tfcd_set_relative_key(void *fcd, int relative_key);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    relative_key (입력)

    RELATIVE 데이터셋의 상태 키이다.

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다.

4.7. tfcd_set_key_id()

FCD 구조체에 기술된 데이터셋의 KEY ID를 지정한다. (INDEXED)

ALTERNATE RECORD KEY가 추가 정의되어 있는 데이터셋에 대해 ALTERNATE RECORD KEY를 이용해서 랜덤하게 레코드를 읽을 경우 tfcd_set_key_id() API를 호출해서 다음 번 Read API에서 사용할 KEY ID를 지정한다.

  • 프로토타입

    int tfcd_set_key_id(void *fcd, int key_id);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    key_id (입력)

    데이터셋의 지정하고자 하는 KEY ID이다.

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다.

4.8. tfcd_set_rec_len()

FCD 구조체에 기술된 데이터셋의 레코드 길이를 지정한다. 가변 길이 데이터셋 레코드를 Write API를 사용해서 기록하기 전에 기록할 레코드의 길이를 지정할 때 사용한다.

가변 길이 레코드 데이터셋의 경우 레코드의 길이는 RDW를 제외한 레코드의 데이터 부분의 길이를 지정한다.

  • 프로토타입

    int tfcd_set_rec_len(void *fcd, int reclen);
  • 파라미터

    파라미터 설명

    fcd (입력/출력)

    Main COBOL 애플리케이션 프로그램에서 전달된 FCD 구조체 주소이다.

    reclen (입력)

    데이터셋의 지정하고자 하는 레코드 길이이다.

  • 반환값

    성공적으로 함수가 실행된 경우 0 값이 반환된다.