- 外殼函數執行一條中斷機器指令(int 0x80),引發處理器從用戶態切換到核心態,并執行系統中斷0x80的中斷矢量所指向的代碼。(在2.6內核及glib 2.3.2之后的版本都支持sysenter指令,進入內核的速度更快)
- 為響應中斷0x80,內核會調用system_call()例程(對于x86-32硬件平臺,位于arch/i386/entry.S)來處理這次中斷,以系統調用編號對存放所有調用服務例程的列表(內核變量sys_call_table)進行索引,發現并調用相應的系統調用服務例程。(在linux中,系統調用服務例程的命名通常會采取sys_xyz()的形式,其中,xyz()正是所論及的系統調用)
- 嵌入式系統C函數庫:uClibc(www.uclibc.org)和dietlibc(www.fefe.de/dietlibc/)
- 確定系統glibc版本:/lib/libc.so.6
- 少數幾個系統函數在調用時從不失敗。例如,getpid()總能成功返回進程的ID,而_exit()總能終止進程。無需對此類系統調用的返回值進行檢測。
- 系統調用返回值為-1表示出錯。
- 系統調用失敗時,將全局整形變量errno設置為一個正值,以標示具體的錯誤。程序應包含<errno.h>,該文件提供了對errno的聲明,以及一組對各種錯誤編號而定義的常量。
- 如果調用系統調用和庫函數成功,errno絕不會被重置為0,故此,該變量值不為0,可能是之前調用失敗造成的。
- 少數系統調用(比如,getpriority())在調用成功后,也會返回-1。要判斷此類系統調用是否發生錯誤,應在調用前將errno設置為0,并在調用之后對其值進行檢測。
- #include<stdio.h>
? ? ? void perror(const char *msg);//打印其msg參數所指向的字符串,緊跟一條與當前errno值對應的消息
- #include<string.h>
? ? ? char * strerror(int errnum);//針對errnum參數中所給定的錯號,返回相應的錯誤字符串。對于無法識別的錯誤編號,返回“Unknown errno? nnn”
- 從錯誤處理的角度來說,可將庫函數劃分為幾類:
? ? (1)某些庫函數返回錯誤信息的方式與系統調用完全相同,返回值-1,拌之以errno號來表示具體的錯誤。
? ? (2)某些庫函數在出錯時返回-1之外的其他值,但仍會設置errno來表明具體的出錯情況。例如,fopen()在出錯時會返回一個NULL指針
? ? (3)還有些函數根本不使用errno