[英]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.