You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:25:52