前へ | 次へ | 目次 | 索引 |
レコードをファイルに書き込みます。
#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(stdin, p1); map stdout to p2 like dup2(stdout, p2); map stderr to p3 like dup2(stderr, p3); 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 only) 組み込み関数を使用して,RTL コードのクリティカル・セクションの周囲で単純なロックを実行し,ロックされたコード領域で非同期システム・トラップ (AST) を無効にすることもあります。AST コードに HP C RTL I/O ルーチンの呼び出しが含まれている場合や,ユーザ・アプリケーションで AST を無効にする場合は,このタイプのロックを使用する必要があります。
- C$C_TOLERANT --- _BBSSI (VAX only) または __TESTBITSSI (Alpha only) 組み込み関数を使用して,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 リエントラント・タイプを下げようとしたことを示します。
UNIX 形式のファイル指定を OpenVMS ファイル指定に変換します。
#include <unixlib.h>int decc$to_vms (const char *unix_style_filespec, int (*action_routine)(char *unix_style_filespec, int type_of_file), int allow_wild, int no_directory);
unix_style_filespec
UNIX のファイル指定形式で名前を格納したヌル区切り文字列のアドレス。action_routine
次の引数を受け付けるルーチンのアドレス。
- 有効な OpenVMS ファイル名に変換される UNIX 形式のファイル名を格納したヌル区切り文字列を指すポインタ。
- 次のいずれかの整数値。
値 変換 0 (DECC$K_FOREIGN) OpenVMS または VAXELN オペレーティング・システムを実行していないリモート・システムのファイル。 2 (DECC$K_DIRECTORY) UNIX 形式のファイル名から OpenVMS のディレクトリに変換することを示す。 1 (DECC$K_FILE) 変換の対象がファイルであることを示す。
これらの値は,シンボル DECC$K_FOREIGN, DECC$K_DIRECTORY,DECC$K_FILE によってシンボルとして定義することができます。詳細については,例を参照してください。
action_routine が 0 以外の値 (TRUE) を返した場合は,ファイル変換は続行されます。0 (FALSE) を返した場合は,それ以降のファイル変換は行われません。
allow_wild
0 または 1 を値によって渡します。 0 を指定した場合は,unix_style_filespec で検出されたワイルドカードは展開されません。それ以外の場合は,ワイルドカードは展開され,それぞれの展開結果が action_routine に渡されます。展開されたファイル名のうち,既存の OpenVMS ファイルに対応するファイルだけが渡されます。no_directory
次のいずれかの値の整数。
値 変換 0 ディレクトリは許可されない。 1 文字列をディレクトリ名として展開することを禁止する。 2 強制的にディレクトリ名に変換する。
decc$to_vms関数は,指定された UNIX 形式のファイル指定を対応する OpenVMS ファイル指定 (すべて大文字) に変換します。 UNIX 形式のワイルドカードを指定することができ,その場合は対応する OpenVMS ファイルのリストに変換されます。decc$to_vmsの動作に影響する次の機能論理名については,『HP C ランタイム・ライブラリ・リファレンス・マニュアル(上巻)』第 1.6 節を参照してください。
DECC$DISABLE_TO_VMS_LOGNAME_TRANSLATION
DECC$NO_ROOTED_SEARCH_LISTS
x 指定された UNIX 形式のファイル指定から変換されたファイル名の数。
/* Translate "UNIX" wildcard file names to OpenVMS names */ /* Define as a foreign command and provide the name as */ /* an argument. */ #include <unixlib.h> #include <stdio.h> int print_name(char *, int); int main(int argc, char *argv[]) { int number_found; /* number of files found */ printf("Translating: %s\n", argv[1]); number_found = decc$to_vms(argv[1], print_name, 1, 0); printf("%d files found\n", number_found); } /* action routine that prints name and type on each line */ int print_name(char *name, int type) { if (type == DECC$K_DIRECTORY) printf("directory: %s\n", name); else if (type == DECC$K_FOREIGN) printf("remote non-VMS: %s\n", name); else printf("file: %s\n", name); /* Translation continues as long as success status is returned */ return (1); }
この例では, HP C で decc$to_vmsルーチンを使用する方法を示しています。引数として UNIX 形式のファイル指定を受け付け,OpenVMS ファイル指定形式で対応する既存の各ファイルの名前を表示します。
前へ | 次へ | 目次 | 索引 |