在linux中使用c語言編程時,errno是個很有用的動動。他可以把最后一次調用c的方法的錯誤代碼保留。但是如果最后一次成功的調用c的方法,errno不會改變。因此,只有在c語言函數返回值異常時,再檢測errno。
errno會返回一個數字,每個數字代表一個錯誤類型。詳細的可以查看頭文件。/usr/include/asm/errno.h
如何把errno的數字轉換成相應的文字說明?
方式一:可以使用strerrno函數
使用方式如下:
fprintf(stderr,"error in CreateProcess %s, Process ID %d ",strerror(errno),processID)
將錯誤代碼轉換為字符串錯誤信息,可以將該字符串和其它的信息組合輸出到用戶界面。
注:假設processID是一個已經獲取了的整形ID
方式二:使用perror函數
void perror(const char *s)
函數說明
perror ( )用來將上一個函數發生錯誤的原因輸出到標准錯誤(stderr),參數s 所指的字符串會先打印出,后面再加上錯誤原因 字符串。此錯誤原因依照全局變量 errno 的值來決定要輸出的字符串。
另外並不是所有的c函數調用發生的錯誤信息都會修改errno。例如gethostbyname函數。
errno是否是線程安全的?
errno是支持線程安全的,而且,一般而言,編譯器會自動保證errno的安全性。
我們看下相關頭文件 /usr/include/bits/errno.h
會看到如下內容:
# if !defined _LIBC || defined _LIBC_REENTRANT /* When using threads, errno is a per-thread value. */ # define errno (*__errno_location ()) # endif # endif /* !__ASSEMBLER__ */ #endif /* _ERRNO_H */
也就是說,在沒有定義__LIBC或者定義_LIBC_REENTRANT的時候,errno是多線程/進程安全的。
為了檢測一下你編譯器是否定義上述變量,不妨使用下面一個簡單程序。
#include <stdio.h> #include <errno.h> int main( void ) { #ifndef __ASSEMBLER__ printf( "Undefine __ASSEMBLER__/n" ); #else printf( "define __ASSEMBLER__/n" ); #endif #ifndef __LIBC printf( "Undefine __LIBC/n" ); #else printf( "define __LIBC/n" ); #endif #ifndef _LIBC_REENTRANT printf( "Undefine _LIBC_REENTRANT/n" ); #else printf( "define _LIBC_REENTRANT/n" ); #endif return 0; }