日本-日本語 |
|
|
|
OpenVMS マニュアル |
|
HP OpenVMS
|
目次 | 索引 |
decc$set_child_standard_streams |
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", ...)を指定する必要があります。
目次 | 索引 |
|