fread を正しく変換したので、fopen に対して この変換を試してみましょう。
dcl fopen ext('fopen')
entry( char(*) varyingz byvalue,
char(*) varyingz byvalue )
returns( byvalue type file_handle );
しかし、実際には C にストリングはない (ポインターだけ) ので、 これらのポインターは byvalue として渡されます。 このため、ストリングは次のように byaddr でなければなりません。
dcl fopen ext('fopen')
entry( char(*) varyingz byaddr,
char(*) varyingz byaddr )
returns( byvalue type file_handle );
しかし、PL/I はストリングとともに記述子を渡しますが、 C は記述子を解釈できないので、記述子は抑止する必要があります。 このためには、宣言に options(nodescriptor) を追加します。
dcl fopen ext('fopen')
entry( char(*) varyingz byaddr,
char(*) varyingz byaddr )
returns( byvalue type file_handle )
options ( nodescriptor );これで正しく働きますが、パラメーターは入力専用なので、 この変換は最適ではありません。 パラメーターが定数の場合は、nonassignable 属性を指定すれば、 コピーの実行と引き渡しを防ぐことができます。 したがって、fopen の宣言の最適な変換は次のとおりです。
dcl fopen ext('fopen')
entry( char(*) varyingz nonasgn byaddr,
char(*) varyingz nonasgn byaddr )
returns( byvalue type file_handle )
options ( nodescriptor );この時点で、fclose 関数の宣言には、おそらく returns 指定の optional 属性を除けば、意外なものはほとんどありません。 この属性を指定することで、CALL ステートメントで fclose 関数を呼び出せるようになり、戻りコードを処理する必要がなくなります。 しかし、ここで注意しなければならないのが、ファイルが出力ファイルだった場合は、fclose の戻りコードを常に検査する必要があるという点です。最終バッファーが書き出されるのがファイルがクローズされるときのみの場合があり、その書き込みがスペース不足のために失敗する可能性があるからです。
dcl fclose ext('fclose')
entry( type file_handle byvalue )
returns( optional type int byvalue )
options ( nodescriptor );これで、z/OS UNIX 環境で、次のコマンドを使用してプログラムをコンパイルして実行できるようになりました。
pli -qdisplay=std filedump.pli
filedump filedump.pli
次の出力が生成されます。
15408689 938584A4 94977A40 97999683 . filedump: proc
4D86955D 409697A3 899695A2 4D959685 (fn) options(noe
A7858396 97A24094 8189955D 5E151540 xecops main);..