![](/img/trans.png)
[英]linux read() function from unistd.h doesn't work for me :(
[英]Why does a call to the crypt() function from unistd.h set the errno to ENOENT?
我已经编写并运行以下代码:
#define _XOPEN_SOURCE
#include <iostream>
#include <unistd.h>
int main()
{
std::cout << "errno = " << errno << std::endl;
std::cout << crypt("sometext", "ab") << std::endl;
std::cout << "errno = " << errno <<std:: endl;
return 0;
}
errno
的初始值为0
,但是在调用crypt()
函数后,其设置为2
( ENOENT )。
这是输出:
errno = 0
abtAunjzvWWRQ
errno = 2
这是C标准关于errno
(第7.5节,第3段,重点已添加。)
程序启动时,初始线程中
errno
的值为零(其他线程中errno
的初始值为不确定的值),但是任何库函数都不会将其设置为零。 无论是否存在错误 , 都可以通过库函数调用将errno
的值设置为非零 ,前提是在此国际标准的函数描述中未记录errno
的使用。
这是Posix说的(部分)(再次强调):
值errno
时,则说明是由函数的返回值有效的只应检查......在这卷POSIX.1-2008的无功能将设置errno
为0 的设置errno
成功调用函数后除非该函数的说明指定errno
不得修改,否则未指定。
crypt
是Posix函数(如unistd.h
存在所示)。 该描述未指定errno
不应被修改。 可能是这样,过去是。
简而言之,除非函数明确报告了错误并且已记录该函数设置errno
,否则切勿尝试使用errno
的值。 在这种情况下,请确保在调用该函数之后,执行可能设置errno
任何其他操作(包括使用iostreams
和cstdio
)之前立即使用它(或保存其值)。
孤立地看这似乎有些奇怪,但实际上是很合理的。 例如,考虑一个需要查阅配置文件的功能(如果存在)。 它将包含类似以下的代码:
FILE* config = fopen(configFileName, "r");
if (config) { /* Read the file */ }
else { /* Set default values */ }
如果配置文件不存在,则根本不会使用它。 没问题。 但是errno
可能是由fopen
失败引起的。
这种事情在库函数中很常见,库函数在第一次调用时执行初始化。 如果不是用于此规定,则调用另一个库函数的任何库函数都必须在启动之前仔细保存errno
,然后在结束时将其还原,除非已报告实际错误。 我敢打赌,您的功能不会这样做:)-我的当然不会。 这很容易出错。 实际采用的约定更好,更易于审核: errno
仅在函数明确报告错误时才有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.