exec はUnix系オペレーティングシステムにおける関数群で、関数の引数として渡されたプログラムで動作中の当該プロセスを完全に置換する機能を有する。新たなプロセスを生成するわけではないので、プロセス識別子 (PID) は変化しないが、プロセスの仮想空間上のスタック、ヒープ、データなどは全て新たなものに置換される。
execl、execlp、execv、execvp では新たなプロセスイメージで現在の環境変数を受け継ぐ。
exec を呼び出したときにオープン済みだったファイルは、新たなプロセスイメージとなってもオープンされたままである。これを使って、新たなプロセスイメージの標準ストリーム(stdin、stdout、stderr)を事前に設定する。
MS-DOSにて exec 関数群の1つを使ってプログラムを実行する場合、その実行ファイルのヘッダにある "maximum allocation" がデフォルト値 0xFFFF にセットされているかのようにプログラムをメモリにロードする。EXEHDRユーティリティを使えば、その値を変更できる。しかしそれを行って exec の一種でその実行ファイルを実行しようとすると、コマンドラインから直接起動した場合や spawn 系関数群を使って起動した場合とプログラムの振る舞いが変わってしまうことがある。
Unixシェルの多くにも exec という組み込みコマンドがあり、指定されたプログラムでシェルプロセスを上書きする[1]。この機能は、環境変数などを設定して実際のプログラムを実行するラッパースクリプトによく用いられる。exec を使えば、実際に実行したいプログラムが起動した際にシェルが使用していたリソースを解放することができる[2]。
POSIX標準では unistd.h、DOSやOS/2やWindowsでは process.h に exec 関数群が宣言されている。
int execl(char const *path, char const *arg0, ...);
int execle(char const *path, char const *arg0, ..., char const * const *envp);
int execlp(char const *file, char const *arg0, ...);
int execv(char const *path, char const * const * argv);
int execve(char const *path, char const * const *argv, char const * const *envp);
int execvp(char const *file, char const * const *argv);
実装によっては、関数名のプレフィックスとしてアンダースコアを付けている場合がある(例えば、_execl)。
現代のたいていのUnixにおける実装では、最も汎用的なexecveをシステムコールとし(すなわちexecve(2))、他はそれを呼ぶライブラリ関数(たとえばexec(3))としている。
各関数の名前は exec(execute、すなわち「実行」)を核とし、それに次のような文字がいくつか続く形式である。
- e - 環境変数群へのポインタ配列を明示的に新プロセスイメージに渡す。
- l - コマンドライン引数群を個々に関数の引数として渡す。
- p - file 引数で示された実行ファイルのある場所を PATH という環境変数を使って検索する。
- v - コマンドライン引数群をポインタ配列として関数に渡す。
- path - 新プロセスイメージとして実行すべきファイルのパス名を指定する。
- file - 新プロセスイメージとして実行すべきファイルのパス名を指定する。ただしスラッシュが含まれていない場合は環境変数 PATH を使って実行すべきファイルのパス名を検索する。
- arg0 - 実行ファイルの名前(へのポインタ)。arg0 から新プロセスイメージに渡される引数のポインタが続く。arg0 は通常 path または file と同じである。arg0 を使って自身の位置を知ろうとする実行ファイルもあるが、それが正しいかどうかは保証されない。
- argv - 新プロセスイメージに渡す引数群へのポインタ配列。
- envp - 環境変数群のポインタ配列。
envpの指す配列は、ヌル終端の文字列へのポインタ配列であり、個々の文字列は次の形式である。
name=value
ここで、name は環境変数名、value はその変数の値である。envp 配列の最後には必ずnullがなければならない。envp 自体がnullの場合は、現在の環境変数設定をそのまま受け継ぐ。
通常 exec 関数は現在のプロセスを置換するので、元々それを呼び出したプロセスイメージに戻り値を返すことはできない。プロセスには終了ステータスがあるが、それを受け取るのは親プロセスである。
exec 関数が呼び出したプロセスに戻るのは、エラーが発生したときであり、戻り値は -1 で、errno(英語版) には以下のような値が設定される。
名前 |
意味
|
E2BIG |
引数リストがシステムの制限を越えている。
|
EACCES |
指定されたファイルが実行できないファイルである(あるいはロックされている)。
|
ENOENT |
指定されたファイルまたはパス名が存在しない。
|
ENOMEM |
新たなプロセスイメージを実行するためのメモリが足りない。
|