open
関数はプロシージャーでありC言語の関数であることがわかった。
これでバインド・ディレクトリーQC2CLE
を定義しておけば
RPG からいろいろなC言語の関数を使えることがわかった。
RPG の使用範囲を広げるには C言語の関数を調べる必要がある。
もう少し正しく言えばopen
という関数は C言語ではなく
C言語が参照する「ライブラリー関数」である。
C言語の関数をIBM マニュアルによって調べてみようという方は
C言語のライブラリー関数を調べてみて欲しい。
それでは C言語のopen
という関数はどのように定義されているのだろうか?
C言語のプロトタイプ: QSYSINC/H,FCNTL
では
QBFC_EXTERN int open(const char *, int, ...);
のように簡単な関数として定義されている。
先の RPGの open
関数の実行:
FD = open('/tmp/hello.txt': O_CREAT + O_TRUNC + O_WRONLY + O_CCSID : O_RDWR : EBC_CCSID);
を C言語で記述すると
fildes = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_CCSID, S_IRWXU | S_IRWXO, ccsid));
となる。
RPG の場合とほとんど変わりはない。
さてパラメータであるが RPG ではパラメータを
O_CREAT + O_TRUNC + O_WRONLY + ....
と+
演算で結合しているが C言語でも
O_WRONLY | O_CREAT | O_TRUNC | O_CCSID
と書いているのは'|'
は OR の意味でありこれも結合を意味している。
RPG では
// oflag Values for open() * Create file if it doesn't exist D O_CREAT C 8 * Exclusive use flag D O_EXCL C 16 * Truncate flag D O_TRUNC C 64
と定義されており C言語でも
/*******************************************************************/ /* oflag Values for open() */ /*******************************************************************/ #define O_CREAT 00010 /* Create file if it doesn't exist */ #define O_EXCL 00020 /* Exclusive use flag */ /* 00040 reserved */ #define O_TRUNC 00100 /* Truncate flag */
のように定義されている。
次にopen
関数が戻す FD であるがこれはファイル識別子(File Descripter)と呼ばれていて
生成されたファイルのユニークな(一意的な)番号である。
生成された後はファイル識別子によってファイル操作を行うことになる。
このような、ある生成された識別子によってオブジェクトを識別する方法は
オープン系ではよく用いられる一般的な方法なので感じといて覚えておくとよい。
Windows の世界でもクライアントの画面の中には数多くのWindowが同時多数に存在する。
そこでこれらを識別するために Windowハンドルという識別子が利用される。
それと気をつけて頂きたいのが ファイルをオープンした後のclose
関数による
ファイルのクローズである。
RPG の場合は何でもシステムの面倒見がよくてファイルをクローズしなくても
プログラムが終了するとシステムが勝手に閉じてくれるのだが
オープン系となるとそうはいかない。
open
でファイルをオープンした後はちゃんと自分でclose
しておかなければ
ならないのだ。
RCLRSC
を実行してもファイルは閉じられない。
RCLACTRP
を実行した場合はファイルは閉じられる。
ジョブの終了した時点ではファイルは閉じられる。
必ずclose
によってファイルを閉じることを忘れないように !!
と言いたいが実際はclose
を忘れる開発者はほとんどいない。
あるオープン系の開発会社のプログラマーがメモリを動的に確保して
最後にその解放(削除)を忘れたりしてしませんか? と言ったことがあるが
そんな程度の人は一般にはいない。