在Linux中,errno
是一個非常重要的全域性變數,用於儲存系統呼叫的錯誤程式碼。
以下是關於errno
的詳細解釋:
定義和用途:
1.errno
是一個預定義的外部整型(int)變數,通常包含在<errno.h>
標頭檔案中。
2.當系統呼叫或庫函式發生錯誤時,它們通常會設定errno
以指示發生了哪種錯誤。
3.errno
的值僅在函式失敗時才會被設定,並且會覆蓋之前的值。
4.透過檢查errno
的值,程式設計師可以確定發生了什麼錯誤,並據此編寫適當的錯誤處理程式碼。
在 /usr/include/asm-generic/errno-base.h 中記錄著errno對應的錯誤資訊
4#define EPERM 1 /* Operation not permitted */ 5 #define ENOENT 2 /* No such file or directory */ 6 #define ESRCH 3 /* No such process */ 7 #define EINTR 4 /* Interrupted system call */ 8 #define EIO 5 /* I/O error */ 9 #define ENXIO 6 /* No such device or address */ 10 #define E2BIG 7 /* Argument list too long */ 11 #define ENOEXEC 8 /* Exec format error */ 12 #define EBADF 9 /* Bad file number */ 13 #define ECHILD 10 /* No child processes */ 14 #define EAGAIN 11 /* Try again */ 15 #define ENOMEM 12 /* Out of memory */ 16 #define EACCES 13 /* Permission denied */ 17 #define EFAULT 14 /* Bad address */ 18 #define ENOTBLK 15 /* Block device required */ 19 #define EBUSY 16 /* Device or resource busy */ 20 #define EEXIST 17 /* File exists */ 21 #define EXDEV 18 /* Cross-device link */ 22 #define ENODEV 19 /* No such device */ 23 #define ENOTDIR 20 /* Not a directory */ 24 #define EISDIR 21 /* Is a directory */ 25 #define EINVAL 22 /* Invalid argument */ 26 #define ENFILE 23 /* File table overflow */ 27 #define EMFILE 24 /* Too many open files */ 28 #define ENOTTY 25 /* Not a typewriter */ 29 #define ETXTBSY 26 /* Text file busy */ 30 #define EFBIG 27 /* File too large */ 31 #define ENOSPC 28 /* No space left on device */ 32 #define ESPIPE 29 /* Illegal seek */
使用示例:
- 在C程式中,如果某個系統呼叫或庫函式呼叫失敗,並且你想檢查失敗的原因,你應該在呼叫後立即檢查
errno
的值。 - 需要注意的是,由於
errno
的值可能會被後續的系統呼叫或庫函式呼叫覆蓋,所以你應該在函式失敗後立即檢查它的值。
1 #include<stdio.h> 2 #include <errno.h> 3 int main() 4 { 5 FILE*fp; 6 fp = fopen("temp","r"); 7 if(fp == NULL) 8 { 9 fprintf(stderr,"fopen() failed! errno = %d\n",errno); 10 exit(1); 11 } 12 puts("OK!"); 13 exit(0); 14 }
示例中我們試圖以只讀方式開啟一個不存在的檔案。
執行結果:
fopen() failed! errno = 2
可以看到errno = 2,對應上面的為
#define ENOENT 2 /* No such file or directory */
直接使用errno存在一個缺陷,因為errno是一個整型數值,需要查詢才能確定錯誤資訊,我們可做如下改進:使用perror()
示例如下:
1 #include<stdio.h> 2 #include <errno.h> 3 int main() 4 { 5 FILE*fp; 6 fp = fopen("temp","r"); 7 if(fp == NULL) 8 { 9 //fprintf(stderr,"fopen() failed! errno = %d\n",errno); 10 perror("fopen() failed!"); 11 exit(1); 12 } 13 puts("OK!"); 14 exit(0); 15 }
這樣可以直接輸出錯誤資訊,輸出結果如下:
fopen() failed!: No such file or directory
或者使用strerror
示例如下:
1 #include<stdio.h> 2 #include <errno.h> 3 #include <string.h> 4 5 int main() 6 { 7 FILE*fp; 8 fp = fopen("temp","r"); 9 if(fp == NULL) 10 { 11 //fprintf(stderr,"fopen() failed! errno = %d\n",errno); 12 //perror("fopen() failed!"); 13 fprintf(stderr,"fopen() failed! errno = %s\n",strerror(errno)); 14 exit(1); 15 } 16 puts("OK!"); 17 exit(0); 18 }
執行結果:
fopen() failed! errno = No such file or directory