execve - システムコールの説明 - Linux コマンド集 一覧表
- 名前
- 書式
- 説明
- 返り値
- エラー
- 準拠
- 注意
- 履歴
- 関連項目
名前
書式
#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
の形式を
しており、新しいプログラムの環境変数として渡される。
argv
と envp
の両方とも 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 で終端される。
関連項目
- Linux Tips 関連記事
- Linux Tips(目次)
- Linux ディストリビューション一覧
- rpm のファイル名にあるi386とかi686とは
- 自分のマシンの情報を調べる
- cron の設定
- ssh の root ログインを禁止する
- ssh を、ユーザ、IPでアクセス制限
- 鍵交換方式によるssh接続
- 鍵交換方式によるssh接続( windowsから )
- 複数ファイル内の文字列を置換して上書き保存する
- あるグループをイニシャルグループとするユーザー一覧出力
- 複数ファイルのファイル名を一括変換する
- 連番ファイルをコマンド一発で作成する
- 中身がランダムなファイルを任意のサイズで作成する
- Linux ユーザーアカウントをロック・アンロックする