1. 程式人生 > >markman101---神即是道 道法自然 如來

markman101---神即是道 道法自然 如來

#ifndef _I386_ERRNO_H
#define _I386_ERRNO_H
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */

#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */

#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */

#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#define ECANCELED 125 /* Operation Cancelled */
#define ENOKEY 126 /* Required key not available */
#define EKEYEXPIRED 127 /* Key has expired */
#define EKEYREVOKED 128 /* Key has been revoked */
#define EKEYREJECTED 129 /* Key was rejected by service */

#endif









許多GNU
C庫中的函式都監測和報告錯誤的情況,而且有時候你的程式需要檢查它們以得到錯誤的情形。比如說:你打開了一個輸入檔案,你必須檢查這個檔案是否正確的打開了,而且在你呼叫一個庫函數出錯的時候打印出錯資訊或採取其他的措施。

這一章描述錯誤報告功能是怎麼工作的。要使用這個功能的話,你的程式必須包含標頭檔案“errno.h”。


錯誤的檢查

許多庫函式返回一個特殊的值說明他們的失敗。這個特殊值典型的有-1、一個空指標、或者一個定義得像EOF這樣的常量。但是這樣的返回只是告訴你錯誤發生了。要找到這是什麼樣的錯誤,你必須檢視變數errno中存放的錯誤程式碼。這個變數在標頭檔案“errno.h”中定義。



變數: volatile int errno

變數errno包括了系統的錯誤號,你可以改變它的值。

當errno描述成volatile,它將可能被一個訊號處理者同步的改變;參見《定義訊號處理者》。一個寫好的訊號處理者能夠存入或恢復errno的值,所以處理你編寫訊號處理者的時候之外一般你基本不用擔心這個。

程式器啟動的似乎errno的初始值是零。許多庫函式在遭遇一些確定的錯誤以後將保證設定它為某個確定的非零值。當這些函式執行成功的時候它將不會修改 errno的值;因此,當一個成功的呼叫以後errno的值不必要是零,而且你不能用errno來判斷一次呼叫是否失敗了。正確的做法是檢查每個函式報道的結果,如果呼叫失敗了,再來檢查errno。

一些庫函式會把errno設定為一個非零值來作為呼叫一個其他的可能出錯的庫函式的返回結果。你必須假定任何庫函式都可能改變errno。

相容性提示:ANSI
C把errno指定為一個比變數強的“可變左值”,允許它像巨集一樣實現。比如說:它可以擴充套件得包括一個函式呼叫:就像*
_errno()。實際上,那就是它自己在GNU系統上的本質。在非GNU系統上的GNU庫中,就算不論怎樣也是這樣的。

這裡有一些庫函式,就像sqrt和atan,在萬一出錯的時候也能返回一個合法的值。對於這樣的函式,如果你要檢查是否發生了錯誤,推薦的手段就是在呼叫函式之前將errno設定為0,然後函式返回以後再檢查它的值。




所有的錯誤程式碼都有一個符號名字;它們都是在“errno.h”中定義的巨集。這些名字都由一個“E”開始後面跟著一個大寫字母或數字;你必須把這些名字考慮成保留字,參見《保留字》

所有的錯誤程式碼都是互不相同的正整數。(比如:既然這些值是不同的,你就可以把它們用作switch結構的標籤。)你不能對這些有特定值的符號常量假定其他的值。

errno的值並不僅限於這些巨集,所以有些庫函式在其他情形下會返回一些其他的錯誤碼。當然手冊列出的這些特定的庫函式的這些特定的值是有另外的含義的


在非GNU的系統中,將一個無效的指標作為引數許多系統呼叫將返回EFAULT。
顯然這結果會在在你的程式有bug的時候發生,而且該情況不會在GNU系統中發生,為節省篇幅,我們就不在進行單獨的函式的描述的時候提及EFAULT。
錯誤程式碼



所有的錯誤程式碼都在頭文見“errno.h”中定義,它們所有的展開以後都是整數常量。這裡的有些錯誤在GNU的系統中不會發生,但是在其他系統中使用GNU庫的時候會出現。



巨集: int EPERM

操作不被允許;只有檔案(或其他資源)或程序的主人才能有特權作這個操作。



巨集: int ENOENT


沒有這樣的檔案或目錄。這是一個普通檔案上的“檔案不存在”錯誤,檔案不在提到的目錄表中。



巨集: int ESRCH


沒有程序符合指定的程序號。



巨集: int EINTR

函式呼叫中斷;一個非同步訊號出現而且阻止呼叫的執行。當出現這樣的情況時,你必須試著重新呼叫。

你可以選擇一個函式來在處理完訊號以後恢復,這樣比出現RINTR的失敗要好,《簡單的訊號中斷》。



巨集: int EIO


輸入輸出錯誤;通常是物理的讀寫錯。



巨集: int ENXIO

沒有這樣的裝置或地址。通常,這意味著一個檔案描述的裝置並沒有正確安裝,系統不能為它找到正確的裝置驅動程式。



巨集: int E2BIG

引數列表太長;當使用exec函式中的某一個執行新程式時傳遞的引數佔用了太多的記憶體空間。這種情況不會出現在GNU的系統中。



巨集: int ENOEXEC

無效的可執行檔案格式。這種情況由exec函式檢測出來;《執行一個檔案》


巨集: int EBADF


錯誤的檔案描述符;比如說,在一個已經關閉的檔案描述符上作IO操作或讀取一個寫開啟的描述符(反之亦然)。



巨集: int ECHILD

沒有子程序。這個錯誤出現在想要作操縱子程序的操作的時候,已經沒有任何可以操縱的子程序了。



巨集: int EDEADLK

死鎖避免;分配系統資源的時候將可能導致死鎖的情況,比如說,參見《檔案鎖定》



巨集: int ENOMEM


沒有可用的記憶體。系統不能分配更多的虛擬記憶體因為它的容量已經滿了。



巨集: int EACCES

許可權被封鎖;檔案的許可權不允許所嘗試的操作。



巨集: int EFAULT


錯誤地址;檢測到一個無效指標。



巨集: int ENOTBLK


給出的這種方式需要塊特殊檔案而這個檔案不是。比如說:試圖把一個普通檔案當檔案系統掛在unix系統中將出現這個錯誤。



巨集: int EBUSY


資源忙;一個正在使用的系統資源不能被共享。比如說,你需要刪除的檔案是一個掛在系統中的檔案系統,你將得到這個錯誤。



巨集: int EEXIST


檔案已存在;應該對新檔案操作的時候這個檔案已經明確存在於目錄表中。



巨集: int EXDEV


嘗試跨檔案系統作檔案連結。



巨集: int ENODEV


在需要進去日指明裝置類別的函式中給出了錯誤的裝置型別。



巨集: int ENOTDIR

在只能處理目錄的時候給出的是檔案而不是目錄。



巨集: int EISDIR


是一個目錄檔案;嘗試開啟一個目錄檔案來作寫操作時就會發生這個錯誤。



巨集: int EINVAL


無效的引數。用來指出傳遞給庫函式引數時候的各種問題。



巨集: int ENFILE

整個系統中打開了太多不同的檔案。注意許多連結通道都會被計算成一個開啟的檔案;參見《連結通道》



巨集: int EMFILE

當前程序已經打開了太多檔案而且不能再打開了。



巨集: int ENOTTY


不適當的IO控制操作,比如說在一個普通檔案上試圖設定終端模式。



巨集: int ETXTBSY

一個打算執行的檔案當前正被寫開啟,或要寫開啟的檔案當前正在執行。(這個名字象徵著“文字檔案忙”。)在GNU的系統中這不是一個錯誤;可能的情況下文字檔案將被複制。



巨集: int EFBIG


檔案太大。檔案的大小超過了系統的允許。



巨集: int ENOSPC


裝置上沒有空間;因為磁碟滿而造成寫操作失敗。



巨集: int ESPIPE

錯誤的查詢操作(比如在管道中)。



巨集: int EROFS


在一個只讀的檔案系統中試圖修改一個檔案。



巨集: int EMLINK


太多的連線;單個檔案的連結數太大。



巨集: int EPIPE

斷掉的管道;在管道的另一邊沒有程序來讀取。所有庫函式在返回這個錯誤程式碼的時候都會產生一個SIGPIPE訊號;如果不處理或阻止的話這個訊號將終止程式。如此,要是不處理或阻止SIGPIPE的話你的程式實際上看不到EPIPE。



巨集: int EDOM


域錯誤;當數學函式得到的引數值不在函式允許範圍內的時候出現這個錯誤。



巨集: int ERANGE


範圍錯誤;當數學函式的結果因上溢或下溢而無法描述的時候出現此錯誤。



巨集: int EAGAIN


資源零是不可用;如果你稍候在作此呼叫或許會成功。只有fork會因為這個原因返回EAGAIN錯誤碼。



巨集: int EWOULDBLOCK


在一個非塊格式的目標上作需要塊的操作。

相容性提示:在4.4BSD和GNU中,EWOULDBLOCK和EAGAIN是一樣的。早期版本的BSD(參見《伯克利UNIX》)使用兩個不同的程式碼,用EWOULDBLOCK來表示需要塊的操作,而EAGAIN表示其他種類的錯誤。






巨集: int EINPROGRESS


在一個選擇為非塊型的目標上的初始化操作不能立即完成。



巨集: int EALREADY


在一個選擇為非塊型的目標上的一個操作正在進行。



巨集: int ENOTSOCK


當需要一個套接字的時候指定的檔案不是套接字。



巨集: int EDESTADDRREQ


在套接字操作中沒有指定目標地址。



巨集: int EMSGSIZE


送往套接字的訊息的大小操作的支援的最大尺寸。



巨集: int EPROTOTYPE


所要求的通訊協議不支援套接字的種類。



巨集: int ENOPROTOOPT


你指定的套接字操作不能被使用的套接字的協議所識別,參見《套接字操作》



巨集: int EPROTONOSUPPORT


套接字域不支援請求的通訊協議。參見《建立一個套接字》



巨集: int ESOCKTNOSUPPORT


套接字型別不被支援。



巨集: int EOPNOTSUPP

你請求的操作不被支援。一些套接字函式不被所有型別的套接字識別,而且有些不能在所有的通訊協議上實現。



巨集: int EPFNOSUPPORT

你請求的套接字協議組不被支援。



巨集: int EAFNOSUPPORT


一個套接字指定的地址組不被支援;它和套接字使用的協議不一致。參見《套接字》



巨集: int EADDRINUSE

請求的套接字地址正在使用。參見《套接字地址》



巨集: int EADDRNOTAVAIL


請求的套接字地址已經不可用;比如說,你試著把一個和本機名字不一樣的名字給套接字。參見《套接字地址》



巨集: int ENETDOWN


由於網路不通造成一個套接字操作失敗。



巨集: int ENETUNREACH


由於子網上的遠端主機不可到達造成一個套接字操作失敗。



巨集: int ENETRESET


由於遠端主機崩潰導致網路連線復位。



巨集: int ECONNABORTED


一個網路連線被本地中斷。



巨集: int ECONNRESET


由於外界控制本地主機的原因造成一個網路連線關閉。比如遠端的重啟動。



巨集: int ENOBUFS


IO操作的核心緩衝區都在使用。



巨集: int EISCONN

你試圖連線一個已經連線了的套接字。參見《建立一個連線》。



巨集: int ENOTCONN


套接字沒有連線任何東西。你得到這個錯誤的原因是你試圖通過一個套接字傳送資料,但是卻沒有先指定資料的目標。



巨集: int ESHUTDOWN


套接字已經被關閉。



巨集: int ETIMEDOUT


套接字操作在指定的超時時間間隔內沒有收到迴音。



巨集: int ECONNREFUSED

遠端主機拒絕建立網路連線。(通常是因為它並不執行請求的這種服務)



巨集: int ELOOP


在查詢檔名的時候遇到了許多指向它的符號連線。這個通常用來指出一個符號連線的環路。



巨集: int ENAMETOOLONG

檔名太長(比PATH_MAX還要長;參見《檔案系統容量限制》)貨主機名字太長(在gethostname或sethostname中;參見《主機身份》






巨集: int EHOSTDOWN


請求網路連線的遠端主機停機。



巨集: int EHOSTUNREACH


請求網路連線的遠端主機不可到達。



巨集: int ENOTEMPTY

在需要空目錄的時候目錄非空。通常這個錯誤出現在你準備刪除一個目錄的時候。



巨集: int EUSERS


檔案配額系統由於太多使用者而拒絕。



巨集: int EDQUOT


使用者的磁碟限額已經超過。



巨集: int ESTALE

過期的NFS檔案控制代碼。這裡只是了NFS系統的內部混亂而且需要對伺服器主機的檔案系統重新整理。修理這種問題通常需要在本地主機上卸下再重新掛上此NFS檔案系統。



巨集: int EREMOTE


一個使用檔名來通過NFS載入遠端檔案系統的時候此檔名已經指定給一個載入好的檔案了。(這只是在某些作業系統上的錯誤,但是我們希望在GNU系統上能執行正常,使這個錯誤程式碼不可能實現)



巨集: int ENOLCK


沒有可用的鎖定。由檔案鎖定功能使用;參見《檔案鎖》






巨集: int ENOSYS

功能沒有實現。一些功能包括命令和選項的定義可能沒有被所有的實現所支援,也就是你請求這些沒有被支援的功能的時候你會得到這一類的錯誤。



巨集: int ED


有經驗的使用者將知道錯誤是什麼。



巨集: int EGRATUITOUS

這個錯誤資訊沒有用處。
錯誤資訊

庫裡的函式和變數都設計得使你的程式在呼叫庫失敗的時候容易的使用自定義的錯誤資訊報告格式。函式strerror和perror將按給定的錯誤程式碼給你標準的錯誤資訊;變數program_invocation_short_name將使你在遇到錯誤的時候方便的訪問你的程式名。



函式: char * strerror (int errnum)

strerr函式對映由引數errnum表示的錯誤程式碼(參見《檢查錯誤》)到錯誤資訊字串。返回值是一個字串指標。


通常errnum的值從變數errno中來。


你不能修改strerroe返回的字串。同樣,如果你後來又呼叫了strerror,這個字串將會被覆蓋。但是這裡可以保證在你之後沒有任何庫函式呼叫strerror。

這個函式在“string.h”中宣告。



函式 void perror (const char *message)

此函式將錯誤資訊列印到流stderr。檢視節《標準流》

如果你呼叫perroe的message不是一個空指標就是一個空字串,perror將把這個訊息列印到相應的errno中,在後面增加一個空行。


如果你提供一個非空的message引數,prror將把這個字串作為它的輸出的字首。它將增加一個冒號和空格字元來分開message中對應errno的錯誤字串。

函式perror在stdio.h中描述。

sterror和perror對給定的錯誤程式碼提供嚴格一致的資訊,就是系統下都一致的準確文字。在GNU系統中,這個資訊是相當短的;這裡沒有多行的資訊或內嵌的新行。每個資訊都由一個大寫字母開始而且沒有結束的標點符號。

相容性提示:函式strerror是ANSI的新定義,許多老的C系統仍然不支援這個函式。


許多不從終端讀取輸入的程式都設計成如果系統呼叫錯誤就退出。而且約定,這樣一個程式產生的錯誤資訊都由這個程式的名字開始,沒有目錄名。你可以從變數 program_invocation_short_name中找到這個名字;完整的檔名存放在變數program_invocation_name 中。


變數: char * program_invocation_name

這個變數的值是用來呼叫產生當前程序的程式的名字。它和argv[0]一樣。



變數: char * program_invocation_short_name

這個變數的值是用來呼叫產生當前程序的程式的名字,但是去掉了目錄名。(就是說,這即便是program_invocation_name,也是減掉了一大半的。)


program_invocation_name和program_invocation_short_name都是系統在呼叫main之前設定的。

相容性提示:這兩個變數都是GNU的擴充套件,如果你想讓你的程式能在非GNU的函式庫上工作,你必須在main中存下argv[0]的值,並且你自己去掉目錄名。我們增加這個擴充套件的目的是使寫不需要外面的main協助的子程式也能自己進行錯誤報告。

這裡有一個例子顯示如如何恰當的處理開啟一個檔案的錯誤。函式open_sesame嘗試開啟一個指定名字的檔案並且在成功的情況下返回一個流。庫函式fopen在因為某些原因打不開一個檔案的時候返回一個空指標。在這樣的情形下,open_message使用strerror函式構造一個錯誤資訊,然後終止程式。如果我們想在呼叫其他庫函式的時候忽略strerror的錯誤程式碼,我們必須把原來的error
code為一個本地的內部變數,因為其他庫函式可能會在其間覆蓋errno。


#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

FILE *
open_sesame (char *name)

  FILE *stream;

  errno = 0;                     
  stream = fopen (name, "r");
  if (!stream) {
    fprintf (stderr, "%s: Couldn't open file %s; %s\n",
             program_invocation_short_name, name, strerror (errno));
    exit (EXIT_FAILURE);
  } else
    return stream;
}