Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ rpcgen(1) — NEWS-os 3.3

Media Vault

Software Library

Restoration Projects

Artifacts Sought

RPCGEN(1)  —  UNIX Programmer’s Manual

名称

rpcgen − RPC プロトコルコンパイラ

形式

rpcgen − an RPC protocol compiler

SYNOPSIS

rpcgen −h [−o outfile] [inputfile]
rpcgen −c [−o outfile] [infile]
rpcgen infile
rpcgen [−s transport]∗ [−o outfile] [infile]

解説

rpcgen は、 RPC プロトコルをインプリメントするための、 C のコードを生成するツールです。 rpcgen に入力する言語は、 RPCL (Remote Procedure Call Language) として 知られる C に極めて似た言語です。 rpcgen は 4つのモードで働きます。 第 1のモードは、 ヘッダファイルとして使うために、 RPCL による定義を C による定義へ変換するときに使用します。 第2 のモードは、 RPCL によって記述されるプロトコルをシリアル化するために 必要となる XDR ルーチンをコンパイルします。 第3 のモードは、 指定の infile (入力ファイル) から、 ヘッダファイルを拡張子 .h のファイルへ、 infile の中の XDR ルーチンを拡張子 .c のファイルへと、 両方コンパイルします。 第 4のモードは、 PRC サーバスケルトンのコンパイルに使用します。 RPC サーバをインプリメントするためにユーザがするべきことは、 RPC には無関係なローカル手続きを書くことだけです。 入力には C の形式のコメントとプリプロセッサ制御文を 含めることができます。 コメントは無視され、 制御文は解釈されずに出力のヘッダファイルに埋め込まれます。 データタイプを未定義のままにしておくことにより、 いくつかの XDR ルーチンをカスタム化することができます。 rpcgen は未定義のデータタイプに対し、 頭に‘xdr_’の付くルーチンがあるものと仮定します。

オプション

−cXDR ルーチンをコンパイルする。

−hC データ定義 (ヘッダファイル) をコンパイルする。

−o outfile
出力ファイル名の指定。 指定が省略された場合には標準出力が使用される (−c、−h、−sモードのみ)。

−s transport
与えられたトランスポートを使用して、 サーバをコンパイルする。 サポートされるトランスポートは udp と tcp です。 このオプションは、 サーバが複数のトランスポートをサービスできるようにコンパイルするため、 1回以上呼び出されます。

使用法

RPCL文法の要約

RPCL文法は rpcgen の入力に適用されますが、 この要約は言語を正確に記述することではなく、 理解を手助けすることを意図しています。

初期データタイプ

[ unsigned ] char
[ unsigned ] short
[ unsigned ] int
[ unsigned ] long
unsigned
float
double
void
bool

追加されたブール型のデータタイプ bool を除いて、 RPCL は C と同じです。 rpcgen は、 bool 宣言を int 宣言に変換してヘッダファイルへ 出力します (文字どおり、 bool は int として #define されている bool_t に変換されます)。 同様に void 宣言は union と program の定義中にのみ現われます。 unsigned を前に付けてタイプする事を嫌う際には、 u_char や u_short、u_int、u_long の ように省略することができます。

宣言

RPCL は、 3種類の宣言のみを許しています。 declaration(宣言):

simple-declaration
pointer-declaration
vector-declaration

simple-declaration(単純宣言):

type-name object-ident

pointer-declaration(ポインタ宣言):

type-name ∗object-ident

vector-declaration(ベクタ宣言):

type-name object-ident[size]

(size 整数または記号定数) RPCL の宣言は、 C と比較して制限される事項と拡張された事項の両方を含んでいます。 制限事項としては、 複数次元の配列および、 1つの行でポインタ-to-ポインタ (これは typedef を使用するならば宣言できます) が宣言できない事あります。 拡張事項は 2つあります。

opaque データは、 ベクトルとして以下のように宣言されます。

opaque object-ident [ size ]

プロトコルでは、 この結果は size バイトのオブジェクトになります。 XDR キャラクタは 32 ビットなので、 これは size バイトのキャラクタの宣言とは同じではありません。 opaque 宣言は、 出力ヘッダファイルの中に size バイトのキャラクタ配列宣言としてコンパイルされます。 文字列は特別で、 ベクトル宣言として宣言されます。

string object-ident [ max-size ]

もし、 max-size(最大サイズ)が指定されなければ、 文字列は本質的に限界のない最大の長さをとります。 文字列宣言は以下のようにコンパイルされます。

char ∗object-ident

タイプ定義

XDRルーチンを生成する唯一の方法は、 タイプの定義です。 ユーザが定義するすべての zetype タイプは、 XDRルーチンの xdr_zetype という名前に対応します。 タイプの定義には 6通りあります。 type-definition:

typedef
enumeration-def
structure-def
variable-length-array-def
discriminated-union-def
program-def

最初の 3つは、 C での同名のものと酷似しています。 C は可変長配列を定義するメカニズムを持たず、 XDR の共用体(union) は C のそれとは大きく異なっています。 プログラム定義は、 ほんとうのタイプの定義ではありませんが、 それにもかかわらず便利なものです。 ユーザは XDR 定義をネストすることはできません。 たとえば以下の例では、 rpcgen が止まってしまいます。

struct dontdoit {
struct ididit {
int oops;
} sorry;
enum ididitagain { OOPS, WHOOPS } iapologize;
};

Typedef (タイプの定義)

XDR の typedef は以下のようなものです。 typedef:

typedef declaration ;

declaration 中の object-ident の 部分は新しいタイプの名前で、 type-name の部分はそれが派生したタイプの名前です。

enumeration タイプ(列挙型)

書式は以下のとおりです。 enumeration-def:

enum enum-ident {

enum-list

};

enum-list:

enum-symbol-ident [ = assignment ]
enum-symbol-ident [ = assignment ] , enum-list

(assignment は整数または記号定数) assignment が明示的に指定されていなければ、 暗黙の指定によって、 以前の enumration に 1 を加えた値となります。 また、 明示的に割り当てられていなければ、 最初の enumration の値は 0 となります。

structures(構造体)

structure-def:

struct struct-ident {

declaration-list

};

declaration-list:

declaration ;
declaration ; declaration-list

variable-length arrays (可変長配列)

variable-length-array-def:

array array-ident {

unsigned length-identifer ;
vector-declaration ;

};

可変長配列の定義は構造体定義とよく似ています。 以下に例を示します。

array mp_int {
unsigned len;
short val[MAX_MP_LENGTH];
};

これは以下のようにコンパイルされます。

struct mp_int {
unsigned len;
short ∗val;
};
typedef struct mp_int mp_int;

discriminated unions (明示な共用体)

Disriminated Unions

discriminated-union-def:

union union-ident switch ( discriminant-declaration ) {

case-list
[ default : declaration ; ]

};

case-list:

case case-ident : declaration ;
case case-ident : declaration ; case-list

discriminant-declaration:

declaration

共用体の定義は、 C における共用体とスイッチの組み合せに似ています。 以下に例を示します。

union net_object switch (net_kind kind) {
case MACHINE:
struct sockaddr_in sin;
case USER:
int uid;
default:
string whatisit;
};

これは以下のようにコンパイルされます。

struct net_object {
net_kind kind;
union {
struct sockaddr_in sin;
int uid;
char ∗whatisit;
} net_object;
};
typedef struct net_object net_object;

出力される構造体の共用体要素の名前は、 タイプ自身の名前と同じになる点に注意してください。

program definitions (プログラム定義)

program-def:

program program-ident {

version-list

} = program-number ;

version-list:

version
version version-list

version:

version version-ident {

procedure-list

} = version-number ;

procedure-list:

procedure-declaration
procedure-declaration procedure-list

procedure-declaration:

type-name procedure-ident ( type-name ) = procedure-number ;

プログラム定義は、 おそらく今までにユーザが見たもののどれとも似ていないので、 例によって説明します。 ユーザが日付を取得または設定できるサーバを作成したいと想定します。 そのための定義は以下のようになります。

program DATE_PROG {
version DATE_VERS {
date DATE_GET(timezone) = 1;
void DATE_SET(date) = 2;/∗ Greenwich mean time ∗/
} = 1;
} = 100;

ヘッダフィルの中へは、 以下のようにコンパイルされます。

#define DATE_PROG 100
#define DATE_VERS 1
#define DATE_GET 1
#define DATE_SET 2

これらの定義 (define) は、 クライアントプログラムがリモート手続きを参照するために使用されます。 ユーザが rpcgen を使用してサーバをコンパイルするならば、 知っておくべき重要な事項がいくつかあります。 ユーザのローカルな手続きとのサーバインタフェースは、 プログラム定義中のそれと同じ名前の C 関数に当てられますが、 すべて小文字でかつ後ろにとバージョン番号が付きます。 以下に、 DATE_GET をインプリメントするローカルな手続きを示します。

date ∗/∗ 常に引数へのポインタをとる ∗/
date_get_1(tz)
timezone ∗tz;/∗ 常に引数へのポインタをとる ∗/
{
static date d;/∗ スタティックであること ∗/
/∗
∗ 日付を算出し、d に格納する
∗/
return(&d);
}

ルーチン名は #define での名前と同じですが、 すべて小文字で後ろにバージョン番号が付きます。 ユーザのローカルな手続きから結果を受け取ると、 XDR は引数を再帰的に自由にします。 したがってユーザは、 コールの間でも必要なときに引数のデータをコピーすることができます。 しかし XDR は、 ユーザの結果を解放も割り当てもしません。 ユーザは、 ユーザ自身で結果を格納することに注意を払わなければなりません。

XDRヘッダのコンパイルに関する Make とのインタフェース規則

XDR ルーチンとヘッダファイルのコンパイルに関しては、 make(1) に従ったサフィックスの変換規則が適用できます。 規則は、 RPCL プロトコルファイルが拡張子 .x を持つことです。 そのための make のルールは次のようになります。

.SUFFIXES: .x
.x.c:
rpcgen −c $< −o $@
 .x.h:
rpcgen −h $< −o $@

バグ

プログラム定義を使用するときに、 名前の衝突が起きることがあります。 これは外見上のスコープ(範囲)と実際とが一致しないときに発生します。 その多くは、 program、 version、 procedure、 type に一意な名前を使用することで避けることができます。

NEWS-OSRelease 3.3

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026