other versions
other languages
other sections
EXECVE(2) | Linux Programmer's Manual | EXECVE(2) |
名前¶
execve - プログラムを実行する書式¶
#include <unistd.h>説明¶
execve() は、filename によって指定されたプログラムを実行する。 filename は、バイナリ実行形式か、 以下の形式の行で始まるスクリプトでなければならない。#! interpreter [optional-arg]
int main(int argc, char *argv[], char *envp[])
- *
- 捕捉されたシグナルの処理方法 (disposition) は デフォルト動作にリセットされる ( signal(7))。
- *
- 代替シグナルスタックはどれも保持されない ( sigaltstack(2))。
- *
- メモリマッピングは保持されない ( mmap(2))。
- *
- 付加された (attached) System V 共有メモリセグメントは分離される ( shmat(2))。
- *
- POSIX 共有メモリ領域はマッピングを解除される ( shm_open(3))。
- *
- オープンされた POSIX メッセージキューディスクリプタはクローズされる ( mq_overview(7))。
- *
- オープンされた POSIX 名前付きセマフォはいずれもクローズされる ( sem_overview(7))。
- *
- POSIX タイマは保持されない ( timer_create(2))。
- *
- オープンされたディレクトリストリームはいずれもクローズされる ( opendir(3))。
- *
- メモリロックは保持されない ( mlock(2), mlockall(2))。
- *
- 終了 (exit) ハンドラは保持されない ( atexit(3), on_exit(3))。
- *
- 浮動小数点関連の環境はデフォルトにリセットされる ( fenv(3) 参照)。
- *
- set-user-ID か set-group-ID されたプログラムが実行されている場合、 prctl(2) の PR_SET_DUMPABLE フラグはクリアされる。それ以外の場合、このフラグはセットされる。
- *
- prctl(2) の PR_SET_KEEPCAPS フラグはクリアされる。
- *
- プロセス名は新しい実行ファイルの名前にリセットされる。 プロセス名は prctl(2) の PR_SET_NAME で設定でき、 ps -o comm で表示できる。
- *
- 終了シグナル (termination signal) は SIGCHLD にリセットされる ( clone(2) 参照)。
- *
- 呼び出し元スレッド以外の全てのスレッドは execve() 中に破棄される。 mutex、条件変数、その他の pthread オブジェクトは保持されない。
- *
- setlocale(LC_ALL, "C") 相当の処理がプログラム開始時に実行される。
- *
- POSIX.1-2001 は、動作が無視かデフォルトに設定されている全てのシグナル の処理方法は変更せずそのままにする、と規定している。 但し、POSIX.1-2001 には一つ例外があり、 SIGCHLD が無視になっている場合、 その処理方法を変更せずにそのままにするか、デフォルト動作にリセットするかは 実装依存となっている。 Linux では前者 (変更しない) となっている。
- *
- 完了していない非同期 I/O 操作はキャンセルされる ( aio_read(3), aio_write(3))。
- *
- execve(2) 時のケーパビリティの扱いについては、 capabilities(7) を参照。
- *
- デフォルトでは、ファイルディスクリプタは execve() を行った後でもオープンされたままである。 close-on-exec の印が付いているファイルディスクリプタはクローズされる。 fcntl(2) の FD_CLOEXEC の説明を参照。 (ファイルディスクリプタがクローズされると、このプロセスが ファイルディスクリプタに対応するファイルに対して獲得していた レコードのロックが全て解放されることになる。) POSIX.1-2001 では、 ファイルディスクリプタ 0, 1, 2 が execve() 成功後にどこかでクローズされ、かつ 実行されるファイルに set-user_ID か set-group_ID の許可ビットが セットされていてプロセスが特権を獲得した場合、 システムは何らかのファイルをオープンする際に これらの番号のディスクリプタのどれかを使うことがある、 とされている。 原則として、移植性が必要なプログラムでは、 特権の有無に関わらず、 execve() の前後でこれら 3つのファイルディスクリプタがクローズされたままで あることを前提にすることはできない。
インタプリタ・スクリプト¶
インタプリタ・スクリプトとは、実行許可が有効になっていて、 最初の行が以下の形になっているテキストファイルのことである。#! interpreter [optional-arg]
interpreter [optional-arg] filename arg...
引き数と環境変数の合計サイズの上限¶
ほとんどの UNIX の実装は、新しいプログラムに渡すことができる コマンドライン引き数 ( argv) と環境変数 (envp) の文字列群の合計サイズに何らかの上限を設けている。 POSIX.1 は、 ARG_MAX 定数を使ってこの上限を決める実装を認めている ( ARG_MAX は <limits.h> で定義されるか、実行時に sysconf(_SC_ARG_MAX) の呼び出しで入手できるかのいずれかである)。返り値¶
成功すると execve() は返らない。エラーの場合は -1 を返し、 errno を適切に設定する。エラー¶
- E2BIG
- 環境変数 (envp) と引き数リスト ( argv) の合計バイト数が大き過ぎる。
- EACCES
- filename やスクリプトインタプリタ名の構成要素に検索許可 (search permission) が与えられていない ( path_resolution(7) も参照すること)。
- EACCES
- ファイルもしくはスクリプトのインタプリタが通常ファイル (regular file) でない。
- EACCES
- ファイルやスクリプトや ELF インタプリタに 実行許可 (execute permission) が与えられていない。
- EACCES
- ファイル・システムが noexec でマウントされている。
- EFAULT
- filename がアクセス可能なアドレス空間の外を指している。
- EINVAL
- ELF 実行形式で複数の PT_INTERP セグメントが存在する。 (すなわち複数のインタプリタを指定した。)
- EIO
- I/O エラーが発生した。
- EISDIR
- ELF インタプリタがディレクトリだった。
- ELIBBAD
- ELF インタプリタが理解できるフォーマットでなかった。
- ELOOP
- filename やスクリプトや ELF のインタプリタを解決する際に遭遇した シンボリック・リンクが多過ぎる。
- EMFILE
- そのプロセスがオープンできるファイル数の上限まで既にオープンしている。
- ENAMETOOLONG
- filename が長過ぎる。
- ENFILE
- オープンされたファイルの総数がシステム全体の上限に達していた。
- ENOENT
- ファイル filename かスクリプトや ELF のインタプリタが存在しない。
- ENOEXEC
- 実行ファイルが理解できない形式であるか、違うアーキテクチャのものか、 その他のフォーマット・エラーにより実行ができなかった。
- ENOMEM
- カーネルに十分なメモリがない。
- ENOTDIR
- filename やスクリプトや ELF のインタプリタの構成要素がディレクトリでない。
- EPERM
- ファイル・システムが nosuid でマウントされ、ユーザがスーパーユーザでなく、 ファイルに set-user-ID あるいは set-group-ID ビットが設定されている。
- EPERM
- プロセスがトレースされ、ユーザがスーパーユーザでなく、 ファイルに set-user-ID あるいは set-group-ID ビットが設定されている。
- ETXTBSY
- 実行ファイルを書き込み用にオープンしているプロセスがある。
準拠¶
SVr4, 4.3BSD, POSIX.1-2001. POSIX.1-2001 には #! 動作についての記述はないが、 他は互換性がある。注意¶
set-user-id プロセスと set-group-ID プロセスは ptrace(2) できない。歴史¶
UNIX V6 では exec() コールの引き数リストは 0 で終端され、 main の引き数リストは -1 で終端されていた。 そのため、 main の引き数リストは、その後の exec() コールには直接使用できなかった。 UNIX V7 以降では、ともに NULL で終端される。例¶
このプログラムは、以下の二つ目のプログラムから実行するためのものである。 コマンドラインを 1行に 1個ずつ表示するだけのプログラムである。/* myecho.c */ #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int j; for (j = 0; j < argc; j++) printf("argv[%d]: %s\n", j, argv[j]); exit(EXIT_SUCCESS); }
/* execve.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { char *newargv[] = { NULL, "hello", "world", NULL }; char *newenviron[] = { NULL }; if (argc != 2) { fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]); exit(EXIT_FAILURE); } newargv[0] = argv[1]; execve(argv[1], newargv, newenviron); perror("execve"); /* execve() only returns on error */ exit(EXIT_FAILURE); }
$ cc myecho.c -o myecho $ cc execve.c -o execve $ ./execve ./myecho argv[0]: ./myecho argv[1]: hello argv[2]: world
$ cat > script.sh #! ./myecho script-arg ^D $ chmod +x script.sh
$ ./execve ./script.sh argv[0]: ./myecho argv[1]: script-arg argv[2]: ./script.sh argv[3]: hello argv[4]: world
関連項目¶
chmod(2), fork(2), ptrace(2), execl(3), fexecve(3), getopt(3), credentials(7), environ(7), path_resolution(7), ld.so(8)この文書について¶
この man ページは Linux man-pages プロジェクトのリリース 3.41 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2012-05-04 | Linux |