系統呼叫(system call)是作業系統為在使用者態執行的程序與硬體裝置(如cpu、磁碟、印表機等)進行互動提供的一組介面。當使用者程序需要發生系統呼叫時,cpu 通過軟中斷切換到核心態開始執行核心系統呼叫函式。下面介紹linux 下三種發生系統呼叫的方法:
一、通過 glibc 提供的庫函式
舉例來說,我們通過 glibc 提供的chmod 函式來改變檔案 etc/passwd 的屬性為 444:?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include
#include
#include
#include
int main()
在普通使用者下編譯運用,輸出結果為:
chmod failed, errno = 1
上面系統呼叫返回的值為-1,說明系統呼叫失敗,錯誤碼為1,在 /usr/include/asm-generic/errno-base.h 檔案中有如下錯誤**說明:
#define eperm 1 /* operation not permitted */
即無許可權進行該操作,我們以普通使用者許可權是無法修改 /etc/passwd 檔案的屬性的,結果正確。
二、使用 syscall 直接呼叫
使用上面的方法有很多好處,首先你無須知道更多的細節,如 chmod 系統呼叫號,你只需了解 glibc 提供的 api 的原型;其次,該方法具有更好的移植性,你可以很輕鬆將該程式移植到其他平台,或者將 glibc 庫換成其它庫,程式只需做少量改動。
但有點不足是,如果 glibc 沒有封裝某個核心提供的系統呼叫時,我就沒辦法通過上面的方法來呼叫該系統呼叫。如我自己通過編譯核心增加了乙個系統呼叫,這時 glibc 不可能有你新增系統呼叫的封裝 api,此時我們可以利用 glibc 提供的syscall 函式直接呼叫。該函式定義在 unistd.h 標頭檔案中,函式原型如下:
long int syscall (long int sysno, ...)
還以上面修改 /etc/passwd 檔案的屬性為例,這次使用 syscall 直接呼叫:?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include
#include
#include
#include
int main()
在普通使用者下編譯執行,輸出的結果與上例相同。
三、通過 int 指令陷入
如果我們知道系統呼叫的整個過程的話,應該就能知道使用者態程式通過軟中斷指令int 0x80 來陷入核心態(在intel pentium ii 又引入了sysenter指令),引數的傳遞是通過暫存器,eax 傳遞的是系統呼叫號,ebx、ecx、edx、esi和edi 來依次傳遞最多五個引數,當系統呼叫返回時,返回值存放在 eax 中。
仍然以上面的修改檔案屬性為例,將呼叫系統呼叫那段寫成內聯彙編**:?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include
#include
#include
#include
int main()
if
(rc == -1)
fprintf(stderr,
"chmode failed, errno = %d\n"
, errno);
else
printf
(
"success!\n"
);
return
0;
}
如果 eax 暫存器存放的返回值(存放在變數 rc 中)在 -1~-132 之間,就必須要解釋為出錯碼(在/usr/include/asm-generic/errno.h 檔案中定義的最大出錯碼為 132),這時,將錯誤碼寫入 errno 中,置系統呼叫返回值為 -1;否則返回的是 eax 中的值。
上面程式在 32位linux下以普通使用者許可權編譯執行結果與前面兩個相同!
hive三種呼叫方式
一 hive e sql語句 shell命令 適合比較短的sql語句呼叫,優點是可以直接在shell中呼叫 靜音模式 s 在執行hiveql過程中,不在顯示器輸出mr的執行過程 hive s e sql語句 test.txt 將執行結果直接輸入到本地檔案 二 hive f sql.sql shell...
函式的三種呼叫方式
第一種 函式立即呼叫執行模式。這裡面的this指向window function add a,b add this window true 第二種 通過建構函式建立物件,然後呼叫自己的方法 這裡的this指向物件本身 也可說是函式的呼叫者 script function fun varf new f...
RestTemplate 呼叫服務三種方式
1.第一種方式直接使用resttemplate,url固定 public string getproductmsg response return response 2.第二種方式 利用loadbalancerclient通過應用名稱獲取url。再使用resttemplate autowired p...