日本-日本語
日本HPホーム 製品 & サービス OpenVMS製品情報
≫  お問い合わせ


OpenVMS マニュアル


 

OpenVMS ドキュメント
ライブラリ

タイトル
目次
まえがき
リファレンス・セクション
   ≫ライブラリ関数一覧
索引
PDF
OpenVMS ホーム

HP OpenVMS
HP C ランタイム・ライブラリ・リファレンス・マニュアル (下巻)


目次 索引




exec関数ファミリの関数によって生成された子プロセスに対して,指定されたファイル記述子を子の標準ストリーム stdinstdoutstderrに関連付けます。

形式

#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 システムでは, forkexecの間のコードは子プロセスのコンテキストで実行されます。

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 コマンドを使用します。

  • 子プロセスが stdoutstderrに書き込んだすべての出力を使用するのは,親プロセスの責任です。サブプロセスが stdoutstderrに書き込む方法 ( 待機モードまたは待機なしモード ) に応じて,サブプロセスは LEF 状態になり,読み込み側がデータを読み込むのを待つことがあります。たとえば,DCLは待機モードで SYS$OUTPUT と SYS$ERROR に書き込むので, DCL コマンド・プロシージャを実行する子プロセスは,すべての出力が親プロセスから読み込まれるまで待機状態になります。
    推奨手順: EOF メッセージが受信されるまで,子プロセスの stdoutstderrに関連付けられているパイプをループで読み込むか,またはこれらのメールボックスで書き込みアテンション AST を宣言してください。

  • SYS$OUTPUT に書き込まれるデータの量は,プロセスの確認状態 (SET VERIFY/NOVERIFY コマンド) に応じて異なります。サブプロセスは親プロセスの確認状態を継承します。サブプロセスが SYS$OUTPUT に書き込むと考えられるデータの量に対応するように親プロセスの確認状態を設定するのは,呼び出し元の責任です。

  • DTM など,一部のアプリケーションは,SYS$ERROR を SYS$OUTPUT として定義します。 stderrが呼び出し元で再定義されていない場合は,サブプロセスで親の SYS$ERROR として設定され,その場合,親の SYS$OUTPUT に変換されます。
    呼び出し元が stdoutをパイプに再定義し, stderrを再定義しなかった場合は, stderrに送信された出力は, stdoutに関連付けられているパイプに送られ,このメールボックスに書き込まれるデータの量は予想より多くなる可能性があります。標準チャネルのサブセットの再定義はサポートされますが,このような状況を回避するために,すべての標準チャネル ( 少なくとも stdoutstderr) を明示的に再定義するのが常に安全です。

  • 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.cchild.comの両方に対して次の情報が返されます。

$ run parent 
parent writing to child's stdin 
child writing to stderr 

child.comを起動するには, parent.cプログラムで明示的に execl("child.com", ...)を指定する必要があります。


目次 索引

© 2012 Hewlett-Packard Development Company, L.P.