天天看點

execve - 執行程式

#include <unistd.h>

int execve (const char *filename, char *const argv [], char *const envp[]);

execve() 執行 filename 指出的 程式. filename 必須 是二進制可執行檔案, 或者 以 "#! interpreter [arg]" 行 開始的 腳本檔案. 後者的 interpreter 必須是 某個 可執行檔案 的 有效 路徑, 這個 可執行檔案 自身不能是 腳本程式, 調用 形式 是 "interpreter [arg] filename".

execve() 調用 成功 後 不會 傳回, 其 程序 的 正文(text), 資料(data), bss 和 堆棧(stack) 段 被 調入程式 覆寫. 調入程式 繼承了 調用程式 的 PID 和所有 打開的 檔案描述符, 他們 不會 因為 exec 過程 而 關閉. 父程序 的 未決 信号被 清除. 所有 被 調用程序 設定過 的 信号 重置為 預設行為.

如果 目前程式 正在 被 ptrace 跟蹤, 成功的 調用 execve() 後 将 收到一個 SIGTRAP 信号.

如果 可執行檔案 是 動态連接配接 的 a.out 二進制程式, 含有 共享庫 的 stub, 開始 執行 程式 的 時候, Linux 動态 連接配接器(linker) ld.so(8) 把 所需的 共享庫 調入 核心, 并且 和 程式 相連.

如果 可執行檔案 是 動态連接配接 的 ELF 二進制程式, 定義在 PT_INTERP 字段 的解釋器(interpreter) 調入 所需的 共享庫. 連接配接 libc5 的 程式 的 典型 解釋器 是 /lib/ld-linux.so.1, 而 連接配接 GNU libc2 (libc6) 的 程式 則為 /lib/ld-linux.so.2.

調用成功 的 時候 execve() 不會 傳回, 調用失敗 時 傳回 -1, 并 設定 errno 為 相應的 值.

<dl></dl>

<dt>EACCES</dt>

<dd>檔案 或 腳本解釋器 不正确.</dd>

<dd>沒有 檔案 或 腳本解釋器 的 執行 權限.</dd>

<dd>檔案系統 挂載(mount) 為 noexec.</dd>

<dt>EPERM</dt>

<dd>檔案系統 挂載為 nosuid, 使用者 不是 超級使用者, 以及 檔案 設定了 SUID 或 SGID 位.</dd>

<dd>程序 正 被跟蹤, 使用者 不是 超級使用者, 以及 檔案 設定了 SUID 或 SGID 位.</dd>

<dt>E2BIG</dt>

<dd>參數清單 過長.</dd>

<dt>ENOEXEC</dt>

<dd>可執行檔案 的 檔案格式 無法 識别, 誤用在 不同的 體系結構, 或者 其他 格式錯誤 導緻 程式 無法 執行.</dd>

<dt>EFAULT</dt>

<dd></dd>

filename 指針 超出 可通路 的 位址空間.

<dt>ENAMETOOLONG</dt>

filename 太長.

<dt>ENOENT</dt>

filename , 腳本解釋器, 或 ELF 解釋器 不存在.

<dt>ENOMEM</dt>

<dd>核心 空間 不足.</dd>

<dt>ENOTDIR</dt>

<dd>在 filename , 腳本解釋器 或 ELF 解釋器 的 字首 路徑 中, 某些 成員 不是 目錄.</dd>

<dd>在 filename 或 腳本解釋器 的 字首 路徑 中, 對 某些 目錄 沒有 通路許可.</dd>

<dt>ELOOP</dt>

<dd>解析 filename , 腳本解釋器 或 ELF 解釋器 時 遇到 過多的 符号連接配接.</dd>

<dt>ETXTBUSY</dt>

<dd>可執行檔案 被 一個 或 多個 程序 以 寫方式 打開.</dd>

<dt>EIO</dt>

<dd>發生 I/O 錯誤.</dd>

<dt>ENFILE</dt>

<dd>達到 系統 定義的 同時打開檔案數 限制.</dd>

<dt>EMFILE</dt>

<dd>程序 打開了 最大數量 的 檔案.</dd>

<dt>EINVAL</dt>

<dd>該 ELF 可執行檔案 擁有 多個 PT_INTERP 字段 (就是說, 試圖 定義 多個 解釋器).</dd>

<dt>EISDIR</dt>

<dd>ELF 解釋器 是 目錄.</dd>

<dt>ELIBBAD</dt>

<dd>無法 識别 ELF 解釋器 的 格式.</dd>

SVr4, SVID, X/OPEN, BSD 4.3. POSIX 沒有 對 #! 行為 的 文檔, 但有 其他的相容 形式. SVr4 記錄了 額外的 錯誤情況 EAGAIN, EINTR, ELIBACC, ENOLINK, EMULTIHOP; POSIX 沒有 關于 ETXTBSY, EPERM, EFAULT, ELOOP, EIO, ENFILE, EMFILE, EINVAL, EISDIR 或 ELIBBAD 錯誤情況 的 文檔.

SUID and SGID processes can not be ptrace()d SUID or SGID.

在 #! 格式的 shell 可執行腳本 中, 第一行 的 長度 不得 超過 127 位元組.

Linux 忽略 腳本程式 的 SUID 和 SGID 位. 

繼續閱讀