系統呼叫(system call)是作業系統為在使用者態執行的程序與硬體裝置(如cpu、磁碟、印表機等)進行互動提供的一組介面。當使用者程序需要發生系統呼叫時,cpu 通過軟中斷切換到核心態開始執行核心系統呼叫函式。下面介紹linux 下三種發生系統呼叫的方法:
舉例來說,我們通過 glibc 提供的chmod
函式來改變檔案etc/passwd
的屬性為 444:
#include#include
#include
#include
intmain
()
在普通使用者下編譯運用,輸出結果為:
chmod failed, errno = 1
上面系統呼叫返回的值為-1,說明系統呼叫失敗,錯誤碼為1,在/usr/include/asm-generic/errno-base.h
檔案中有如下錯誤**說明:
#define eperm 1 /* operation not permitted */
即無許可權進行該操作,我們以普通使用者許可權是無法修改 /etc/passwd 檔案的屬性的,結果正確。
使用上面的方法有很多好處,首先你無須知道更多的細節,如 chmod 系統呼叫號,你只需了解 glibc 提供的 api 的原型;其次,該方法具有更好的移植性,你可以很輕鬆將該程式移植到其他平台,或者將 glibc 庫換成其它庫,程式只需做少量改動。
但有點不足是,如果 glibc 沒有封裝某個核心提供的系統呼叫時,我就沒辦法通過上面的方法來呼叫該系統呼叫。如我自己通過編譯核心增加了乙個系統呼叫,這時 glibc 不可能有你新增系統呼叫的封裝 api,此時我們可以利用 glibc 提供的syscall
函式直接呼叫。該函式定義在unistd.h
標頭檔案中,函式原型如下:
longintsyscall
(long
intsysno
,...)
還以上面修改 /etc/passwd 檔案的屬性為例,這次使用 syscall 直接呼叫:
#include#include
#include
#include
intmain
()
在普通使用者下編譯執行,輸出的結果與上例相同。
如果我們知道系統呼叫的整個過程的話,應該就能知道使用者態程式通過軟中斷指令int 0x80
來陷入核心態(在intel pentium ii 又引入了sysenter
指令),引數的傳遞是通過暫存器,eax 傳遞的是系統呼叫號,ebx、ecx、edx、esi和edi 來依次傳遞最多五個引數,當系統呼叫返回時,返回值存放在 eax 中。
仍然以上面的修改檔案屬性為例,將呼叫系統呼叫那段寫成內聯彙編**:
#include#include
#include
#include
intmain
()if(rc
==-1)
fprintf
(stderr
,"chmode failed, errno = %d\n"
,errno
);else
printf
("success!\n"
);return0;
}
如果 eax 暫存器存放的返回值(存放在變數 rc 中)在 -1~-132 之間,就必須要解釋為出錯碼(在/usr/include/asm-generic/errno.h
檔案中定義的最大出錯碼為 132),這時,將錯誤碼寫入 errno 中,置系統呼叫返回值為 -1;否則返回的是 eax 中的值。
上面程式在 32位linux下以普通使用者許可權編譯執行結果與前面兩個相同!
Linux下使用系統呼叫的三種方法
系統呼叫 system call 是作業系統為在使用者執行的程序與硬體裝置 如cpu,磁碟,印表機等 進行互動提供的一組介面。當程序需要發生系統呼叫時,cpu通過軟中斷切換到核心態開始執行核心系統呼叫函式。1.通過 glibc 提供的庫函式 舉例來說,我們通過 glibc 提供的chmod 函式來改...
Linux系統安裝軟體的三種方法
rpm 是linux的一種軟體包名稱,以.rmp結尾,安裝的時候語法為 rpm ivh。rpm包的安裝有個很大的缺點就是檔案的關聯性太大,有時裝乙個軟體要安裝很多其他的軟體包,很麻煩。所以為此redhat小紅帽開發了yum安裝方法,他可以徹底解決這個關聯性的問題,很方便,只要配置兩個檔案即可安裝,安...
LabVIEW 呼叫 Python的三種方法
1.labpython 屬於openg庫 免費 此方法根據論壇反饋,不是特別好使用,因此不做敘述 我也沒用過 2.labview 2018 system inte ce 屬於labview 2018自帶介面 免費 labview 2018提供了3個python函式,如上圖所示 分別是open pyt...