在 GNU 中使用负 ERRNO 值的历史
History of using negative ERRNO values in GNU
是否有history behind the "negative error" approach? That is, in a lot of kernel code and in various Linux-related projects, one does not set the errno
, but uses <errno.h>
,return代码格式为:
int iErr;
if ( function_successful ) {
iErr = 0;
} else if ( function_successful && num_bytes_handled > 0 ) {
iErr = num_bytes_handled;
} else {
// Error
iErr = (-EINVAL);
}
return iErr;
在编写驱动程序、资源管理器、库等时,我自己也开始使用这种方法,但我一直想知道这种做法起源于何处。我个人认为使用函数 returning int
处理错误编号是一种聪明的方法,并且想知道更多关于它是如何开始的以及从哪里开始的。
谢谢。
历史上,系统调用 returned 要么是一个正值(如果成功),要么是一个指示错误代码的负值。就我而言,从 UNIX 一开始就是这种情况。 libc 将错误 [=20=] 转换为对 errno
的赋值和 -1
的 return 值(在错误的情况下),或原始的 return 值(在错误的情况下)成功。
需要这种方法,因为内核无法设置 errno
,因为它不知道 errno
在哪里。也许可以设计一个系统,告诉内核 errno
在哪里,但这比让 libc 分配 errno
复杂得多。
在 http://yarchive.net/comp/linux/errno.html,Linus Torvalds 详细阐述了 errno 变量方法为何存在缺陷。
在现代多线程 POSIX 实现中,errno 被定义为一个宏,用于解决传统 extern int errno
变量可能会遇到的多线程问题。
正如他所说:
Too bad that user space has to fix up the correct error code
returning that the kernel does, and turn it into the "errno" stupidity
for backwards compatibility.
是否有history behind the "negative error" approach? That is, in a lot of kernel code and in various Linux-related projects, one does not set the errno
, but uses <errno.h>
,return代码格式为:
int iErr;
if ( function_successful ) {
iErr = 0;
} else if ( function_successful && num_bytes_handled > 0 ) {
iErr = num_bytes_handled;
} else {
// Error
iErr = (-EINVAL);
}
return iErr;
在编写驱动程序、资源管理器、库等时,我自己也开始使用这种方法,但我一直想知道这种做法起源于何处。我个人认为使用函数 returning int
处理错误编号是一种聪明的方法,并且想知道更多关于它是如何开始的以及从哪里开始的。
谢谢。
历史上,系统调用 returned 要么是一个正值(如果成功),要么是一个指示错误代码的负值。就我而言,从 UNIX 一开始就是这种情况。 libc 将错误 [=20=] 转换为对 errno
的赋值和 -1
的 return 值(在错误的情况下),或原始的 return 值(在错误的情况下)成功。
需要这种方法,因为内核无法设置 errno
,因为它不知道 errno
在哪里。也许可以设计一个系统,告诉内核 errno
在哪里,但这比让 libc 分配 errno
复杂得多。
在 http://yarchive.net/comp/linux/errno.html,Linus Torvalds 详细阐述了 errno 变量方法为何存在缺陷。
在现代多线程 POSIX 实现中,errno 被定义为一个宏,用于解决传统 extern int errno
变量可能会遇到的多线程问题。
正如他所说:
Too bad that user space has to fix up the correct error code returning that the kernel does, and turn it into the "errno" stupidity for backwards compatibility.