GETCAP(3)

名称
cgetent, cgetset, cgetmatch, cgetcap, cgetnum, cgetstr, cgetustr, cgetfirst, cgetnext, cgetclose - ケーパビリティデータベースにアクセスするルーチン

書式
#include <stdlib.h> int cgetent(char **buf, char **db_array, char *name) int cgetset(char *ent) int cgetmatch(char *buf, char *name) char * cgetcap(char *buf, char *cap, int type) int cgetnum(char *buf, char *cap, long *num) int cgetstr(char *buf, char *cap, char **str) int cgetustr(char *buf, char *cap, char **str) int cgetfirst(char **buf, char **db_array) int cgetnext(char **buf, char **db_array) int cgetclose(void)

解説
cgetent() は、 NULL で終わるファイル配列 db_array で指定したデータベースから、ケーパビリティ name を抜き出し、 buf 内に malloc したそのコピーのポインタを返します。 cgetent() 関数は ASCII ファイルにアクセスする前に、まず、 .db で終わるファイルを探します( cap_mkdb(1) 参照)。 Buf は、以後の cgetmatch(), cgetcap(), cgetnum(), cgetstr() および cgetustr() の呼び出しすべてを通じて保持されなければなりませんが、呼び出しの完了後は free(3) できます。抜き出しに成功した場合は 0が、返すレコードに未解決な tc 拡張の含まれている場合は 1が、要求されたレコードの見付からなかった場合は -1 が返ります。システムエラー(ファイルがオープンできなかった/読み取れ なかった、など)が発生した場合は -2 が返るとともに、 errno が設定されます。また、潜在的な参照ループが検出された場合は -3 が返ります(後述の tc= 参照)。

cgetset() 関数は、1 つのケーパビリティレコードエントリが含まれた、キャラクタバッ ファのケーパビリティデータベースへの追加を有効にします。 概念的には、 このエントリが最初の ``ファイル'' としてデータベースに追加されるので、 cgetent() の呼び出しでは最初に検索されます。エントリは ent に渡されますが、 ent が NULL の場合、現在のエントリはデータベースから除去されます。 cgetset() の呼び出しは、データベースの走査に先行しなければなりません。 cgetent() 呼び出しの前に、呼び出す必要があります。シーケンシャルなアクセスを実行 する場合は、最初のシーケンシャルアクセス呼び出し( cgetfirst() または cgetnext() )の前に呼び出すか、 cgetclose() 呼び出しの直後に呼び出す必要があります(後掲参照)。呼び出しに成功した場合は 0 が、失敗した場合は -1 が返ります。

cgetmatch() 関数は、 name がケーパビリティレコード buf の名前の 1つならば 0を、そうでなければ -1 を返します。

cgetcap() 関数は、タイプ type によってケーパビリティ cap を、ケーパビリティレコード buf で検索します。タイプは、1 つのキャラクタを使用して指定します。コロン (`:')を使用した場合は、タイプのないケーパビリティが検索されます(後掲の タイプの説明を参照してください)。検索が成功した場合は buf にある cap 値のポインタが返ります。要求されたケーパビリティが見付からない場合は、 NULL が返ります。ケーパビリティ値の終わりは、 ‘’: または ASCII NUL で示されます(後掲のケーパビリティデータベースの構文を、参照してくださ い)。

cgetnum() 関数は、 buf で示されたケーパビリティレコードから、数値ケーパビリティ cap の値を取り出します。この数値は num に示される long で返されます。成功した場合は 0が返ります。要求された数値ケーパビリティが 見付からない場合は -1 が返ります。

cgetstr() 関数は、 buf で示されたケーパビリティレコードから、ストリングケーパビリティ cap の値を取り出します。そのストリングのデコードされ、 NUL で終わる malloc されたコピーのポインタが、 str に示される char * で返されます。成功した場合は、デコードされたストリングの終端の NUL を含まない数が返ります。要求されたストリングケーパビリティが見付からな い場合は -1 が返り、システムエラー(ストレージ割り振りエラー)が発生し た場合は -2 が返ります。

cgetustr() 関数は cgetstr() と同様な機能ですが、特殊キャラクタを拡張しないで、むしろケーパビリティ ストリングの、文字どおり各キャラクタを返すところが違います。

cgetfirst() および cgetnext() 関数は、ファイル名が NULL ポインタで終わる配列 db_array への、シーケンシャルなアクセスができる関数グループを構成します。 cgetfirst() 関数は、指定データベースにある最初のレコードを返し、最初のレコードへの アクセスをリセットします。 cgetnext() 関数は、前の cgetfirst() または cgetnext() 呼び出しによって返ったレコードの、指定データベースにある次のレコードを 返します。前の呼び出しがない場合は、指定データベースにある最初のレコー ドを返します。各レコードは buf で示される されたコピーで返り、 tc 拡張がなされます。(後掲の tc= の説明を参照してください。) データベース検索を完了して、返すレコードがない場合は 0が返ります。検索 に成功して返すレコードがあり、さらに次のレコードの残っている可能性があ る(データベースの終わりにまだ達していない)場合は 1が返ります。返すレコー ドに、未解決な tc 拡張の含まれている場合は 2が返ります。システムエラーの発生した場合は -1 が返ります。潜在的な参照ループが検出された場合は -2 が返ります。 (後掲の tc= の説明を参照してください。)データベースが完了した(0が返った)場合、デー タベースはクローズされます。

cgetclose() 関数は、シーケンシャルなアクセスをクローズし、すべてのメモリおよび使用 されていたファイル記述子を解放します。 cgetset() の呼び出しによってプッシュされたバッファは、消去されないことに注意して ください。

ケーパビリティデータベースの構文
ケーパビリティデータベースは一般に ASCII です。標準のテキストエディタで編集できます。空白行および `#' で始まる 行はコメントなので無視されます。`\' で終わる行は、次の行が現在の行 の続きであることを示します。この `\' および後に続く改行は無視されま す。長い行はふつういくつかの物理行に分割され、最終行を除いて各行末に `\' が付けられます。

ケーパビリティデータベースは、一連のレコード(1論理行当たり1つ)によって 構成されます。各レコードには、可変数の `:' で分けられたフィールド(ケー パビリティ)が含まれます。空白スペースキャラクタ(スペースおよびタブ)で、 すべて構成されるフィールドは無視されます。

各レコードの最初のケーパビリティは、 `|' キャラクタで分けられた名前(複 数)を指定します。取り決めによって最後の名前は常にコメントで、ルックアッ プタグとしての意図はありません。たとえば、 termcap データベースの vt100 レコードの最初は次のとおりです。

    d0|vt100|vt100-am|vt100am|dec vt100:

ここでは最初から 4つの名前が、このレコードのアクセスに使用できます。

残りの空白ではないケーパビリティはそれぞれ、オプションでタイプ指定値が 後に続く名前を、(名前、値)結合セットで記述します。次のとおりです。
名前 | タイプのない[ブール] ケーバビリティ名 [真の]
nameTvalue | 値
value をもつケーパビリティ (name, T)
name@ |
存在する非ケーパビリティ name
nameT@ |
存在しない(非在の)ケーパビリティ (name, T)

名前は、1つまたは複数のキャラクタで構成されます。名前には `:' を除く あらゆるキャラクタを含めることができますが、印刷可能キャラクタに限定し て、 `#' 、`=' 、`%' 、`@' などのグラフィックキャラクタの使用を避ける のが、通常は最良です。タイプは、ケーパビリティ名をそれぞれの関連タイプ 指定値から区別するのに使用される 1つのキャラクタです。`:' を除くすべて のキャラクタが使用できますが、ふつうは `#'、`=' 、`%' 、などのグラフィッ クキャラクタが使用されます。値は無制限な数のキャラクタで、`:' を除くす べてのキャラクタが使用できます。

ケーパビリティデータベースの意味論
ケーパビリティレコードは、(名前、値)結合のセットを記述します。名前は、 それらに結合された複数の値を持つことができます。1つの名前に対する異な る値は、それぞれの type によって識別されます。 cgetcap() 関数は、ケーパビリティ名およびその値のタイプが与えられた、名前の値のポ インタを返します。

タイプ `#' および `=' は慣用で、数値およびストリングタイプ指定の値を示 しますが、これらのタイプのそうした用途限定は強制的なものではありません。 関数 cgetnum() および cgetstr() によって、`#' および `=' の従来の構文および意味論が実行できます。タイ プのないケーパビリティは、ふつう真値および偽値をそれぞれ示す存在または 非在付きの、ブールオブジェクトを示します。この解釈は簡単に次のように表 すことができます。

    (getcap(buf, name, ':') != NULL)

特殊ケーパビリティ tc= name は、名前によって指定したレコードを tc ケーパビリティに置き換えるように指示します。 tc ケーパビリティは、同じく tc ケーパビリティが含まれたレコードを補間できます。1つのレコード内で、複数の tc ケーパビリティが使用できます。 tc の拡張範囲(すなわち引数が検索される範囲)には、 tc が宣言されたファイル以降の、そのファイル配列にあるすべてのファイルが含 まれます。

ケーパビリティレコードをデータベースで検索する場合は、その検索で最初に 適合したレコードが返ります。ケーパビリティをレコードでスキャンする場合は、 最初に適合したケーパビリティが返ります。ケーパビリティ :nameT@: は、後に続く名前のタイプ T の値の、あらゆる定義を隠します。また、ケーパビリティ :name@: は、後に続く名前のあらゆる値を不可視にします。

tc ケーパビリティと組み合わされたこれらの機能は、新しいケーパビリティを追 加したり、新しい定義によってこれまでの定義を上書きしたり、または `@' ケーパビリティによって後に続く定義を隠したりすることによって、ほかのデー タベースまたはレコードをさまざまに変化させることができます。

例

    example|an example of binding multiple values to names:\
    	:foo%bar:foo^blah:foo@:\
    	:abc%xyz:abc^frap:abc$@:\
    	:tc=more:

ケーパビリティ foo にはそれに結合された2 つの値(タイプ `%' の bar および タイプ `^' のblah)があります。結合されたほかのすべての値は隠されています。 ケーパビリティabc にも結合された2つの値がありますが、ケーパビリティレコード more での定義が禁止されているのは、タイプ `$' の値だけです。

    file1:
     	new|new_record|a modification of "old":\
    		:fript=bar:who-cares@:tc=old:blah:tc=extensions:
    file2:
    	old|old_record|an old database record:\
    		:fript=foo:who-cares:glork#200:

これらのレコードを抜き出す場合は、file2の前にfile1で cgetent() を呼び出します。それによって file1 の新ケーパビリティレコード fript=bar が、file2 の旧ケーパビリティレコードから補間された fript=foo を上書きします。また、who-cares@ が旧レコードにあるすべての who-cares 定義を不可視にします。さらに、glork#200 が旧レコードから持ち越され、 blah および、このレコードの拡張によって定義された一切が旧レコード内の それら定義に追加されます。ここでは、tc=old の前に fript=bar および who-cares@ の定義を置くことが重要です。それらの定義を tc=old の後に置 いた場合は、旧レコードの定義が優先されます。

CGETNUMおよびCGETSTRの構文と意味論
cgetnum() および cgetstr() によって定義ずみの、2つのタイプがあります。次のとおりです。
name#number|値
number を持つ数値ケーパビリティ名
name=string|値
string を持つストリングケーパビリティ名
name#@|存在しない(非在)数値ケーパビリティ名
name=@|存在しない(非在)ストリングケーパビリティ名

数値ケーパビリティ値は、3 つの基数のどれかで与えることができます。 または で始まる数は、16 進数として解釈されます(大文字および小文字の a-f を使っ て16 進数の拡張桁を示すことができます)。その他の で始まる 数字は、8 進数として解釈されます。残りの数字はすべて 10 進数として解釈 されます。

ストリングケーパビリティ値には、あらゆるキャラクタを含めることができます。 印刷可能ではない ASCII コード、改行コードやコロンなどが、エスケープシーケンスを使って簡単に表 せます。次のとおりです。
^X ('X' & 037) コントロール X \b, \B (ASCII 010) バックスペース \t, \T (ASCII 011) タブ \n, \N (ASCII 012) ラインフィード(改行) \f, \F (ASCII 014) フォームフィード \r, \R (ASCII 015) キャリッジリターン \e, \E (ASCII 027) エスケープ \c, \C (:) コロン \\ (\) バックスラッシュ \^ (^) キャレット \nnn (ASCII 8進数 nnn)

`\ の後に最大 3 桁の 8 進数を続ければ、特定キャラクタの数値コードを 直接指定することができます。ただし、エンコードは簡単でも ASCII NUL を多用すると、あらゆる問題の原因となる可能性があります。 NUL はふつうストリングの終わりを示しますから、使用に当たっては注意が必要 です。多くのアプリケーションで、 NUL を表すのに `\200' が使用されています。

診断
Cgetent(), cgetset(), cgetmatch(), cgetnum(), cgetstr(), cgetustr(), cgetfirst(), および cgetnext() などは、いずれも成功した場合は 0またはそれを上回る価を返し、失敗した場 合は 0を下回る値を返します。 cgetcap() 関数の場合は、成功するとキャラクタポインタを、失敗すると NULL を返します。

cgetent() および cgetseq() 関数の失敗では、 errno が、ほかのライブラリ関数 fopen(2), close(2), open(2), および close(2) などのエラーに設定される場合があります。

cgetent(), cgetset(), cgetstr() および cgetustr() の失敗では、次のエラーに errno が設定される場合があります。

[ENOMEM]
    割り振るメモリがありません。

関連項目

cap_mkdb(1), malloc(3)

バグ
コロン (`:') が、名前、タイプ、値に使用できません。

cgetent() に、 tc=name ループのチェックがありません。

cgetset() の呼び出しによってバッファをデータベースに追加することは、このデータベー スに限りませんが、ほかの使用データベースに追加する場合は、後ではなく前 に付加する方が無難です。