04.2オペレーター応答とコマンドを受け取る(WTORとQEDIT)

By 神居 - Posted: 2008/12/12 Last updated: 2009/11/11 - Leave a Comment

プログラムがコンソール・オペレーターと通信(会話)を行うには2つの方法があります。1つはメッセージを出力して、そのメッセージに対する応答を受け取る方法です。もう1つはメッセージとは無関係にオペレーターがMODIFYコマンドやSTOPコマンドによってプログラムに指示を与える方法です。
前者はプログラムでオペレーターの判断を必要とする何らかの事態が起きたときに利用されます。例えばデータセットを初期化することがパラメーターで指定された時に、本当にクリアーしてもいいのかを再確認するような機能を持たせる場合や、誤った入力データを見つけたような時に、処理不能で異常終了するのか、誤ったデータを無視して処理を続けるのか、などを選択させるような場合に、その旨のメッセージをコンソールに出して、この後どう動くかをオペレーターに判断してもらうようなプログラムを作ることができます。
後者はオペレーターの都合によってプログラムに特定の動作を行わせたり、動きを変える場合などに利用されます。バッチ処理のように入力データが終わったらプログラムの処理も終わるのではなく、一定時間あるいはオペレーターが指示するまで動き続ける常駐型のプログラムを作る際に必要となる機能です。MODIFYコマンドでプログラムの動作や機能を変更し、STOPコマンドでプログラムを終了させるのが一般的です。


メッセージに対するオペレーター応答を受け取る

WTORマクロはコンソールにメッセージを表示して、オペレーターからの応答を受け取ります。出力するメッセージの指定方法はWTOマクロと同じですが、オペレーターからの応答を受け取る領域とその長さ、および待ち受けのためのECBアドレスを追加で指定します。
WTORマクロの完了はオペレーターが応答を入力したときではありません。コンソールへのメッセージ出力がスケジュールされたら完了してプログラムに戻ってきます。この時返答領域にオペレーターからの応答が入力されているかはわかりません。WTORマクロで指定したECBでWAITマクロを発行して応答入力を待ち受けなければなりません。オペレーターが応答すればWAITマクロが完了します。
バッチ処理のプログラムではあまり必要ありませんが、WTORマクロの後ですぐにWAITを出さず、オペレーターが入力するまでの間も止まることなく別の処理を行うこともできます。またWTORもマクロ完了時にGR1にメッセージ識別番号が返ります。必要なら応答を待たずにメッセージを取り消すことも可能です。

最初の例は古典的なWTORマクロのコーディングです。MSPとVOS3もこの書き方になります。2番目はMVS(z/OS)で利用可能なメッセージ・テキストをマクロの外に記述する方法です。


オペレーター・コマンドを受け取る

アドレス空間に常駐してオペレーターが指示するまで一定の処理を行い続けるサーバー型のプログラムでは、「次に何を行うか?」と言ったことをオペレーターからのコマンドによって判定したい場合があります。このような場合にOSのMODIFYコマンドやSTOPコマンドでオペレーターの指示を受け取ることができます。このプログラムはMODIFYおよびSTOPコマンドを処理するサンプルです。WTORに比べるとロジックはやや複雑になりますが、STCタスクとして動かす常駐型のサーバープログラムでは必須となる機能です。

プログラムは起動時の初期設定として、EXTRACTマクロをサンプルのように発行してMVSのコマンドスケジューラーリスト(COMMAREA)のアドレスを得ます。STARTコマンドで起動されたSTCタスクの場合は、STARTコマンド用CIBがチェインされているのでそのアドレスを求めます。これはCOMMAREA内のCOMCIBPTフィールドにあります。バッチジョブなどSTARTコマンド以外の方法で起動された場合はチェインされていません。このアドレスを調べればSTARTコマンドで起動されたSTCタスクかそうでないかを判定できます。STC起動の場合はSTARTコマンド用CIBをBLOCK指定のQEDITマクロを発行してクリアーしておきます。(サンプルでは内部サブルーチンFREECIBで行っています)STARTコマンドでパラメーターを指定していなくてもCIBは作成されることを知っておいて下さい。

STARTコマンドでパラメーターを指定する場合はこのようにコマンドを入力します。例えば S MYSTC1,,,MODE=DEBUG とすれば MODE=DEBUG の文字列がSTARTコマンド用CIBで渡されます。CIBDATLNはパラメーターの長さ、CIBDATAがパラメーター文字列です。
次にMODIFYコマンド用のコマンドキューを作るため、CIBCTR指定のQEDITマクロを発行します。CIBCTRには同時に入力可能なコマンド数(最大255)を指定します。入力されたコマンドはいっぺんにプログラムに渡ってくるわけではありません。1つずつ順番に取り出し、1つずつ処理することができます。そのためCIBCTRは1でもかまいませんが、コマンド処理に時間が掛かるとオペレーターは次のコマンドを入力してもMVSにリジェクトされてしまいます。極端に多くする必要なありませんが、10個程度はあってもいいでしょう。CIBCTR=10は未処理のコマンドを10個分OS内でキューイングできることになります。ORIGINパラメーターにはCOMMAREAのCOMCIBPTフィールドを指定します。これでオペレーターコマンドを受け取る準備ができました。
EXTRACTを出した後QEDITも含めてOSのコントロールブロック(制御表)をプログラムで直接参照します。このためコントロールブロックをフィールド名でアクセスするためにコントロールブロックのマッピングマクロを使います。参照するコントロールブロックはCOMMAREAとCIBです。それぞれIEZCOMマクロとIEZCIBマクロでマッピングします。DSECT展開マクロでないためサンプルのように自分でDSECTを定義します。MSPではKDJCOMマクロとKDECIBマクロ、VOS3ではJDJCOMマクロとJDECOMIBマクロになります。このサンプルで参照しているものであればフィールド名は同じです。

プログラムはコマンドを受け取るタイミングになったら、COMMAREA内のCOMECBPTフィールドでポイントされているコマンド入力待ち合わせ用のECBを指定してWAITします。COMECBPTフィールドはECBそのものではなく、ECBアドレスが格納されたポインターフィールドです。
すでに何らかのコマンドが入力されていたり、新たなコマンドが入力された時点でWAITは解除されます。COMMAREA内のCOMCIBPTフィールドには次の処理すべきコマンドのCIBアドレスが入っています。ここが0ならすべてのCIBは処理済みなので再びWAITを発行してオペレーターコマンド入力待ちになります。CIBアドレスが入っていればそのCIBを調べることで入力されたコマンド文字列を求めることができます。CIBのCIBVERBフィールドは入力されたコマンド種類を示します。x44ならMODIFY、x40ならSTOPコマンドですが、サンプルのように必ずラベル名で参照します。CIBSTOPはSTOPコマンドを示すEQUラベルです。通常STOPコマンドはプログラムの終了を意味しますから、サンプルのように終了処理へ移ってしまってかまいません。MODIFYコマンドの場合は入力されたコマンド文字列と長さが必要なのでCIBから求めます。CIBDATLNはコマンド文字列の長さ、CIBDATAがコマンド文字列です。コマンドを入力したコンソールIDもわかります。MSPとVOS3ではCIBCONIDフィールド、z/OSではCIBX内のCIBXCNIDまたはCIBXCNNMフィールドを利用します。CIBXはCIBに連続して配置されている拡張CIBで、先頭アドレスはCIBアドレスにCIBXOFFフィールドの値を加えることで求められます。これによって特定のコンソールからのコマンド入力かどうかをチェックしたり、コマンド発行元コンソールを記録することなどもできます。
コマンド文字列が求められたら、対応するコマンド処理を行い、その後処理済みコマンドのCIBを解放します。(サンプルでは内部サブルーチンFREECIBで行っています)先にCIBを解放してもかまいませんが、その場合は入力されたコマンド文字列をプログラム側の領域に適宜コピーしておく必要があります。解放したCIB領域を後から参照してはなりません。このサンプルは入力されたコマンド文字列と長さを先頭の32バイト分コンソールにエコーしています。

コマンド処理が終わりCIBを解放したら、次のコマンドをチェックします。再びCOMCIBPTフィールドを参照して次のCIBがセットされているかを調べます。COMCIBPTはCIBを解放するためのBLOCK指定のQEDITマクロによって内容が更新されます。次のCIBがなければWAITへ回ります。このようなサイクルでオペレーターコマンドの処理を行っていきます。MODIFYコマンドで独自のコマンド処理をする場合であってもプログラムはSTCタスクである必要はありません。バッチで起動されても同じロジックで処理できます。異なる点は初期設定時にSTARTコマンド用CIBがあるかないかです。もしSTARTコマンドではパラメーターを受け取らないなら、少し乱暴ですが初期設定時にSTCかどうかを判定せずにSTARTコマンド用CIBをQEDITで無条件にクリアーしてもかまいません。バッチの場合はQEDITがエラーになるだけでABENDするようなことにはなりません。


Posted in 中級編 • • Top Of Page