HP OpenVMS Systems Documentation |
| 前へ | 次へ | 目次 | 索引 |
例 5-2 では,親は子プロセスに引数を渡します。
| 例 5-2 子プロセスへの引数の引き渡し |
|---|
/* CHAP_5_CHILDARG.C */
/* In this example, the arguments are placed in an array, gargv, */
/* but they can be passed to the child explicitly as a zero- */
/* terminated series of character strings. The child program in this */
/* example writes the arguments that have been passed it to stdout. */
#include <climsgdef.h>
#include <stdio.h>
#include <stdlib.h>
#include <perror.h>
#include <processes.h>
const char *child_name = "chap_5_childarg_child.exe" ;
main()
{
int status,
cstatus;
char *gargv[] =
{"Child", "ARGC1", "ARGC2", "Parent", 0};
if ((status = vfork()) != 0) {
if (status < -1)
printf("Parent - Child process failed\n");
else {
printf("Parent - waiting for Child\n");
if ((status = wait(&cstatus)) == -1)
perror("Parent - Wait failed");
else if (cstatus == CLI$_IMAGEFNF)
printf("Parent - Child does not exist\n");
else
printf("Parent - Child final status: %x\n",
cstatus);
}
}
else {
printf("Parent - Starting Child\n");
if ((status = execv(child_name, gargv)) == -1) {
perror("Parent - Exec failed");
exit(EXIT_FAILURE);
}
}
}
--------------------------------------------------------
/* CHAP_5_CHILDARG_CHILD.C */
/* This is a child program that echos its arguments */
#include <stdio.h>
main(argc, argv)
int argc;
char *argv[];
{
int i;
printf("Program name: %s\n", argv[0]);
for (i = 1; i < argc; i++)
printf("Argument %d: %s\n", i, argv[i]);
return(255) ;
}
|
例 5-3 は, wait関数を使用して,同時に実行される複数の子の最終状態を確認する方法を示しています。
| 例 5-3 子プロセスの状態の確認 |
|---|
/* CHAP_5_CHECK_STAT.C */
/* In this example 5 child processes are started. The wait() */
/* function is placed in a separate for loop so that it is */
/* called once for each child. If wait() were called within */
/* the first for loop, the parent would wait for one child to */
/* terminate before executing the next child. If there were */
/* only one wait request, any child still running when the */
/* parent exits would terminate prematurely. */
#include <climsgdef.h>
#include <stdio.h>
#include <stdlib.h>
#include <perror.h>
#include <processes.h>
const char *child_name = "chap_5_check_stat_child.exe" ;
main()
{
int status,
cstatus,
i;
for (i = 0; i < 5; i++) {
if ((status = vfork()) == 0) {
printf("Parent - Starting Child %d\n", i);
if ((status = execl(child_name, 0)) == -1) {
perror("Parent - Exec failed");
exit(EXIT_FAILURE);
}
}
else if (status < -1)
printf("Parent - Child process failed\n");
}
printf("Parent - Waiting for children\n");
for (i = 0; i < 5; i++) {
if ((status = wait(&cstatus)) == -1)
perror("Parent - Wait failed");
else if (cstatus == CLI$_IMAGEFNF)
printf("Parent - Child does not exist\n");
else
printf("Parent - Child %X final status: %d\n",
status, cstatus);
}
}
|
例 5-4 は, pipe関数と dup2関数を使用して,特定のファイル記述子を通じて親プロセスと子プロセスの間で通信する方法を示しています。 #defineプリプロセッサ・ディレクティブは,プリプロセッサ定数 inpipeと outpipeをファイル記述子 11 と 12 の名前として定義します。
| 例 5-4 パイプによる通信 |
|---|
/* CHAP_5_PIPE.C */
/* In this example, the parent writes a string to the pipe for */
/* the child to read. The child then writes the string back */
/* to the pipe for the parent to read. The wait function is */
/* called before the parent reads the string that the child has */
/* passed back through the pipe. Otherwise, the reads and */
/* writes will not be synchronized. */
#include <perror.h>
#include <climsgdef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <processes.h>
#include <unixio.h>
#define inpipe 11
#define outpipe 12
const char *child_name = "chap_5_pipe_child.exe" ;
main()
{
int pipes[2];
int mode,
status,
cstatus,
len;
char *outbuf,
*inbuf;
if ((outbuf = malloc(512)) == 0) {
printf("Parent - Outbuf allocation failed\n");
exit(EXIT_FAILURE);
}
if ((inbuf = malloc(512)) == 0) {
printf("Parent - Inbuf allocation failed\n");
exit(EXIT_FAILURE);
}
if (pipe(pipes) == -1) {
printf("Parent - Pipe allocation failed\n");
exit(EXIT_FAILURE);
}
dup2(pipes[0], inpipe);
dup2(pipes[1], outpipe);
strcpy(outbuf, "This is a test of two-way pipes.\n");
status = vfork();
switch (status) {
case 0:
printf("Parent - Starting child\n");
if ((status = execl(child_name, 0)) == -1) {
printf("Parent - Exec failed");
exit(EXIT_FAILURE);
}
break;
case -1:
printf("Parent - Child process failed\n");
break;
default:
printf("Parent - Writing to child\n");
if (write(outpipe, outbuf, strlen(outbuf) + 1) == -1) {
perror("Parent - Write failed");
exit(EXIT_FAILURE);
}
else {
if ((status = wait(&cstatus)) == -1)
perror("Parent - Wait failed");
if (cstatus == CLI$_IMAGEFNF)
printf("Parent - Child does not exist\n");
else {
printf("Parent - Reading from child\n");
if ((len = read(inpipe, inbuf, 512)) <= 0) {
perror("Parent - Read failed");
exit(EXIT_FAILURE);
}
else {
printf("Parent: %s\n", inbuf);
printf("Parent - Child final status: %d\n",
cstatus);
}
}
}
break;
}
}
------------------------------------------------------------------
/* CHAP_5_PIPE_CHILD.C */
/* This is a child program which reads from a pipe and writes */
/* the received message back to its parent. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define inpipe 11
#define outpipe 12
main()
{
char *buffer;
int len;
if ((buffer = malloc(512)) == 0) {
perror("Child - Buffer allocation failed\n");
exit(EXIT_FAILURE);
}
printf("Child - Reading from parent\n");
if ((len = read(inpipe, buffer, 512)) <= 0) {
perror("Child - Read failed");
exit(EXIT_FAILURE);
}
else {
printf("Child: %s\n", buffer);
printf("Child - Writing to parent\n");
if (write(outpipe, buffer, strlen(buffer) + 1) == -1) {
perror("Child - Write failed");
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
|
この章では, HP C for OpenVMS システムで提供される画面管理ルーチンについて説明します。
OpenVMS Curses 画面管理パッケージは,すべての OpenVMS システムでサポートされます。
OpenVMS Alpha システムでは, 2 つの画面管理パッケージがサポートされます。それは OpenVMS Curses と,UNIX との互換性がより高く, BSD (Berkeley Standard Distribution) Curses ソフトウェア 1 第 6.1 節 を参照してください。
さらに, HP C RTL では,4.4BSD Berkeley Software Distribution をベースにした Curses パッケージも提供されるようになりました。 4.4BSD Curses パッケージに関する情報は,Kenneth C.R.C. Arnold 著,『Screen Updating and Cursor Movement Optimization: A Library Package』に記載されています。
OpenVMS と BSD ベースの Curses パッケージの関数およびマクロはほぼ同じです。両者の相違点の大部分については,この章で説明しています。それ以外の場合は,この章では 2 つの Curses パッケージを区別せず,単に「Curses」または「Curses 関数とマクロ」と呼んでいます。
1 Copyright (c) 1981 Regents of the University of California. |
6.1 BSD ベースの Curses パッケージの使用 (Alpha only)
BSD ベースの Curses の実装を使用するのに必要な <curses.h>ヘッダ・ファイルは, OpenVMS Alpha システムでは HP C コンパイラで提供されます。
OpenVMS Curses 関数はデフォルトの Curses パッケージとして提供されるため,既存のプログラムは BSD ベースの Curses 関数の影響を受けません ( この点は,BSD ベースの Curses がデフォルトであった HP C の以前のバージョンから変更された点です)。
4.4BSD Curses の実装を入手するには,次の修飾子を使用して <curses.h>を取り込むモジュールをコンパイルする必要があります。
/DEFINE=_BSD44_CURSES
BSD ベースの Curses 関数では,Curses 関数によって割り当てられたペーストボードとキーボードを使用する OpenVMS SMG$ ルーチンを呼び出すのに必要なサポートは提供されません。したがって, SMG$ エントリ・ポイントの呼び出しおよび Curses 関数に依存する Curses プログラムは,今後も OpenVMS の Curses を使用する必要があります。
BSD ベースの Curses は,以前の実装との間で相互運用性がありません。新しい関数と古い関数の呼び出しが混在している場合,画面に不正な出力が表示され,SMG$ ルーチンから例外が発生する可能性があります。
6.2 Curses の概要
Curses,つまり HP C Screen Management Package は,端末画面の定義されたセクションの作成と変更,およびカーソルの最適な移動を行う HP C RTL 関数およびマクロで構成されています。画面管理パッケージを使用すると,ユーザにとって親しみやすく,魅力のあるユーザ・インタフェースを開発できます。 Curses は端末に依存しておらず,端末画面の書式設定を簡単に行うことができ,効率のよいカーソルの移動を実現できます。
ほとんどの Curses 関数とマクロは 2 つ 1 組で示されます。最初のルーチンがマクロで,2 番目が "ウィンドウ" を表す接頭語 "w" から始まる関数です。これらの接頭語は角括弧 ([ ]) で囲んで示されます。たとえば, [w]addstrは, addstrマクロと waddstr関数を示します。マクロのウィンドウは,デフォルトで stdscrに設定され,関数は,引数として指定されたウィンドウを受け付けます。
Curses 関数およびマクロにアクセスするには, <curses.h>ヘッダ・ファイルを取り込みます。
端末に依存しない Screen Management Software は OpenVMS RTL の一部であり, Curses を実装するために使用されます。移植性を確保するために,ほとんどの関数とマクロは他の C の実装と同様の方法で動作するように設計されています。しかし,Curses ルーチンは OpenVMS システムおよびその Screen Management Software に依存しているため,一部の関数とマクロの動作は他の実装の関数およびマクロと少し異なる可能性があります。
他のシステムで提供される関数とマクロの中には, HP C RTL Curses パッケージで提供されないものがあります。
[w]clrattr, [w]insstr, mv[w]insstr, [w]setattrなどの一部の関数は, HP C for OpenVMS Systems 固有であり,移植できません。
表 6-1 は, HP C RTL で提供されるすべての Curses 関数とマクロを示しています。各関数とマクロの詳細については,『HP C ランタイム・ライブラリ・リファレンス・マニュアル (下巻)』「リファレンス・セクション」を参照してください。
| 関数またはマクロ | 説明 |
|---|---|
| [w]addch | ウィンドウの現在のカーソルの位置に文字を追加する。 |
| [w]addstr | ウィンドウの現在のカーソルの位置に文字列を追加する。 |
| box | ウィンドウの周囲に四角形を描く。 |
| [w]clear | 指定されたウィンドウの内容を消去し,カーソルの位置を座標 (0,0) にリセットする。 |
| clearok | ウィンドウのクリア・フラグを設定する。 |
| [w]clrattr | ウィンドウの内部でビデオ表示属性を無効にする。 |
| [w]clrtobot | カーソルの現在の位置からウィンドウの最下部まで,ウィンドウの内容を消去する。 |
| [w]clrtoeol | 指定されたウィンドウの現在のカーソルの位置から行末まで,ウィンドウの内容を消去する。 |
| [no]crmode | 端末を cbreak モードに設定する。または設定を解除する。 |
| [w]delch | 指定されたウィンドウで,現在のカーソルの位置から文字を削除する。 |
| [w]deleteln | 現在のカーソルの位置から行を削除する。 |
| delwin | 指定されたウィンドウをメモリから削除する。 |
| [no]echo | 文字が端末画面に表示されるように,または表示されないように,端末を設定する。 |
| endwin | 端末画面をクリアし,Curses 構造体に割り当てられている仮想メモリを解放する。 |
| [w]erase | 空白をペイントすることにより,ウィンドウを消去する。 |
| [w]getch | 端末画面から 1 文字を取得し,指定されたウィンドウに表示する。 |
| [w]getstr | 端末画面から文字列を取得し,文字変数に格納し,指定されたウィンドウに表示する。 |
| getyx | ウィンドウで現在のカーソルの位置の座標 (y,x) を変数 y および変数 x に代入する。 |
| [w]inch | ウィンドウを変更せずに,指定されたウィンドウの現在のカーソルの位置にある文字を返す。 |
| initscr | 端末タイプ・データとすべての画面関数を初期化する。 |
| [w]insch | 指定されたウィンドウの現在のカーソルの位置に文字を挿入する。 |
| [w]insertln | 現在カーソルが設定されている行の上に 1 行を挿入する。 |
| [w]insstr | 指定されたウィンドウの現在のカーソルの位置に文字列を挿入する。 |
| leaveok | ウィンドウを更新した後,現在の座標にカーソルをそのまま置く。 |
| longname | 文字列を十分格納できるだけの大きさの文字名に完全な端末の名前を代入する。 |
| [w]move | 指定されたウィンドウの現在のカーソルの位置を変更する。 |
| mv[w]addch | カーソルを移動し,指定されたウィンドウに文字を追加する。 |
| mv[w]addstr | カーソルを移動し,指定されたウィンドウに文字列を追加する。 |
| mvcur | 端末のカーソルを移動する。 |
| mv[w]delch | カーソルを移動し,指定されたウィンドウで文字を削除する。 |
| mv[w]getch | カーソルを移動し,端末画面から文字を取得し,指定されたウィンドウに表示する。 |
| mv[w]getstr | カーソルを移動し,端末画面から文字列を取得し,その文字列を変数に格納し,指定されたウィンドウに表示する。 |
| mv[w]inch | カーソルを移動し,ウィンドウを変更せずに,指定されたウィンドウの文字を返す。 |
| mv[w]insch | カーソルを移動し,指定されたウィンドウに文字を挿入する。 |
| mv[w]insstr | カーソルを移動し,指定されたウィンドウに文字列を挿入する。 |
| mvwin | ウィンドウの開始位置を指定された座標に移動する。 |
| newwin | 端末画面の指定された座標から始まる行と列で新しいウィンドウを作成する。 |
| [no]nl | UNIX ソフトウェアとの互換性を維持するためだけに提供され, OpenVMS 環境では機能しない。 |
| overlay | 1 つのウィンドウの内容 (別のウィンドウの内容の上に完全に収まるサイズ) を別のウィンドウの内容に上に完全に書き込む。処理は 2 つのウィンドウの開始座標から開始される。 |
| overwrite | 1 つのウィンドウの内容を別のウィンドウの上に収まる範囲で書き込む。処理は 2 つのウィンドウの開始座標から開始される。 |
| [w]printw | 現在のカーソルの位置からウィンドウに対して printf を実行する。 |
| [no]raw | UNIX ソフトウェアとの互換性を維持するためだけに提供され, OpenVMS 環境では機能しない。 |
| [w]refresh | 指定されたウィンドウを端末画面に再表示する。 |
| [w]scanw | ウィンドウに対して scanf を実行する。 |
| scroll | ウィンドウのすべての行を 1 行ずつ上に移動する。 |
| scrollok | 指定されたウィンドウのスクロール・フラグを設定する。 |
| [w]setattr | ウィンドウ内でビデオ表示属性を有効にする。 |
| [w]standend | 指定されたウィンドウの太字属性を無効にする。 |
| [w]standout | 指定されたウィンドウの太字属性を有効にする。 |
| subwin | 端末画面で指定された座標から始まる行と列で新しいサブウィンドウを作成する。 |
| touchwin | 指定されたウィンドウの最新バージョンを端末画面に表示する。 |
| wrapok | OpenVMS Curses のみ。ウィンドウの右端から次の行の先頭への単語の折り返しを認める。 |
| 前へ | 次へ | 目次 | 索引 |