为何调用unistd.h中的crypt()函数会将errno设为ENOENT?
crypt()调用后errno被设为ENOENT(2)的原因解析 我来帮你拆解这个问题——你会发现crypt()明明成功返回了加密字符串,但errno却被设置成了2(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
abtAunjzvWWRQ
errno = 2
核心原因分析
这里的关键知识点是:只有当crypt()返回NULL时,errno的值才是有效的错误标识。如果函数返回了非空的加密字符串,说明主功能已经成功完成,此时的errno可能是函数内部调用的底层系统操作留下的“残留值”。
具体来说,crypt()的实现通常会尝试访问系统密码相关的文件(比如/etc/passwd或/etc/shadow),用来获取默认盐值或做一些辅助验证。但当你已经显式传入了盐值(这里是"ab"),它不需要依赖这些文件就能完成加密,所以会忽略底层文件访问失败的错误(也就是ENOENT,文件不存在),继续完成加密逻辑。但底层系统调用已经把errno设置成了2,这个值就被保留了下来。
正确的错误判断方式
如果你需要判断crypt()是否真的执行失败,应该检查它的返回值是否为NULL,而不是直接看errno:
#define _XOPEN_SOURCE #include <iostream> #include <unistd.h> #include <errno.h> // 需要包含这个头文件来使用errno int main() { errno = 0; // 初始化errno char* result = crypt("sometext", "ab"); if (result == NULL) { std::cout << "crypt failed, errno = " << errno << std::endl; } else { std::cout << "加密结果: " << result << std::endl; // 此时errno的值无意义,不要用它判断成功与否 } return 0; }
内容的提问来源于stack exchange,提问作者Piotr Kózka
相关产品推荐
相关产品推荐

