QUSLOBJ
も使用頻度の高い API であり、オブジェクトの一覧をユーザー・スペースに
出力して、それを検索して解析したり別の一覧表に出力するような目的のために使用される。
API の結果の出力方法は QUSROBJD
で紹介したレシーバー変数に出力する場合と
結果の項目が複数個ある場合は、この QUSLOBJ
のようにユーザー・スペースに
出力する方法に分かれる。
必須パラメータ・グループ:
1. | ユーザー・スペース修飾名 | 入力 | Char(20) |
2. | 形式名 | 入力 | Char(8) |
3. | オブジェクト修飾名 | 入力 | Binary(4) |
4. | オブジェクト・タイプ | 入力 | Char(10) の配列(*) |
任意選択パラメータ:
5. | エラー・コード | 入出力 | Char(*) |
任意選択パラメータ:
6. | 権限制御 | 入力 | Char(*) |
7. | 選択制御 | 入力 | Char(*) |
結果の内容を受け取るためのユーザー・スペース ( *USRSPC
) は QUSLOBJ
を実行する前には
予め作成して準備しておかなければならない。
後で示すサンプル・ソースには、この作業も含めてある。
形式名 は、
OBJL0100 形式 | ・・・・・・ | オブジェクト名(最高速) |
OBJL0200 形式 | ・・・・・・ | テキスト記述および拡張属性 |
OBJL0300 形式 | ・・・・・・ | 基本オブジェクト情報 |
OBJL0400 形式 | ・・・・・・ | 作成情報 |
OBJL0500 形式 | ・・・・・・ | 保管および復元情報 |
OBJL0600 形式 | ・・・・・・ | 使用状況情報 |
OBJL0700 形式 | ・・・・・・ | すべてのオブジェクト情報(最低速) |
形式によって受け取る情報の詳細は後述する。
オブジェクト修飾名 は ( オブジェクト名 ) + ( ライブラリー名 ) であるが次の特殊値を
指定することができる。
*ALL | ・・・・・・ | すべてのライブラリー |
*ALLUSR | ・・・・・・ | すべてのユーザー・ライブラリー ( ユーザー・ライブラリーとは 名前が Q で始まっていないライブラリーであり、 #CGULIB, #RPGLIB, #COBLIB, #SDALIB, #DFULIB, #SEULIB, #DSULIB を除く。) |
*CURLIB | ・・・・・・ | ジョブの現行ライブラリー |
*LIBL | ・・・・・・ | ライブラリー・リスト |
*USRLIBL | ・・・・・・ | ジョブのライブラリー・リストのユーザー部分だけ |
オブジェクト・タイプ は、特定のオブジェクト・タイプ または *ALL
を指定する。
権限制御 と 選択制御 はあまり指定することがないので必要があれば IBM API 解説書を参照のこと。
最初にユーザー・スペースを作成するために ユーザー・スペースの作成 API である QUSCRTUS
を紹介する。
必須パラメータ・グループ:
1. | ユーザー・スペース修飾名 | 入力 | Char(20) |
2. | 拡張属性 | 入力 | Char(10) |
3. | 初期サイズ | 入力 | Binary(4) |
4. | 初期値 | 入力 | Char(1) |
5. | 共通権限 | 入力 | Char(10) |
6. | テキスト記述 | 入力 | Char(20) |
任意選択パラメータ:
7. | 置換 | 入力 | Char(10) |
8. | エラー・コード | 入出力 | Char(*) |
ユーザー・スペース修飾名 は例えば、「 USRSPC QTEMP
」 などのように任意の名前をつけて
QTEMP に作成することが多い。
拡張属性 は、ユーザー・スペースの拡張属性であり使用するユーザーが識別できるものでよい。
例えば、PF
, LF
, DSPF
または SAVF
などでよい。
初期サイズ は最初にユーザー・スペースを作成するサイズ ( バイト数 ) であるが 1000 バイトあたりに
定義しておけば不測の場合は自動的に OS によって拡張される。
初期値 は最初にユーザー・スペースに埋め込む 1 バイトの Char である。NULL かまたは ブランク でよい。
共通権限 は AUT
であるので通常は *ALL
として作成しておけばよい。
テキスト記述 は文字通りこのユーザー・スペースのテキストである。
置換 は任意選択とはなっているが必須であろう。
*YES
として指定しておけば QUSCRTUS
は、作成するユーザー・スペースが存在していても
エラーを発生することなく上書きで作成してくれる便利な機能である。
従って置換には必ず *YES
を指定して作成することが肝要である。
QUSCRTUS
の実行例は次のとおりである。
/*(1) ユーザー・スペースの作成 */ typedef struct { char name[10]; char lib[10]; } USNAME; USNAME usname; : : errcode.BYTESPRO = 160; errcode.BYTESAVL = 0; memcpy(usname.name, "LIBSPC ", 10); memcpy(usname.lib, "QTEMP ", 10); QUSCRTUS(&usname, "PF ", 1000, " ", "*ALL ", "QUSLOBJ ユーザー・スペース ", "*YES ", &errcode); if(errcode.BYTESAVL != 0){/* APIERR */ printf("ApiError MSGID = %s\n", errcode.MSGID); getchar(); return; }/* APIERR */
次に API : QUSLOBJ
によって *ALLUSR
のライブラリー一覧を ユーザー・スペースに出力する。
QUSLOBJ
の実行自体は次のように簡単である。
/*(2) QUSLOBJ の実行 */ QUSLOBJ(&usname, "OBJL0300", "*ALLUSR *ALL ", "*LIB ", &errcode);
結果の ユーザー・スペースの読み取りは API : QUSRTVUS
によって検索する。
API : QUSRTVUS
もユーザー・スペースを検索するために良く使う API であり
使用方法はどのような場合でも全く同じである。
必須パラメータ・グループ:
1. | ユーザー・スペース修飾名 | 入力 | Char(20) |
2. | 開始位置 | 入力 | Birary(4) |
3. | データの長さ | 入力 | Binary(4) |
4. | レシーバー変数 | 出力 | Char(*) |
任意選択パラメータ:
5. | エラー・コード | 入出力 | Char(*) |
ユーザー・スペースの構造はすべて同じであり、最初のヘッダー部分に レコード数 と 1 レコードの長さ が
登録されている。従って 最初にヘッダー部分を読んで最初のデータの開始位置 ( offset
) と
レコードの長さ( size
) を取得してから 項目数( inspace.number_of_entries
) の分だけ
LOOP してデータを読み取ればよい。
/*(3) QUSRTVUS によるユーザー・スペースの検索 */ typedef _Packed struct header_struct { char user_data[64]; int generic_header_size; char header_version[4]; char format_name[8]; char program_name[10]; char time_generated[13]; char information_status; int usrspc_used; int parm_section_offset; int parm_section_size; int header_section_offset; int header_section_size; int list_section_offset; /*( 最初の開始位置 )*/ int list_section_size; int number_of_entries; /*( 項目数 )*/ int size_of_entry; /*( 1 項目の長さ )*/ } HEADER_STRUCT; HEADER_STRUCT inspace; : : QUSRTVUS(&usname, 0x01, sizeof(inspace), &inspace, &errcode); offset = inspace.list_section_offset +1; size = inspace.size_of_entry; for(i = 0; i<inspace.number_of_entries; i++){/*for-loop*/ QUSRTVUS(&usname, offset, size, &objl0300, &errcode); /*--------------( 処理の開始 )-----------------*/ memcpy(name, objl0300.Object_Name_Used, 10); name[10] = 0x00; printf("[%d] Object_Name = [%s]\n", i+1, name); /*--------------( 処理の終了 )-----------------*/ offset += inspace.size_of_entry; }/*for-loop*/
ユーザー・スペースの読み取りは ( 処理の開始 ) 〜 ( 処理の終了 ) が変わるだけで
ヘッダー構造 ( HEADER_STRUCT
) もつねに同じである。
以上の処理をひとつのソースにまとめると次のようになる。
0001.00 #include <stdio.h> 0002.00 #include <stdlib.h> 0003.00 #include <string.h> 0004.00 #include <QUSCRTUS.h> 0005.00 #include <QUSLOBJ.h> 0006.00 #include <QUSRTVUS.h> 0007.00 #include <signal.h> 0008.00 #include <errno.h> 0009.00 0010.00 #define TRUE 0 0011.00 #define FALSE -1 0012.00 volatile _INTRPT_Hndlr_Parms_T ca; 0013.00 typedef struct { 0014.00 int BYTESPRO; 0015.00 int BYTESAVL; 0016.00 char MSGID[7]; 0017.00 char RESRVD; 0018.00 char EXCPDATA[100]; 0019.00 } ERRSTRUCTURE; /* Define the error return structure */ 0020.00 ERRSTRUCTURE errcode;/* Error Code Structure for RCVMSG */ 0021.00 0022.00 void main(void){ 0023.00 typedef struct { 023.00 typedef struct { 024.00 char name[10]; 025.00 char lib[10]; 026.00 } USNAME; 027.00 USNAME usname; 028.00 typedef _Packed struct header_struct { 029.00 char user_data[64]; 030.00 int generic_header_size; 031.00 char header_version[4]; 032.00 char format_name[8]; 033.00 char program_name[10]; 034.00 char time_generated[13]; 035.00 char information_status; 036.00 int usrspc_used; 037.00 int parm_section_offset; 038.00 int parm_section_size; 039.00 int header_section_offset; 040.00 int header_section_size; 041.00 int list_section_offset; /*( 最初の開始位置 )*/ 042.00 int list_section_size; 043.00 int number_of_entries; /*( 項目数 )*/ 044.00 int size_of_entry; /*( 1 項目の長さ )*/ 045.00 } HEADER_STRUCT; 046.00 HEADER_STRUCT inspace; 0047.00 int offset, size, i, len; 0048.00 char name[11]; 0049.00 Qus_OBJL0300_t objl0300; 0050.00 0051.00 printf("** TESTUSLO : オブジェクト一覧表 **\n"); 0052.00 getchar(); 0053.00 /*(1) ユーザー・スペースの作成 */ 0054.00 errcode.BYTESPRO = 160; 0055.00 errcode.BYTESAVL = 0; 0056.00 memcpy(usname.name, "LIBSPC ", 10); 0057.00 memcpy(usname.lib, "QTEMP ", 10); 0058.00 QUSCRTUS(&usname, "PF ", 1000, " ", "*ALL ", 0059.00 "QUSLOBJ ユーザー・スペース ", "*YES ", &errcode); 0060.00 if(errcode.BYTESAVL != 0){/* APIERR */ 0061.00 printf("ApiError MSGID = %s\n", errcode.MSGID); 0062.00 getchar(); 0063.00 return; 0064.00 }/* APIERR */ 0065.00 0066.00 /*(2) QUSLOBJ の実行 */ 0067.00 QUSLOBJ(&usname, "OBJL0300", "*ALLUSR *ALL ", "*LIB ", &errcode); 0068.00 0069.00 /*(3) QUSRTVUS によるユーザー・スペースの検索 */ 0070.00 QUSRTVUS(&usname, 0x01, sizeof(inspace), &inspace, &errcode); 0071.00 offset = inspace.list_section_offset +1; 0072.00 size = inspace.size_of_entry; 0073.00 0074.00 printf("count = %d\n", inspace.number_of_entries); 0075.00 getchar(); 0076.00 for(i = 0; i<inspace.number_of_entries; i++){/*for-loop*/ 0077.00 QUSRTVUS(&usname, offset, size, &objl0300, &errcode); 0078.00 /*--------------( 処理の開始 )-----------------*/ 0079.00 memcpy(name, objl0300.Object_Name_Used, 10); 0080.00 name[10] = 0x00; 0081.00 printf("[%d] Object_Name = [%s]\n", i+1, name); 0082.00 /*--------------( 処理の終了 )-----------------*/ 0083.00 offset += inspace.size_of_entry; 0084.00 }/*for-loop*/ 0085.00 }
QUSLOBJ
以外の別の ユーザー・スペースに出力する API の場合も
0067.00 QUSLOBJ(&usname, "OBJL0300", "*ALLUSR *ALL ", "*LIB ", &errcode);
と、
0078.00 /*--------------( 処理の開始 )-----------------*/ 0079.00 memcpy(name, objl0300.Object_Name_Used, 10); 0080.00 name[10] = 0x00; 0081.00 printf("[%d] Object_Name = [%s]\n", i+1, name); 0082.00 /*--------------( 処理の終了 )-----------------*/
が変わるだけでありその他は同じソースとなるはずである。
従ってこの例はコピーして繰り返し参照して使用することになるだろう。