execve() - Unix、Linux系統呼叫 - 技術教學
Tutorials Point


  Unix入門
  Unix Shell程式設計
  高階Unix
  Unix有用參考資料
  Unix有用資源
  精選閱讀

版權所有 © 2014 tutorialspoint



  首頁     參考資料     討論論壇     關於TP  

execve() - Unix、Linux系統呼叫


previous next AddThis Social Bookmark Button

廣告

名稱

execve - 執行程式

概要

#include <unistd.h> 

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

描述

execve() 執行指向filename 的程式。filename必須是二進位制可執行檔案,或者是一個以“#! interpreter [arg]”形式的行開頭的指令碼。在後一種情況下,直譯器必須是可執行檔案的有效路徑名,它本身不是指令碼,將被呼叫為interpreter [arg] filename

argv是傳遞給新程式的引數字串陣列。envp是字串陣列,通常為key=value形式,作為環境傳遞給新程式。argvenvp都必須以空指標結尾。被呼叫程式的main函式可以訪問引數向量和環境,當它定義為int main(int argc, char *argv[], char *envp[])時。

execve() 成功時不返回,呼叫程序的文字、資料、bss和堆疊將被載入的程式覆蓋。被呼叫的程式繼承呼叫程序的PID,以及任何未設定為close-on-exec的開啟檔案描述符。呼叫程序上掛起的訊號將被清除。任何設定為被呼叫程序捕獲的訊號都將重置為其預設行為。SIGCHLD訊號(當設定為SIG_IGN時)可能重置為SIG_DFL,也可能不重置。

如果當前程式正在被ptrace跟蹤,則成功執行execve()後,將向其傳送SIGTRAP

如果filename指向的程式檔案中設定了set-user-ID位,並且呼叫程序沒有被ptrace跟蹤,則呼叫程序的有效使用者ID將更改為程式檔案所有者的有效使用者ID。類似地,當程式檔案的set-group-ID位被設定時,呼叫程序的有效組ID將設定為程式檔案的組。

程序的有效使用者ID被複制到已儲存的set-user-ID;類似地,有效組ID被複制到已儲存的set-group-ID。此複製發生在由於set-user-ID和set-group-ID許可權位而發生的任何有效ID更改之後。

如果可執行檔案是包含共享庫存根的a.out動態連結二進位制可執行檔案,則在執行開始時呼叫Linux動態連結器ld.so(8)將所需的共享庫載入到記憶體中,並將其與可執行檔案連結。

如果可執行檔案是動態連結的ELF可執行檔案,則PT_INTERP段中命名的直譯器用於載入所需的共享庫。對於與Linux libc版本5連結的二進位制檔案,此直譯器通常為/lib/ld-linux.so.1,對於與GNU libc版本2連結的二進位制檔案,此直譯器通常為/lib/ld-linux.so.2

返回值

成功時,execve()不返回,錯誤時返回-1,並適當地設定errno

錯誤

錯誤程式碼描述
E2BIG 環境 (envp) 和引數列表 (argv) 中的總位元組數太大。
EACCES filename路徑字首的元件或指令碼直譯器名稱的搜尋許可權被拒絕。(另見path_resolution(2)。)
EACCES 檔案或指令碼直譯器不是普通檔案。
EACCES 對檔案或指令碼或ELF直譯器的執行許可權被拒絕。
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的結果在Linux核心版本之間有所不同:有些會在這樣做會賦予使用者她之前沒有的許可權時拒絕執行SUID/SGID可執行檔案(並返回EPERM),有些只會忽略SUID/SGID位併成功exec()。

#!可執行shell指令碼的第一行允許的最大行長為127個字元。

歷史

在Unix V6中,exec()呼叫的引數列表以0結尾,而main的引數列表以-1結尾。因此,此引數列表不能直接用於進一步的exec()呼叫。從Unix V7開始,兩者都是NULL。

參見



previous next Printer Friendly

廣告


  

廣告



廣告