[英]If the POSIX socket “read” function returns 0, does that indicate an error occurred?
[英]Why errno, when POSIX function indicate error condition by returning -1 or NULL
當其中一個UNIX系統函數發生錯誤時,通常會返回負值,並將整數
errno
設置為一個值,從而提供其他信息。 - UNIX環境中的高級編程,第1.7節
這看起來很奇怪:
errno
需要是線程本地的。 errno
哪個也是另一個函數調用。 為什么不在返回值中編碼錯誤狀態?
主要由於歷史原因。
請注意,實際上, errno
今天不是普通的全局變量(在20世紀80年代就是這種情況)。 這是今天(C99,C11 ...)宏-通常是擴展到一些函數調用,或許__errno()
和最近的C標准要求 errno
是一個宏,見n1570第7.5節); 或者它可能會擴展到一些線程局部變量,甚至一些編譯器魔法。
errno
希望成為多線程需求的宏,所以我猜這些標准發展到要求它成為一些宏
所以你應該#include <errno.h>
並使用errno
宏,就好像它是一個全局變量,但知道它實際上不是一個。
細節是特定於實現的。 查看C標准庫的源代碼,例如musl-libc在errno / __ errno_location.c中
int *__errno_location(void)
{
return &__pthread_self()->errno_val;
}
並在include / errno.h公共標題中:
int *__errno_location(void);
#define errno (*__errno_location())
和GNU libc有一些非常相似的東西
BTW一些系統函數不返回整數(例如mmap
),並且一些POSIX函數不指示錯誤通過errno
,例如dlopen
(參見dlerror
)。 因此,在某些標准中很難保證每個錯誤都可以由返回值指示。
我會引用Linus Torvalds的話。
“錯誤號”在UNIX那幾個非常糟糕的愚蠢的一個。 Linux修復了它,並沒有在內部使用它,也永遠不會。 太糟糕了,用戶空間必須修復返回內核所做的正確錯誤代碼,並將其轉換為“errno”愚蠢以實現向后兼容性。
[...]
“errno”是那些根本不應該存在的破碎事物之一。 原來的UNIX是錯的,現在錯了。
[...]
Linux返回負錯誤號的方法要好得多。 它本質上是線程安全的,並沒有性能缺點。 當然,它確實依賴於擁有足夠的結果域,您可以始終將錯誤返回與良好的返回分開,但在實踐中對所有系統調用都是如此。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.