SMFデータセットのアンロード(IFASMFDP)

By kamii - Last updated: 金曜日, 11月 21, 2008

SMFデータセットのアンロードJCLサンプル

SMFデータセットを順次データセットにアンロードします。SMFデータセット内のすべてのレコードがアンロードされます。TYPE(0:255)
入力元SMFデータセットの内容はクリアーせずにそのまま残します。ACTIVEなSMFデータセットでもアンロードは可能です。日付や時刻でアンロードするレコードを絞り込むこともできます。日付ならMVSではDATE(2008001,2008031)、MSPではDATE(080101,080131)のように制御文に追加します。
MSPではプログラム名はKDKSMFDPとなります。なおVOS3ではまったくJCLが異なりますのでSMSのマニュアルを参照して下さい。


アンロードするレコードを、レコード・タイプで選択し出力先データセットを振り分けることもできます。その場合はOUTDD制御文を複数個定義し、レコード・タイプに対応した出力先DD名を指定します。
サンプルではレコード・タイプ30をWORK.SMFMANX.UNLOAD.REC30へ、レコード・タイプ60番台をWORK.SMFMANX.UNLOAD.REC60へアンロードします。


Filed in ありがたいサンプルJCL

ありがたいOSコマンド集(SLIPコマンド)

By kamii - Last updated: 木曜日, 11月 20, 2008

SLIPコマンド設定状況の表示


SLIPコマンド・サンプル集


複数のメモリー範囲にSAトラップを掛ける例

Filed in システムプログラマーのための手引きいろいろ

TSO/TESTコマンドによるデバッグ

By kamii - Last updated: 木曜日, 11月 20, 2008

TSOのTESTコマンドはMVSにおける標準デバッガーです。WindowsやUnixのビジュアル開発ツールのような多機能なデバッガーではありませんが、アセンブラー言語のプログラムのちょっとしたデバッグには結構役に立ちます。レジスターやメモリー領域の表示、ブレークポイントの設定など基本的なデバッグができます。
※TESTコマンドはISPFのコマンドシェル・パネル(オプション6)では実行できません。ネイティブなTSOコマンドプロンプトから実行します。


TESTコマンドを使ってプログラムを起動する

TESTコマンドで実行したいプログラムを、’格納されているロードモジュールライブラリー(メンバー名)’で指定します。起動後、プログラムは入口点(先頭の命令)でブレークした状態になり、TESTのサブコマンド入力待ちになります。


サブコマンド(プログラムを実行する)

GOコマンドはブレークしている場所からプログラムの実行を行います。次のブレークポイントを見つけるか途中でABENDするとそこで停止します。最後の命令を実行するとプログラムは終了します。WHEREコマンドで現在どこでブレークしているかがわかります。ENDコマンドでTESTコマンドを終了します。
プログラムの中でWTOマクロを使っている場合、メッセージはコンソールだけでなくTSO端末にもエコーされます。


サブコマンド(レジスターやメモリー内容を表示する)

LISTMAPは仮想記憶の割り当て状態のサマリーを表示します。プログラム自身がGETMAINしていなくても、TSOおよびTESTコマンドが制御のために割り当てた領域も含まれます。LISTPSWは現在のPSW内容を編集して表示します。

LISTコマンドはレジスターやメモリー領域の内容を表示します。
1Rはレジスター1の内容を、0R:15Rは全てのレジスターの内容を表示します。メモリーの内容はアドレスまたはラベル名で表示できます。アドレスは16進数で指定し末尾に.(ピリオド)を付けます。LENGTHパラメーターで長さを指定できます。省略すると4バイトだけしか表示されません。XCは表示タイプで16進数(HEX)と文字(CHAR)の両方が表示されるダンプ形式です。LENGTHパラメーターに代えてアドレスとアドレスを:(コロン)で繋げば、そのアドレス範囲のメモリー内容を表示できます。メンバー名.CSECT名とすればプログラムの先頭から表示できます。+xxxxのようにプログラムの先頭からの相対アドレスで表示することもできます。この場合は末尾にピリオドは付けません。
ラベル名はソースプログラム内に書いたラベル名です。ラベル名を使う場合はアセンブルおよびバインド(リンクエディット)両方のパラメーターにTESTオプションを指定する必要があります。TESTオプションによってソースプログラム中のラベル名などのシンボル情報がオブジェクトとロードモジュールに出力されます。

アドレスは直接指定の他にレジスターを使った間接アドレスでも指定できます。12R%のようにRの後ろに%を置くと、そのレジスターの内容をアドレスとするメモリーの内容を表示します。


サブコマンド(レジスターやメモリー内容を変更する)

レジスターやメモリーの内容は表示するだけでなく、変更することもできます。もちろん変更できるのは自分のプログラムまたはGETMAINした領域です。割り当てられている領域はLISTMAPコマンドで確認できます。
nR=X’xxxxxxxx’とすれば、n番レジスターに値xxxxxxxxをロードします。+20=はプログラムの先頭からx20バイト離れたアドレス、20EF4.=はx20EF4番地のアドレスのメモリー内容を変更することになります。デバッグ中にレジスターやメモリーの内容を変えてプログラムの動きがどう変わるかを確認することができます。


ブレークポイントの設定

ブレークポイントはATで設定できます。ブレークする場所をラベル名、プログラムの先頭からの相対アドレスで指定できます。Cパラメーターは通過回数カウンター値です。3と指定すれば3回目にそこを通過する時ブレークします。ここでカウンターがリセットされるのでループが続くと、さらに3回目の通過で再びブレークします。つまり3,6,9と3の倍数回目で止まります。2であれば偶数回数目、10であれば10,20,30回目になります。Cパラメーターを使うとループの中にブレークポイントを設定する時、いちいちプログラムが止まらなくなるのでデバッグ効率が上がります。なおブレークは設定できますが、1命令ずつ止めるステップ実行はできないので、必要に応じてブレークポイントを細かく設定します。
ブレークする箇所の後ろに、ブレークと同時に実行するコマンドを指定することもできます。2番目のサンプルではブレークしたら同時にその時点のPSWとレジスター0から15の内容を表示します。

TESTコマンドはブレークする箇所にSVC 97と言う命令(x0A61)を埋め込みます。そのため命令コードやオペランドそのものをデータとして処理しているようなプログラムは正しく動かなくなりますから注意が必要です。

太字箇所が命令オペランドがデータとして参照されているものです。サンプルのようにWAITマクロを書いてアセンブルして見ればよりわかりやすいでしょう。

Filed in S/370アセンブラー講座

05.1プログラムをABENDさせる(ABEND)

By kamii - Last updated: 木曜日, 11月 20, 2008

実行中にデータやパラメーターの誤りを見つけた時、自ら論理の矛盾やデータの不整合がわかった時、プログラム自ら途中で処理を止めて実行を中止することがあります。原因や理由が明確ならばメッセージやログデータによってそれを指摘した上で完了コードを設定して終了することもできます。しかしエラーが起きたことはわかったが、原因や理由はわからない場合、プログラムは自分自身を異常終了させるようOSに要求することができます。アベンドすべきかノーマルエンドすべきかの基準はありませんので、デザイナーが自由に決められます。わからなければ他のソフトウェアがどうしているかなどを参考にするのもいいでしょう。


プログラムをABENDさせる?

ABENDマクロはプログラムの異常終了を行います。ABENDマクロはほとんどが定位置パラメーターです。1番目のパラメーターは完了コード(ABENDコード)を指定します。2番目がダンプを出力するかどうか、3番目がサブタスクがABENDマクロを発行する時、自タスクだけがABENDするのかジョブステップ全体をABENDさせるかの指定です。シングルタスクのプログラムではどのみちステップは終了します。

最初の例は完了コードU0001でABENDさせます。2番目の例は完了コードをレジスターに入れて指定しています。ABEND時にダンプの出力を行います。プログラムを実行するJCLにはSYSUDUMP,SYSABENDあるいはSYSMDUMP DD文の定義が必要です。ABENDマクロによるダンプ要求ではダンプの出力先データセットをあらかじめOPENしておく必要はありません。3番目の例はダンプは出力せずにジョブステップごと終了させます。ダンプを出力するならDUMP,STEPと指定できます。

ABENDコードは0?4095が指定でき、Unnnnの形式で表示されます。Sxxx形式のコードを指定することもできますが、MVSのABENDコードと混同するので特別な理由が無い限りシステムABENDコードは使わない方がいいでしょう。



プログラムをABENDさせる?

ABENDマクロを使わないで、プログラム割込みによる方法です。
システムプログラムではしばしばわざと誤った命令を実行してABENDさせる方法が採られます。最初の例は奇数レジスターを指定した除算です。DR R1,R1と書くのと同じですが、アセンブラーが構文チェックをするのでDC命令で命令コードを直接書き込みます。2番目の例はEX命令で自分自身を指します。どちらも意図的に行わない限り起き得ないABENDなので、「何かエラーを見つけてわざとそこでABENDさせたんだな」と言うことを伝えられます。
昔こう言った手法をがあることを知らない頃は「これ書いた奴ってバカじゃないの?」なんて思ったことがありますが、バカなのは私でした。

なお故意によるプログラム割込みでABENDさせる時は、S0C1やS0C4あるいはS0C7,S0C9と言った、本当のバグや誤ったデータによって起きるABENDと混同してしまうコードを使うのは避けましょう。

Filed in .基礎編

ファイル転送を行う(FTPクライアント)

By kamii - Last updated: 水曜日, 11月 19, 2008

FTPクライアント実行JCLサンプル(MVS)

メインフレームではFTPはサーバーとして利用されることが多いですが、FTPクライアントも利用できます。特にバッチのジョブ・ステップとして実行すれば、転送作業を自動化したり、他のステップの処理と連動させたりできますから、覚えれば便利な機能になります。メインフレーム←→PC間で利用する場合、相手側PCにはFTPサーバーが必要です。


FTPクライアント実行JCLサンプル(MSP)

MSPではFTPクライアントを使用するにはアトリビュート・データセットを作成しておく必要があります。このデータセットに接続先のホスト名(IPアドレス)とユーザーID・パスワードをあらかじめ登録しておかなければなりません。TSSセッションで直接使うならアトリビュート・データセットは不要だったかも知れません...


FTPクライアント実行JCLサンプル(VOS3)

VOS3のFTPクライアントのサンプルです。VOS3の方はMVSに近いもの(と言うよりは標準のFTPに)があります。

Filed in ありがたいサンプルJCL

ユーティリティ

By kamii - Last updated: 水曜日, 11月 19, 2008

MVS,MSPおよびVOS3では多くのユーティリティ・プログラムに互換があります。プログラム名は違っても機能、JCL、制御文などはまったく同じかほとんど同じと言っていいものが多いです。特に古くからある伝統的なユーティリティは元々がMVS互換のためかほとんど同じです。ディスクのバックアップなどに使用するユーティリティなどは後年になってそれぞれのメーカーから独自のものが出てきていますから同等ではあっても互換はありません。
同じ(互換)ユーティリティかどうかはMVSのユーティリティ・プログラム名で実行できるかどうかでおおよその見当がつきます。MVSのプログラム名の別名が付いていれば互換ユーティリティと考えていいでしょう。


Filed in OSの互換性

07.REXX 外部コマンド

By takao - Last updated: 水曜日, 11月 19, 2008
REXXから外部コマンドを発行する方法について、書きます。
もっとも乱暴な話をすると、REXXプログラムの中に外部コマンドを書くと実行されます。たとえば、
/* REXX */
STATUS
say RC

TSOのSTATUSコマンドが実行されると思います。ただし、暗黙の前提をフルに使っています。
暗黙の設定を順に説明します。STATUSは変数として値をもっていないので、’STATUS’という値をもちます。これはREXXコマンドにはないので、REXXは外部環境に渡します。外部環境がTSOであった場合、無事にSTATUSコマンドが実行されます。RCは外部コマンド実行後にリターン・コードが入る特別な変数名です。

変数の暗黙の値を利用するのは、わかりにくくなる原因なので、”STATUS”というように”で囲むことが強く推奨されています。

ここで外部環境とあっさり書きましたが、状況は簡単でないことも多いでしょう。次のように環境が重なっている場合が普通かと思います。
REXX
ISPF
TSO
…..
この層になっている環境において、どれに対してコマンドを渡すか明示しておいたほうが安心です。
そのためには、ADDRESSコマンドを使います。(とはいいながらも、ADDRESS以降にどの環境をどういう名前で指定するかは決まっているので、事前にマニュアルで調べることが必要です。)
たとえば、ISPFが動作している環境でISPFに対してコマンドを出す場合、
ADDRESS ISPEXEC ‘SELECT service’

MVSが提供しているサービスを利用する場合にも、ADDRESSを使います。
ADDRESS MVS command …..
というように指定します。
ここで、commandはこのプログラム内だけで使うスタックを定義する、NEWSTACK,QSTACK,DELSTACK,DROPSTACK, MAKEBUF,DRIPBUF,QBUF,QELEM)。 実行モードを制御するEXECUTIL, I/OサービスをしてくれるEXECIOなどがあります。

ここではとくに、I/OサービスのEXECIOをサンプルとしてみてみましょう。今までの勉強の確認にもなります。

/* REXX */
"ADDRESS TSO ALLOC DD(INDD) DA('SYS1.PARMLIB(IEASYS00)') SHR REUSE"
"ADDRESS MVS EXECIO * DISKR INDD (FINIS"
"ADDRESS TSO FREE DD(INDD)"

DO QUEUED()
 PARSE PULL record
 SAY record
END
EXIT

2行目は、TSO CLISTでおなじみのAllocateコマンドです。3行目は、MVSサービスでREXXに提供されているEXECIOです。*はレコードを全部読むという意味で、次のDISKRは読み取りを意味します。INDDはAllocateコマンドで設定したDD名です。FINISは読み終わったらファイルをクローズするという意味です。読み取られたレコードはすべてスタックにおかれています。
つまり、スタックにファイルを読み取りたかったら、このままの形式で(もちろんDD名だけは考慮が必要ですが)読み取れます。
4行目は、TSO CLISTでおなじみのFREEコマンドです。アロケートしたファイルを開放します。

次のDO~ENDはスタックにある限りループします。QUEUED()はスタックの大きさを返します。
スタックからデータを取りだすために、PULLし、データをrecorという変数にPARSEで割り当てます。SAYで表示することの繰り返しです。
単純ながらプログラムらしくなってきましたね。

次にEXECIOの別の使い方を紹介してみます。ここでは、ADDRESSは面倒なので省略します。多くの場合、うまく外部コマンドは見つかり実行されます。


/* REXX */
"ALLOC DD(INDD) DA('SYS1.PARMLIB(EIASYS00)') SHR REUSE"
"EXECIO * DISKR INDD (STEM rec. FINIS"
"FREE DD(INDD)"

DO i=1 TO rec.0
 SAY rec.i
END
EXIT

EXECIOにおいて、STEM rec. が加わってます。これで配列rec.にファイルが読み込まれます。
配列からデータを取り出すために、iというカウンターでループしてデータを取り出します。配列のrec.0には、要素数が入っています。

以上で基本的な外部コマンドの使い方を終わります。
Filed in REXX入門

02.2インターバルタイマー(STIMER)

By kamii - Last updated: 水曜日, 11月 19, 2008

時間に関する機能には、日付と時刻の取得の他にインターバルタイマーがあります。間隔計時機構とも呼ばれ、一定時間おきに行う処理を作る際や一定時間プログラムの実行を止める場合などに利用されます。


10秒間プログラムの実行を停止する

一定時間プログラムの実行を止めるにはSTIMERサービスのWAIT機能を使います。STIMERマクロの最初の定位置パラメーターにWAITを指定し、続けて待ち合わせ時間を定義したパラメーターを指定します。サンプルでは待ち合わせ時間を2進整数で指定しています。1/100秒単位で指定でき、1は1/100秒、100は1秒となります。STIMERマクロ発行後、OSサービスルーチン内で指定した時間が経過するまで待ち状態に入ります。指定した時間が経過するとプログラムに戻ってきます。

サンプルの処理内容は、指定した区分データセットのメンバーがISPFエディターで編集中かをENQマクロでテストします。編集中であればENQが失敗するので、その事をWTOマクロでコンソールにメッセージで通知して、10秒間待ち状態に入ります。10秒経過後、再びENQをトライします。このサイクルで6回繰り返し、都合1分間リトライします。ENQに成功した場合と、リトライ回数をオーバーしたらプログラムは終了します。
ENQマクロによる排他制御が獲得できない時、一定回数リトライすることはよく行われますが、人間の操作が絡む資源の場合、単にループするよりはSTIMERマクロを組み合わせて一定時間待ってからリトライするのが一般的です。


指定した時刻になったら通知してもらう

目覚まし時計プログラムです。一定時間の経過ではなく、指定した時刻になったら起き上がるサンプルです。今度はWAITではなくREALを指定しています。REALは実時間の経過を通知する機能です。TODパラメーターは間隔時間ではなく時刻を指定するパラメーターです。MVSではTODの代わりにLTパラメーターでもかまいません。
運用の自動化ソフトなどを使えば必要ありませんが、18:00になったらオンラインシステムを終了させる、21:00になったらバックアップジョブを実行させる、など決まった時刻になったら行う処理を自動化させるためには目覚まし時計が必要です。


10秒ループしたら自分で自分をキャンセルする

実時間ではなくCPU時間によるインターバルタイムの計測です。REALの代わりにTASKと指定します。間隔時間の指定方法はREALもTASKも同じです。このサンプルではCPUタイマー単位(約26.04166マイクロ秒)で指定しています。約10秒です。わかりにくいので普通にBINTVLで指定してかまいません。
サンプルの処理は一定のCPU時間を使い切ったらプログラムをABENDさせる例です。タイマーをセットしてから、わざと無限ループに入ります。指定した時間のCPUを使い切ると、TIMREXITに飛び込んできます。


サンプルではタイマー出口内で大した処理をしてませんので簡単に書いてますが、出口ルーチン内からメインライン側のデータ領域などを直接参照・更新したい場合は、上記のようなハウスキーピングをすればいいでしょう。メインライン側のベースアドレスを同じベースレジスターに再設定します。STIMER出口ルーチンの規約では、汎用レジスター0?12の内容はSTIMERマクロ発行時の内容とは規定されていません。仮にGR12にプログラムのベースアドレスが入っていたとしても、それはたまたまです。マニュアル通りGR0?12は壊れていると言う前提で再設定しましょう。STIMERに限らずすべてのマクロの出口ルーチンについて言えます。マニュアルに記載されている出口ルーチンのレジスター規約を必ず確認してそれに従います。

STIMERで設定したタイマーは設定時間が経過して出口で通知されると無効になります。再びタイマーによる時間測定が必要なら改めてSTIMERマクロを発行する必要があります。STIMERマクロは必ずしもメインルーチン内で出す必要はありません。出口ルーチン内でSTIMERマクロを発行してタイマーを再設定してもかまいません。


タイマー測定のキャンセル

TTIMERマクロを使うと一度設定したタイマーの残り時間を調べたり、タイマー計測をキャンセルすることができます。
サンプルでは10秒の実時間タイマーを設定してから、5命令×一千万回で計五千万回の命令を実行します。その後TTIMERで設定したタイマーを取り消します。GR0にタイマーの残り時間がCPUタイマー形式(約26.04166マイクロ秒単位)で返されます。サンプルではタイマー出口は意味を持たないのでBR 14命令で何もせずに復帰しています。
タイマーを設定している常駐型のプログラムなどでは、オペレーターコマンドなどによって処理を終了する時、TTIMERで不要になったタイマー設定を取り消します。TPモニターなどユーザーアプリケーションを自分の制御で実行するようなソフトでは、ユーザープログラム開始前にTASK指定のSTIMERでCPUタイマーを設定し、ユーザープログラムが終了した時点でそれを取り消したりします。

STIMERサービスは1つのタスクで同時に複数使用することはできません。STIMERサービスによるインターバルタイマーの設定は1つしか出来ないのです。同じタスクで複数のインターバルタイムを計測するためにはSTIMERM(MSPではSTIMERE、VOS3では公開されていません)マクロを利用します。MSPのSTIMEREサービスでは経過時間の通知に出口ルーチンではなく、ECBポストによる方法も選択できます。

Filed in .基礎編

データセットをファイル転送可能な形式に変換する(TRANSMITとIEHMOVE)

By kamii - Last updated: 火曜日, 11月 18, 2008

固定長レコードのデータセットであればそのままファイル転送することができますが、可変長/不定長レコードの場合は相手側転送ソフトがメインフレームのレコード形式に対応していないと正しく転送できません。
TSOのTRANSMIT/RECEIVEコマンドを使うと、順次または区分データセットであればレコード形式に関係なく、データセットをRECFM=FB,BLKSIZE=3120,LRECL=80の形式に変換し、元の形式に復元することができます。TRANSMITで変換してから転送し、転送先でRECEIVEで復元すればあらゆるデータセットを転送することができます。VSAMデータセットも一旦REPROで順次データセットにアンロードすればTRANSMITに掛けることができます。

FTPなどでの転送の場合、TRANSMITコマンドはデータの変換に過ぎませんが、NJEで接続されたz/OS同士、VSEやVMなどのIBMシステムであれば同時に転送が行われます。
※転送処理自体はNJEによって行われる。NJEで接続されていなければ、FTPや3270エミュレーターのファイル転送などを利用することになる。


TSO/TRANSMITコマンド


IEHMOVEユーティリティー

Filed in ありがたいサンプルJCL

04.1コンソールまたはSYSLOGにメッセージを出す(WTOとWTL)

By kamii - Last updated: 火曜日, 11月 18, 2008

プログラムで起きていることを状況に応じてメッセージで伝えることは重要です。特にエラーが起きてオペレーターの操作や判断を必要する場合、適切なメッセージはシステムの運用面で大きな利益をもたらします。どのような時にどのようなメッセージを出すかは、プログラムのロジックと並びデザイナーの腕の見せ所でもあります。MVSにはコンソールへメッセージを出したり、オペレーターからの操作や応答を受け取るためのAPIも用意されています。これらはコンソールを操作するオペレーターとプログラムの間の通信機能でもあります。


コンソールへメッセージを出力する

WTOマクロはコンソールへメッセージを出力します。世の中のメインフレーム・アセンブラープログラマーに「初めて使ったOSのAPIマクロは何ですか?」とアンケートを取れば恐らく1位、少なくとも3位内には入るであろう、と言うぐらいポピュラーなマクロです。
使い方もいたって簡単で、マクロ名に続いて出したいメッセージテキストを”で囲めばOKです。テキストが長くて1行に書ききれないときは、71桁目まで目一杯書いて、72桁目に何か文字を置き、次の行の16桁目から続けます。16桁目が空白でもそのまま空白文字として扱われます。

残りの2例は、メッセージテキストの中の文字を置換えて出力したい場合に用いられる方法の1つです。実戦では固定のメッセージテキストだけでなく、メッセージの中にプログラムの処理によって内容が変わる値などを埋め込みたいことがよくあります。このような場合はリスト形式と実行形式のWTOマクロを組み合わせます。再入可能プログラムではモジュール内のWTOパラメーターを直接変更できないので、モジュール外の作業域に一旦コピーして、そちら側を修正して使用します。
わざと同じENQを2回出し、それぞれのENQサービスの復帰コードをメッセージ中のRC=??の??部分に埋め込んでコンソールに出力するものです。単にENQ ERRORと出すよりはるかに実用的です。復帰コードの値がわからなければ対処のしようがありません。サンプルでは簡単にするために10進数に変換していますが、16進数文字への変換なら、マニュアルのコード表示と一致するのでさらにわかりやすくなります。

メッセージテキストはWTOパラメーターの+4バイト目から始まります。アセンブルしてマクロの展開形を見ればすぐにわかります。本来ならOSマクロの中を、直接変位を指定して場所をポイントするのは決していいことではないのですが、WTOのような基本的なマクロはその内容が変わることは現実的にありませんし、サンプルの方法は古典的ではありますが、昔から多くのプログラムで行われている、言わば標準的・伝統的な方法です。


可変長のメッセージテキストを出力する

可変長のメッセージテキストを出力する例です(※MVSでのみ利用できる方法)。
TEXTパラメーターでコンソールへ出力するメッセージテキストの格納アドレスを指定します。メッセージ領域の先頭2バイトはメッセージテキストの長さです。メッセージ長フィールドの長さは含みません。長さに続いてメッセージテキストを格納します。

MSPおよびVOS3で可変長メッセージテキストを扱う場合、リスト形式のWTOマクロを使ってWTOパラメーターがどのように作成されるかをアセンブルリストで確かめます。それに合わせてプログラムでメッセージテキストをWTOパラメーターを作り、実行形式のWTOマクロでメッセージを出力します。

メッセージテキストを’’で囲む従来からあるWTOパラメーターは上図のフォーマットになっています。先頭2バイトにメッセージテキスト長に4を加えた値を設定します。DESCまたはROUTCDEパラメーターを指定した場合、メッセージテキストの後ろに設定されますが、その長さは先頭のレングスフィールドには含まれません。パラメーターはワード境界に合わせます。


メッセージの種類と宛先を指定する

メッセージの種類や宛先を指定することもできます。DESCパラメーターはメッセージの種類(性質)を表します。通常は省略してかまいませんが、指定するなら、一般のプログラムであれば6または7でいいでしょう。OSの出口ルーチンなどで重大なエラーを検出して、オペレーターにメッセージで伝えるような時、スクロールされてメッセージが流れないようにするにはDESCコードとして11を指定します。DESCコード11を指定した場合、WTOマクロ完了時にGR1に返されるメッセージ識別番号を保存します。この識別番号を使えばDOMマクロによってメッセージを削除することが可能です。DESCコード11のメッセージはプログラムがDOMマクロを使うか、オペレーターがコンソール操作(MVSの場合、K C,A,idコマンド)によってしか消されることはありません。

ROUTCDEパラメーターはメッセージの宛先を表します。これも通常は省略してかまいませんが、一般プログラムが指定するなら2がいいでしょう。MVSではSYSLOGの3?9桁目がメッセージのROUTE CODEを示します。16進表記ですが左ビットからROUTE1,2,3,4,5,6,…,28となっています。ここを見て他のソフトウェア製品などがどのようなROUTCDEを使っているかを参考にするのも1つの方法です。FFFFFFFFとなっていたらROUTCDEは省略されています。
DESCとROUTCDEのコードそのものの詳細な解説は「MVS 宛先コードおよび記述子コード」マニュアルに記載されています。コードの用途はMSP/VOS3でも基本的に同じです。


SYSLOGへメッセージを出力する

コンソールへの表示は不要だがシスログには残したい、と言う場合もあります。そのような時はWTLマクロをWTOマクロの代わりに使うことができます。なお現在IBMではWTLマクロに代わり、MCSFLAG=HRDCPYを指定したWTOマクロによる方法を推奨しています。
MCSFLAG=HRDCPY指定のWTOを使った場合、SDSFのLOG機能やECSなどの仮想コンソールプログラムを使用すると、上記の方法ではメッセージが表示されることがあります。これはその仮想コンソール機能が純粋にコンソールとしてではなく、SYSLOGをベースにメッセージを表示しているからです。本当にコンソールには出ていないかを確認するには実コンソールを見て下さい。


補足

Filed in .基礎編