HP OpenVMS Systems Documentation |
| 前へ | 次へ | 目次 | 索引 |
文字列をパターンと照合します。
#include <unixlib.h>int decc$match_wild (char *test_string, char *string_pattern);
test_string
ヌル区切り文字列のアドレス。string_pattern
照合するパータンを格納した文字列のアドレス。このパターンには正規表現 (範囲 [a-z] など) だけでなく,ワイルドカード (アスタリスク (*),疑問符 (?),パーセント記号 (%)) なども含むことができます。
decc$match_wildルーチンは,指定されたテスト文字列が,パータンによって指定される文字列セットのメンバであるかどうかを判断します。
1 (TRUE) 文字列はパターンと一致します。 0 (FALSE) 文字列はパターンと一致しません。
/* Define as a foreign command and then provide */ /* two arguments: test_string, string_pattern. */ #include <unixlib.h> #include <stdio.h> int main(int argc, char *argv[]) { if (decc$match_wild(argv[1], argv[2])) printf("\n%s matches %s", argv[1], argv[2]); else printf("\n%s does not match %s", argv[1], argv[2]); }
レコードをファイルから読み込みます。
#include <stdio.h>int decc$record_read (FILE *fp, void *buffer, int nbytes);
fp
ファイル・ポインタ。ファイル・ポインタは,読み込みのために現在オープンされているファイルを参照しなければなりません。buffer
入力データが格納される連続した記憶域のアドレス。nbytes
読み込み操作で読み込まれる最大バイト数。
decc$record_read関数は OpenVMS システム固有であり,移植可能なアプリケーションを作成する場合は使用すべきではありません。この関数は read関数と同じですが,最初の引数がファイル記述子ではなく,ファイル・ポインタである点が異なります。
x 読み込んだ文字数。 - 1 物理的な入力エラー,不正なバッファ・アドレス,保護違反,未定義ファイル記述子などの読み込みエラーを示します。
レコードをファイルに書き込みます。
#include <stdio.h>int decc$record_write (FILE *fp, void *buffer, int nbytes);
fp
ファイル・ポインタ。ファイル・ポインタは,書き込みまたは更新のために現在オープンされているファイルを参照しなければなりません。buffer
出力データが格納されている連続する記憶域のアドレス。nbytes
書き込み操作で書き込まれる最大バイト数。
decc$record_write関数は OpenVMS システム固有であり,移植可能なアプリケーションを作成する場合は使用すべきではありません。この関数は write関数と同じですが,最初の引数がファイル記述子ではなく,ファイル・ポインタである点が異なります。
x 書き込んだバイト数。 - 1 未定義ファイル記述子,不正なバッファ・アドレス,物理 I/O エラーなどのエラーを示します。
execファミリの関数で生成される子プロセス用のデフォルト・ディレクトリを設定します。
#include <unixlib.h>int decc$set_child_default_dir (const char *default_dir);
default_dir
子プロセス用のデフォルト・ディレクトリの指定,または NULL。
デフォルトでは, execファミリの関数で生成される子プロセスは,親プロセスのデフォルト (作業) ディレクトリを継承します。decc$set_child_default_dir関数を使用すると,子プロセス用のデフォルト・ディレクトリを設定できます。 decc$set_child_default_dirを呼び出した後,新しく生成される子プロセスは,実行開始時に,デフォルト・ディレクトリとして default_dir が設定されます。 default_dir 引数は,正しいディレクトリ指定でなければなりません。正しくないと,この呼び出しの結果は予期できないものとなります (以後子プロセスを呼び出すと,何の通知もなく失敗することがあります)。この関数呼び出しでは, OpenVMS と UNIX の両方の形式のファイル指定がサポートされています。
default_dir に NULL を指定すると,デフォルトの動作に戻すことができます。以降は,新しく生成される子プロセスは,親プロセスの作業ディレクトリを継承します。
0 成功を示します。新しいデフォルト・ディレクトリが継承されるようになります。 - 1 失敗を示します。子プロセス用に新しいデフォルト・ディレクトリを設定することができませんでした。この関数は,次のいずれかの値を errno に設定します。
- ENOMEM -- メモリ不足です。
- ENAMETOOLONG -- 必要な SET DEFAULT コマンドを実行するには, default_dir が長すぎます。
exec関数ファミリの関数によって生成された子プロセスに対して,指定されたファイル記述子を子の標準ストリーム stdin, stdout, stderrに関連付けます。
#include <unixlib.h>int decc$set_child_standard_streams (int fd1, int fd2, int fd3);
fd1
親プロセスでこのファイル記述子に関連付けられているファイルは,子プロセスでファイル記述子番号 0 ( stdin) に関連付けられます。 - 1 を指定した場合,親のファイル記述子番号 0 に関連付けられているファイルが使用されます (デフォルト)。fd2
親プロセスでこのファイル記述子に関連付けられているファイルは,子プロセスでファイル記述子番号 1 ( stdout) に関連付けられます。 - 1 を指定した場合,親のファイル記述子番号 1 に関連付けられているファイルが使用されます (デフォルト)。fd3
親プロセスでこのファイル記述子に関連付けられているファイルは,子プロセスでファイル記述子番号 2 ( stderr) に関連付けられます。 - 1 を指定した場合,親のファイル記述子番号 2 に関連付けられているファイルが使用されます (デフォルト)。
decc$set_child_standard_streams関数を使用すると,指定されたファイル記述子と子の stdin/stdout/stderrストリームとの対応付けが可能になり,それによって OpenVMS システムに実際の fork関数が欠如しているという問題をある程度補うことができます。UNIX システムでは, forkと execの間のコードは子プロセスのコンテキストで実行されます。
parent: create pipes p1, p2 and p3 fork child: map stdin to p1 like dup2(p1, stdin); map stdout to p2 like dup2(p2, stdout); map stderr to p3 like dup2(p3, stderr); exec (child reads from stdin and writes to stdout and stderr) exit parent: communicates with the child using pipes
OpenVMS システムでは,同じタスクを次のように実行することができます。
parent: create pipes p1, p2 and p3 decc$set_child_standard_streams(p1, p2, p3); vfork exec (child reads from stdin and writes to stdout and stderr) parent: communicates with the child using pipes
decc$set_child_standard_streamsの呼び出しで子の標準ストリームのマッピングを確立した後,このマッピングは,次のいずれかの呼び出しで明示的に無効にするまで有効です。
decc$set_child_standard_streams(-1, -1, -1);
または
decc$set_child_standard_streams(0, 1, 2);
通常,子プロセスは親のオープンされているすべてのファイル記述子を継承します。しかし, decc$set_child_standard_streamsの呼び出しにファイル記述子番号 n が指定されている場合は,親の記述子番号はファイル記述子番号 n として子プロセスに継承されず,子の標準ストリームの記述子番号になります。
注意
- 標準ストリームは,パイプにのみリダイレクトすることができます。
- 親プロセスが DCL の DEFINE コマンドを再定義した場合,この再定義はユーザ定義チャネルを含むサブプロセスでは有効ではありません。サブプロセスは常に標準の DCL の DEFINE コマンドを使用します。
- 子プロセスが stdoutと stderrに書き込んだすべての出力を使用するのは,親プロセスの責任です。サブプロセスが stdoutと stderrに書き込む方法 ( 待機モードまたは待機なしモード ) に応じて,サブプロセスは LEF 状態になり,読み込み側がデータを読み込むのを待つことがあります。たとえば,DCLは待機モードで SYS$OUTPUT と SYS$ERROR に書き込むので, DCL コマンド・プロシージャを実行する子プロセスは,すべての出力が親プロセスから読み込まれるまで待機状態になります。
推奨手順: EOF メッセージが受信されるまで,子プロセスの stdoutと stderrに関連付けられているパイプをループで読み込むか,またはこれらのメールボックスで書き込みアテンション AST を宣言してください。- SYS$OUTPUT に書き込まれるデータの量は,プロセスの確認状態 (SET VERIFY/NOVERIFY コマンド) に応じて異なります。サブプロセスは親プロセスの確認状態を継承します。サブプロセスが SYS$OUTPUT に書き込むと考えられるデータの量に対応するように親プロセスの確認状態を設定するのは,呼び出し元の責任です。
- DTM など,一部のアプリケーションは,SYS$ERROR を SYS$OUTPUT として定義します。 stderrが呼び出し元で再定義されていない場合は,サブプロセスで親の SYS$ERROR として設定され,その場合,親の SYS$OUTPUT に変換されます。
呼び出し元が stdoutをパイプに再定義し, stderrを再定義しなかった場合は, stderrに送信された出力は, stdoutに関連付けられているパイプに送られ,このメールボックスに書き込まれるデータの量は予想より多くなる可能性があります。標準チャネルのサブセットの再定義はサポートされますが,このような状況を回避するために,すべての標準チャネル ( 少なくとも stdoutと stderr) を明示的に再定義するのが常に安全です。- DCL コマンド・プロシージャを実行する子プロセスの場合, SYS$COMMAND は子の stdinに対して指定されたパイプに設定されるので,親プロセスはパイプを通じて SYS$COMMAND から子が要求しているデータを送ることができます。DCL コマンド・プロシージャの場合,子の SYS$INPUT を使用して親から子にデータを渡すことができません。これは,コマンド・プロシージャの場合, DCL は SYS$INPUT をコマンド・ファイル自体として定義するからです。
x 子に対して設定されているファイル記述子の数。この数には,呼び出しに - 1 として指定されたファイル記述子は含まれません。 - 1 不正なファイル記述子が指定されたことを示します。 errno は EBADF に設定されます。
parent.c ======== #include <stdio.h> #include <string.h> #include <unistd.h> int decc$set_child_standard_streams(int, int, int); main() { int fdin[2], fdout[2], fderr[2]; char msg[] = "parent writing to child's stdin"; char buf[80]; int nbytes; pipe(fdin); pipe(fdout); pipe(fderr); if ( vfork() == 0 ) { decc$set_child_standard_streams(fdin[0], fdout[1], fderr[1]); execl( "child", "child" ); } else { write(fdin[1], msg, sizeof(msg)); nbytes = read(fdout[0], buf, sizeof(buf)); buf[nbytes] = '\0'; puts(buf); nbytes = read(fderr[0], buf, sizeof(buf)); buf[nbytes] = '\0'; puts(buf); } } child.c ======= #include <stdio.h> #include <unistd.h> main() { char msg[] = "child writing to stderr"; char buf[80]; int nbytes; nbytes = read(0, buf, sizeof(buf)); write(1, buf, nbytes); write(2, msg, sizeof(msg)); } child.com ========= $ read sys$command s $ write sys$output s $ write sys$error "child writing to stderr"
このサンプル・プログラムでは, child.cと child.comの両方に対して次の情報が返されます。
$ run parent parent writing to child's stdin child writing to stderr
child.comを起動するには, parent.cプログラムで明示的に execl("child.com", ...)を指定する必要があります。
リエントラントな HP C RTL ルーチンが示すリエントラントのタイプを制御します。
#include <reentrancy.h>int decc$set_reentrancy (int type);
type
目的のリエントラントのタイプ。次のいずれかの値を使用します。
- C$C_MULTITHREAD --- DECthreads 製品と組み合わせて使用するように設計されています。DECthreads ロックを実行し, AST を絶対に無効にしません。この形式のリエントラントを使用するには,システムで DECthreads が使用可能でなければなりません。
- C$C_AST --- _BBSSI (VAX only) または __TESTBITSSI (Alpha, I64) 組み込み関数を使用して,RTL コードのクリティカル・セクションの周囲で単純なロックを実行し,ロックされたコード領域で非同期システム・トラップ (AST) を無効にすることもあります。AST コードに HP C RTL I/O ルーチンの呼び出しが含まれている場合や,ユーザ・アプリケーションで AST を無効にする場合は,このタイプのロックを使用する必要があります。
- C$C_TOLERANT --- _BBSSI (VAX only) または __TESTBITSSI (Alpha, I64) 組み込み関数を使用して,RTL コードのクリティカル・セクションの周囲で単純なロックを実行しますが,AST は無効になりません。 AST が使用され,ただちに配布しなければならない場合は,このタイプのロックを使用する必要があります。 TOLERANT はデフォルトのリエントラント・タイプです。
- C$C_NONE --- HP C RTL で最適な性能を実現しますが,RTL コードのクリティカル・セクションの周囲で絶対にロックを行いません。 HP C RTL を呼び出す AST によって実行スレッドが割り込まれる可能性がない場合に,単一スレッド環境でのみ使用するようにしなければなりません。
リエントラント・タイプは上げることができますが,下げることはできません。リエントラント・タイプを低いものから高いものへ順に並べると,C$C_NONE, C$C_TOLERANT,C$C_AST,C$C_MULTITHREAD の順になります。たとえば,アプリケーションをマルチスレッドに設定した後,リエントラントを AST に設定する呼び出しは無視されます。 decc$set_reentrancyの呼び出しでリエントラント・タイプを下げようとすると, - 1 という値が返されます。
リエントラント・ルーチンによって示されるリエントラントのタイプを変更するには, decc$set_reentrancy関数を使用します。decc$set_reentrancyは非 AST レベルで明示的に呼び出す必要があります。
DECthreads を使用するアプリケーションでは,DECthreads が自動的にリエントラントをマルチスレッドに設定します。
タイプ この呼び出しの前に使用されていたリエントラントのタイプ。 - 1 リエントラント・タイプを下げようとしたことを示します。
| 前へ | 次へ | 目次 | 索引 |