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


前へ 次へ 目次 索引



decc$record_write

レコードをファイルに書き込みます。

形式

#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 エラーなどのエラーを示します。


decc$set_child_default_dir (Alpha only)

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 が長すぎます。


decc$set_child_standard_streams

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

  • 子プロセスが 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", ...)を指定する必要があります。


decc$set_reentrancy

リエントラントな HP C RTL ルーチンが示すリエントラントのタイプを制御します。

形式

#include <reentrancy.h>

int decc$set_reentrancy (int type);


引数

type

目的のリエントラントのタイプ。次のいずれかの値を使用します。

リエントラント・タイプは上げることができますが,下げることはできません。リエントラント・タイプを低いものから高いものへ順に並べると,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 リエントラント・タイプを下げようとしたことを示します。


decc$to_vms

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

次の引数を受け付けるルーチンのアドレス。

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 Cdecc$to_vmsルーチンを使用する方法を示しています。引数として UNIX 形式のファイル指定を受け付け,OpenVMS ファイル指定形式で対応する既存の各ファイルの名前を表示します。


前へ 次へ 目次 索引