kazmax - Linux で自宅サーバー

execve - システムコールの説明 - Linux コマンド集 一覧表

  1. 名前
  2. 書式
  3. 説明
  4. 返り値
  5. エラー
  6. 準拠
  7. 注意
  8. 履歴
  9. 関連項目

名前

execve - プログラムを実行する

書式

#include <unistd.h>
int execve(const char * filename , char *const argv [],
char *const envp []);

説明

execve () は、filename によって指定されたプログラムを実行する。 filename は、バイナリ実行形式か、"#! interpreter [arg]" という形式の行で始まるスクリプトでなければならない。 後者の場合、interpreter は適切な実行ファイルのパス名でなければならず、 それ自身がスクリプトであってはならない。そしてそれは interpreter [arg] filename の形で呼び出される。
argv は新しいプログラムに渡される引き数文字列の配列である。 envp は文字列の配列であり、伝統的に key=value の形式を しており、新しいプログラムの環境変数として渡される。 argvenvp の両方とも NULL ポインタで終っている 必要がある。引き数配列と環境変数は呼び出されたプログラムの main 関数を int main(int argc, char *argv[], char *envp[]) のように定義することによってアクセス可能になる。
成功した場合、execve () は返らない。 そして、呼び出し元のプロセスの text, data, bss, スタックは、 読み込まれたプログラムによって上書きされる。 呼び出されたプログラムは、呼び出し元の PID および exec 時クローズ (close-on-exec) の設定されていないすべての ファイル・ディスクリプタを継承する。 呼び出し元プロセスの保留シグナルは解除される。呼び出し元のプログラムで 設定されたシグナル捕獲時の動作はデフォルト動作に戻される。 SIGCHLD シグナルが SIG_IGN に設定されている場合は SIG_DFL にリセット されるかもしれないし、されないかもしれない。
もし元のプログラムが ptrace されていると、execve () が成功した後に そのプログラムに SIGTRAP が送られる。
filename で指定されたプログラムファイルに set-user-ID ビットが 設定されており、呼び出したプロセスが ptrace されていない場合、 呼び出したプロセスの実効 (effective) ユーザ ID は プログラムファイルの所有者 (owner) に変更される。 同様に、プログラムファイルに set-group-ID ビットが設定されていた場合、 呼び出したプロセスの有効グループ ID は プログラムファイルのグループに変更される。
プロセスの実効ユーザ ID は保存 (saved) set-user-ID にコピーされる。 同様に、実効グループ ID は保存 set-group-ID にコピーされる。 このコピーは、set-user-ID / set-group-ID 許可ビットにより発生する 実効 ID の変更後に行われる。
実行ファイルが動的リンクされた a.out 実行形式で、共有ライブラリの スタブを含むものだった場合、実行の開始時に Linux の ダイナミック・リンカ   ld.so (8) が呼び出され、必要な共有ライブラリをメモリに読み込んでリンクを行う。
実行ファイルがダイナミック・リンクされた ELF 実行形式だった場合、 PT_INTERP セグメントに指定されたインタプリタが必要な 共有ライブラリ (shared library) を読み込むのに使用される。 通常使用されるインタプリタは Linux libc version 5 をリンクしたバイナリ の場合には /lib/ld-linux.so.1 が、GNU libc version 2 をリンクした バイナリの場合には /lib/ld-linux.so.2 が使用される。

返り値

成功すると execve () は返らない。エラーの場合は -1 を返し、 errno を適当に設定する。

エラー

E2BIG
環境変数 ( envp )と引き数リスト ( argv )の合計バイト数が大き過ぎる。
EACCES
filename やスクリプトインタプリタ名の構成要素に検索許可 (search permission) が与えられていない ( path_resolution (2)も参照すること)。
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 でマウントされ、ユーザがスーパーユーザでなく、 ファイルに SUID あるいは SGID ビットが設定されている。
EPERM
プロセスがトレースされ、ユーザがスーパーユーザでなく、 ファイルに SUID あるいは SGID ビットが設定されている。
ETXTBSY
実行ファイルを書き込み用にオープンしているプロセスがある。

準拠

SVr4, 4.3BSD, POSIX.1-2001. POSIX.1-2001 には #! 動作についての記述はないが、 他は互換性がある。

注意

SUID プロセスと SGID プロセスは ptrace () できない。
Linux はスクリプトの SUID と SGID ビットを無視する。
ファイルシステムを nosuid でマウントした場合に SUID/SGID 実行ファイルをどの様に扱うかは、 Linux カーネルのバージョンによって異なる: あるバージョンでは、すでに必要な権限を持っている場合を除いて、 その実行を拒否する (そして EPERM を返す)。別のあるバージョンでは SUID/SGID ビットのみを無視し exec ()は成功する。
#! 実行形式のシェル・スクリプトの1行目には最大 127 文字が許されている。

履歴

Unix V6 では exec ()コールの引き数リストは 0 で終端され、 main の引き数リストは -1 で終端されていた。 そのため、 main の引き数リストは、その後の exec ()コールには直接使用できなかった。 Unix V7 以降では、ともに NULL で終端される。

関連項目