exec 関数

標準

標準/拡張機能 C/C++ 依存項目

POSIX.1
XPG4
XPG4.2
Single UNIX Specification、バージョン 3

両方  

形式

#define _POSIX_SOURCE
#include <unistd.h>
extern char **environ;

int execl(const char *path, const char *arg, …, NULL);
int execle(const char *path, const char *arg, …, NULL, char *const envp[]);
int execlp(const char *file, const char *arg, …, NULL);
int execv(const char *path, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
注: POSIX.1 では unistd.h 組み込みファイルをインクルードする必要は ありませんが、移植性のために unistd.h 組み込みファイルを インクルードすることをお勧めします。

機能説明

exec 関数のすべてが、現行のプロセス・イメージを HFS (階層ファイル ・システム) のファイルから取得した新しいプロセス・イメージに置き換える ことによって、新規プログラムを実行します。

MVS™ データ・セットと HFS ファイルの名前の指定についての詳細は 、「z/OS XL C/C++ プログラミング・ガイド」を参照してください

呼び出しプロセスが新規プロセスで上書きされるので、正常終了の 場合、exec 関数は制御を戻しません。

path 引数は、ファイルの絶対パス名または 相対パス名を指定するストリングです。このファイルには、実行されるプロセスのイメージが 含まれています。

file は、実行されるプロセスのイメージが 含まれているファイルのパス名を判別するのに使用される ストリングです。file にスラッシュ文字 (/) が含まれている場合、ファイルの絶対パス名または相対パス名であることが 想定されます。file にスラッシュが含まれていない場合、システムは、PATH 環境変数で指定した ディレクトリーのリストで、指定のファイル名を検索します。システムは PATH 変数に現れる順番で ディレクトリーをチェックして、file ストリングと名前 が一致する最初のファイルを実行します。ファイルは HFS に常駐していなければなりません。

exec 関数は、以下の環境変数を使用します。
STEPLIB
STEPLIB 環境変数の作成と、この環境変数の 新規プロセス・イメージへの伝搬とをサポートします。以下に、STEPLIB 環境変数に受け入れられる値と、それぞれの 値で取られるアクションを示します。
  • STEPLIB=NONE。新規プロセス・イメージの Steplib DD が作成されません。
  • STEPLIB=CURRENT。exec() への呼び出しの時点で 呼び出しタスクに対してアクティブになっている TASKLIB、STEPLIB、また は JOBLIB DD データ・セット割り振りは、これらのデータ・セット がカタログされていることが判断されると、新規プロセス・イメージに伝搬される。カタログされていない データ・セットは、新規プロセス・イメージに伝搬されません。
  • STEPLIB=Dsn1:Dsn2:,...DsnN。指定したデータ・セットの Dsn1:Dsn2:...DsnN は、新規プロセス・イメージの STEPLIB DD に組み込まれます。
    注: DD の実際の名前は STEPLIB ではありません が、STEPLIB DD と同じ効果を持つシステム生成名です。データ・セットは指定した順に連結されます。データ・セットの指定は、標準 MVS データ・セットの命名規則に従わなければなりません。この標準に違反しているデータ・セットは無視されます。データ・セットが標準に従っていても、以下の条件が該当する 場合、データ・セットは無視されます。
    • 呼び出し元に、データ・セットへの適切な セキュリティー・アクセスがない。
    • データ・セットがカタログされていない、または ロード・ライブラリー形式ではない。
    エラー状態のデータ・セットは無視されるため、実行可能ファイル は、適切な STEPLIB 環境を使用しないで実行されることがあります。不適切なセキュリティー・アクセスのためにデータ・セットが エラー状態の場合、X'913' 異常終了が生成されます。この異常終了のダンプは、ユーザーのインストールによって 抑制することができます。

STEPLIB 環境変数が指定されていない場合、exec() の デフォルトの動作は、STEPLIB=CURRENT が指定されている 場合と同じになります。

呼び出されるプログラムが set-user-ID また は set-group-ID ファイルで、さらにファイルの user-ID また は group-ID が現行プロセス・イメージのものとは異なる 場合、新規プロセス・イメージ用の STEPLIB 環境に 組み込まれるデータ・セット は、set-user-id および set-group-id プログラムの システム認可リストになければなりません。認可リストにあるデータ・セットだけが、新規プロセス・イメージの STEPLIB 環境に組み込まれます。認可リスト、および STEPLIB のパフォーマンス考慮事項に関する詳細は、「z/OS UNIX System Services 計画) を参照してください。

_BPX_JOBNAME
新規プロセス・イメージのジョブ名の変更に使用する。ジョブ名の変更が許可されるのは、呼び出し元に適切な特権 があり、さらにこの呼び出し元が fork により作成された アドレス・スペースで稼働中の場合だけです。これらの条件が満たされない場合、環境変数は無視されます。受け入れられる値は 1 ~ 8 の英数字のストリングです。誤った指定は無視されます。
_BPX_ACCT_DATA
新規プロセス・イメージのアカウント・データの変更に使用する。アカウント・データの指定の規則は次のとおりです。
  • 142 までの実アカウント・データ文字が許可される (任意の数のコンマを含む)。
  • サブパラメーターはコンマで分けなければならない。
  • 文字セットについての制約事項はない。
  • アカウント・データが 142 文字を超える場合、データは無視される。
_BPXK_JOBLOG
_BPXK_JOBLOG 環境変数を使用すると、WTO メッセージをオープン HFS ジョブ・ログ・ファイルに書き込むように指定できます。指定できる値を次に示します。
説明
nn
ジョブ・ログ・メッセージがオープン・ファイル記述子 nn に書き込まれます。
STDERR
ジョブ・ログ・メッセージが標準エラー・ファイル記述子 2 に書き込まれます。
なし
ジョブ・ログ・メッセージが書き込まれません。これはデフォルトです。

メッセージを取り込むために使用するファイルは、oe_env_np サービス (BPX1ENV) を呼び出して、_BPXK_JOBLOG を別のファイル記述子に指定することによって、随時変更できます。

指定されているファイル記述子に、fork または exec でクローズのマークが付けられた場合は、メッセージ取り込みがオフになります。

メッセージ取り込みは、プロセスに関連します。1 つのプロセス下では、すべてのスレッドでジョブ・ログ・ファイルを共用します。メッセージ取り込みは、そのプロセス下のどのスレッドからでも開始できます。

単一のアドレス・スペース内の複数の各プロセスで、異なるファイルを JOBLOG ファイルとしてアクティブにすることができます。一部またはすべてのプロセスで同じファイルを共用できます。また、一部のプロセスで、ほかのプロセスではアクティブにしないメッセージ取り込みをアクティブにすることができます。

ファイル記述子で表すことができるファイルだけを、ジョブ・ログ・ファイルとして使用できます。MVS データ・セットは使用できません。

メッセージ取り込みは、fork() または spawn() で伝搬されます。 ファイル記述子が指定された場合は、fork または作成されるプロセスでメッセージ取り込みが続行されるように、物理ファイルは同じものでなければなりません。STDERR が指定された場合は、ファイル記述子を別の物理ファイルに再マップできます。

メッセージ取り込みは、exec() または spawn() で指定変更できます。変更するには、_BPXK_JOBLOG 環境変数を exec() または spawn() のパラメーターとして指定します。

メッセージ取り込みは、fork された (BPXAS) アドレス・スペースでのみ行われます。
注: これは、本当のジョブ・ログのサポートではありません。通常 JESYSMSG データ・セットへ行くメッセージは取り込まれますが、JESMSGLG へ行くメッセージは取り込まれません。
XPG4 の特殊な動作: このファイルが有効な実行可能オブジェクトではない 場合、execlp() および execvp() 関数は、呼び出し元の パス名と残りの入力引数を指定して /bin/sh を 呼び出します。これは以下の呼び出しと同様です。
execl("/bin/sh",
      "sh",
      "--",
      fully_expanded_pathname,
      arg1, arg2, ..., argn,
      NULL
     );
ここで、arg1、arg2、...、argn は execlp() または execvp() への 呼び出し元の引数であり、fully_expanded_pathname は現行 PATH の ディレクトリーの検索により検出されるシェル・スクリプトのパス名です。

arg、…、NULL は、呼び出されている プロセスの引数を指定する NULL 終了文字ストリングを指す一連のポインターです。新規プロセスが main() の場合、これらのストリングは配列に保管され、その 配列を指すポインターは argv パラメーターに渡されます。最初の引数は必須で、この引数は、exec が開始しているプロセスに関連したファイルの名前を含むストリングを指す必要があります。NULL ポインターは、最後の引数ストリング・ポインターの次に 指定しなければなりません。

argv[ ] は、NULL 終了文字ストリングを指す一連のポインターからなる配列を指す ポインターです。配列の終わりをマークするため、最後の文字ストリングの 後に NULL ポインターがなければなりません。これらの文字ストリングは、呼び出されるプロセスに対する引数として 使用されます。argv[0] は、exec が開始しようとしているプロセスと関連付けられた ファイルの名前が入っているストリングを指している必要があります。envp[] は、NULL 終了文字ストリングを指す一連のポインターからなる配列を指す ポインターです。配列の終わりをマークするため、最後の文字ストリングの 後に NULL ポインターがなければなりません。envp のストリングは、新規プロセス用に 環境変数を提供します。

どの種類の exec 関数でも、実行する新規プロセスと新規プロセス に渡す必要のある引数のコレクションが含まれているファイルを見つける方法が提供 されます。それぞれの種類の exec ごとに、この情報を指定する独自のメソッドが あります。

exec 呼び出しの中には、envp 引数を使用して明示的に環境を 渡すものもあります。環境が明示的に渡されないバージョン - execl()、execlp()、execv()、および execvp() - では、システムは、呼び出し元の環境全体を使用します。呼び出し元の環境は、外部変数**environ が指す環境変数になると想定されます。

sysconf(_SC_ARG_MAX) を呼び出して z/OS®UNIX サービスから取得 される ARG_MAX 変数では、呼び出されるプロセスに渡される引数と 環境変数に使用できる最大バイト数を指定します。バイト数には、各ストリングの NULL ターミネーターが含まれます。

exec 関数で開始されたプロセスには、close-on-exec フラグ の FD_CLOEXEC でオープンされたファイルを除いて、呼び出し元に存在して いたオープン・ファイル記述子がすべてあります。このフラグについての詳細は、fcntl() - オープン・ファイル記述子の制御を 参照してください。オープンしたままのファイル記述子では、すべての属性が 未変更のままです (ファイル・ロックを含む)。

呼び出しプロセス・イメージでオープン中の ディレクトリー・ストリームは、新規プロセス・イメージで クローズされます。

変換記述子とメッセージ・カタログ記述子の状態は 未定義です。

呼び出し元で無視されるよう設定されたシグナル SIG_IGN は、新規プロセス・イメージで無視されるように設定されます。無視されているシグナルの取り扱いには注意してください。ハンドラーを指定する sigaction() は渡されません が、SIG_IGN は渡されます。シグナルのブロック化も渡されます。その他のすべてのシグナルは、呼び出し元がそのシグナルを処理した方法 にかかわらず、新規プロセス・イメージでデフォルト・ アクション SIG_DFL に設定されます。

新規プロセスの実ユーザー ID (UID)、実グループ ID (GID)、および補足グループ ID は、呼び出し元のものと同じです。プログラム・ファイルの set-user-ID モード・ビットがオン の場合、新規プロセスの有効ユーザー ID はファイルの 所有者に設定されます。同様に、プログラム・ファイルの set-group-ID モード・ビット がオンの場合、新規プロセスの有効グループ ID は ファイルのグループに設定されます。新規プロセス・イメージの有効ユーザー ID は 保管済み set-user-ID として保管され、新規プロセス・イメージの有効グループ ID は 保管済み set-group-ID として保管されます。

呼び出しプロセス・イメージに付加された共用メモリー・セグメントはいずれも、新規プロセス・イメージに付加されません。shmat() - 共用メモリー付加操作を参照してください。呼び出しプロセス・イメージに付加された共用メモリー・セグメントは、切り離されます (つまり、shm_nattch の値が 1 つ減ります)。これが共用メモリー・セグメントに付加された最後のスレッド であり、さらに shmctl() RMID が発行された場合、そのセグメントはシステムから取り除かれます。

XPG4.2 の特殊な動作: インターバル・タイマーは、exec の間中保持されます。

新規プロセスは、呼び出し元から以下のものも継承します。

exec 関数は、正常終了時には、指定したプログラム・ファイルを自動的 にオープンし、そのファイルのアクセス時間 st_atime を更新 します。プログラムがファイルから読み取られた後で、プログラム・ファイルは自動的にクローズされます。このクローズ操作の正確な時刻は未定義です。

z/OSUNIX サービスの特殊な動作:
  1. 無許可ライブラリーから MVS XCTL サービスによる、以前ロードされた MVS 無許可プログラムの再利用へ適用する同じ状況下で、同一アドレス・スペースで以前にロードされた HFS プログラムのコピーは 再利用されます。ただし、以下のような例外があります。
    • 呼び出しプロセスが Ptrace デバッグ・モードの場合、以前にロードされたコピーは再使用されません。
    • 呼び出しプロセスが Ptrace デバッグ・モードではない が、HFS プログラムの中で以前にロードした唯一の 使用可能コピーが呼び出し元で変更可能なストレージにある場合、以前のコピーは再利用されません。
  2. 変更の始まり指定のファイル名が外部リンクまたは スティッキー・ビット・ファイルを表す場合、プログラムは 呼び出し元の MVS ロード・ライブラリーの検索順序で ロードされます。外部リンクの場合、外部名は、名前が 8 文字以下の場合にのみ使用されます。その他の場合は、呼び出し元は loadhfs サービスからエラーを受け取ります。スティッキー・ビット・プログラムの場合は、ファイル名は 8 文字以下の場合にのみ使用されます。ファイル名が 8 文字より多い場合、プログラムは HFS からロードされ、set-user-ID 属性または set-group-ID 属性を持つスティッキー・ビット・プログラムに対して次の制限があります。

    プログラムが MVS プログラム検索順序で見つかる場合、MVS プログラム名は RACF FACILITY クラスで定義された BPX.STICKYSUG.program_name リソース・プロファイルである必要があります。リソース・プロファイルの定義について詳しくは、 z/OS UNIX System Services 計画ブックを参照してください。この制限に従わない場合、コード xxxxE055 での異常終了 EC6 の原因となります。

    変更の終わり
  3. 呼び出しタスクが WLM エンクレーブにある場合、新規プロセス・イメージ内の結果のタスクは、同一 WLM エンクレーブへ結合されます。これにより、WLM はシステムのアカウンティングおよび管理の目的で、新旧のプロセス・イメージを 1 つの「作業単位」エンティティーとして管理できます。
注: この関数で z/OS UNIX マジック番号サポートを利用するには、 プロセス初期化時に、POSIX(ON) の Language Environment® ランタイム・オプションを設定しておく必要があります。POSIX(OFF) を指定して開始したプロセスでマジック番号サポートを利用しようとすると、何らかの障害が起きることがあります。z/OS UNIX マジック番号の詳細と使用法については、「z/OS UNIX System Services 計画) および「z/OS V2R2.0 UNIX System Services ユーザーズ・ガイド) を参照してください。

戻り値

呼び出しプロセスが新規プロセスで上書きされるので、正常終了の 場合、exec 関数は制御を決して戻しません。

正常に終了しなかった場合、exec 関数は -1 を戻し、errno に以下の値のいずれかを設定します。
エラー・コード
説明
E2BIG
新規プロセスの引数リストと環境リストの 組み合わせ (バイト数) がシステム定義の長さを超えています。システム定義の長さについての詳細は、sysconf() - システム構成オプションの判別を 参照してください。
EACCES
以下の理由のいずれかにより、プロセスには 指定されたファイルを実行するのに適切な許可がありません。
  • プロセスには、path で指定したディレクトリー名を 検索する許可がありません。
  • プロセスには、ファイルを実行するための実行許可がありません。
  • システムはこのタイプのファイルを実行できません。
EFAULT
正しくないアドレスを呼び出しの引数として受け取りました。または ユーザー出口プログラムがチェックされました。

理由コードを調べて、エラーが起きた正確な理由を判別します。理由コード、JRExecParmErr および JRExitRtnError が戻りコードに 付随することがあります。

EINVAL
新規プロセス・イメージ・ファイルには適切な許可が あり、その形式も認知されたものであるが、システムは この形式のファイルの実行をサポートしていません。
ELOOP
ループがシンボリック・リンクに存在しています。path または file 引数の解決で検出された シンボリック・リンクの数が、POSIX_SYMLOOP (limits.h ヘッダー・ファイルに定義 された値) よりも大きい場合、このエラーが発行されます。
ELEMULTITHREAD
exec 関数がマルチスレッド環境から呼び出されました。
EMVSSAF2ERR
実行可能ファイルが set-user-ID または set-group-ID ファイル で、ファイル所有者の UID または GID が RACF® に対して定義されていません。
ENAMETOOLONG
ファイル名の全部または一部が長すぎます。以下の場合に、これが起こる可能性があります。
  • path または file 引数が、PATH_MAX の値を超えています。または、path のエレメントが PATH_MAX を超えています。
  • pathname コンポーネントが NAME_MAX を超えていて 、_POSIX_NO_TRUNC が有効になっています。
  • path 引数に入っている、シンボリック・リンクに置き換わるパス名の ストリングの長さが PATH_MAX を超えています。
PATH_MAX および NAME_MAX の値は、pathconf() で判別されます。
ENOENT
path または file の 1 つ以上の pathname コンポーネントが存在しません。このエラーは、path または file が NULL ストリングの場合にも発行されます。
ENOEXEC
新規プロセス・イメージ・ファイルには適切なアクセス許可 があるが、その形式は認知されていません。execlp() と execvp() を除いて、exec ファミリーの関数のいずれかから この errno が戻されることがあります。
注: さらに、理由コードが errno に加わります。 理由コードについては、「z/OS UNIX System Services メッセージおよびコード」を参照してください。
ENOEXEC の場合、該当する理由コードは以下のとおりです。
理由コード 説明
X'xxxx0C27' ターゲットの HFS ファイルのフォーマット設定が正しく ないため、実行可能ファイルになりません。
X'xxxx0C31' ターゲットの HFS ファイルは、実行システム でサポートされているレベルより高いレベルで作成されています。
ENOMEM
新規プロセスが必要としているメモリーは、オペレーティング・システムで許可されているメモリー よりも大きいです。
ENOTDIR
path または file の ディレクトリー・コンポーネントが実際にはディレクトリーではありません。

CELEBE03
⁄* CELEBE03

   This example runs a program, using the execl() function.

 *⁄
#define _POSIX_SOURCE
#include <stdio.h>
#include <sys⁄wait.h>            ⁄*FIX: used be <wait.h>*⁄
#include <sys⁄types.h>
#include <unistd.h>

main() {
  pid_t pid;
  int status;

  if ((pid = fork()) == 0) {
    execl("⁄bin⁄false", NULL);
    perror("The execl() call must have failed");
    exit(255);
  }
  else {
    wait(&status);
    if (WIFEXITED(status))
      printf("child exited with status of %d¥n", WEXITSTATUS(status));
    else
      puts("child did not exit successfully¥n");
  }
}
出力:
child exited with status of 1

関連情報