execによるプロセス生成
実行中のプロセスを新しいプロセスで置き換える.したがって新しいプロセスのPIDやniceなどはexecを実行したプロセスと同じである.あと,ファイルディスクリプタなどもexec元がオープンしていれば,新しいプロセスでもオープンされている.ディレクトリストリームはクローズされるらしい.execではshell経由での起動ではないので,shellの展開機能は使用できないが,shell起動のオーバーヘッドはない.
私のシステムではman execとすると,5つの関数について表示される.
#include <unistd.h> extern char **environ; int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg , ..., char * const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]);そしてこれらは
#include <unistd.h> int execve(const char *filename, char *const argv [], char *const envp[]);のフロントエンドらしい.以上の関数について簡単にまとめる.
- 実行するファイルの条件
- バイナリ形式か,#!インタプリタのパスで始まるファイルでなければならない.
- 実行するプログラムの指定
- 引数にpathがある関数は引数で指定したプログラムを起動する.関数名がpで終る関数は引数fileでしていしたプログラムを環境変数PATHから検索する.
- 引数の指定
- 関数名がexeclで始まる関数は引数arg,...で新しいプログラムの引数をそれぞれ別々の文字列として指定する.関数名がexecvで始まる関数は引数argv[]で引数の文字列の配列を指定する.argv[]の最後の要素はNULLでなければならない.
- 環境変数の渡し方
- グローバル変数environに格納して渡す.また,関数名がeで終る関数は引数envp[]で渡す.envp[]の最後の要素はNULLでなければならない.呼び出されるプログラムはmain(int argc, char *argv[], char *envp[])とすることでenvpを使用できる.
- 返り値
- 成功した場合返らない.失敗したときは-1を返してerrnoを設定する.
自分が受け取った引数をちょっといじってlsに渡すプログラムを作ってみた.
実行.
Call ls a.out exec-ls.c exec-ls.c~exec族は呼び出しに成功すると返らない(というかexec族を呼び出したプロセスがそのままexecで起動されたプロセスと置き換わるので返りようがない)のでexecvp後のfprintfは実行されない.
exec族に渡す引数と環境の配列には上限があるらしい.それはARG_MAXで設定されているらしい.
grep "ARG_MAX" /usr/include/linux/limits.h #define ARG_MAX 131072 /* # bytes of args + environ for exec() */POSIXではARG_MAXの値は最小4096バイトと規定しているらしい.

