Linux错误码 perror errno

本文详细解析了Linux错误代码体系,从权限错误到远程操作失败,涵盖128个错误码及其含义,为开发者提供深入理解错误处理的基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//errno.h
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
[root@jfht ~]# perror 13
OS error code  13:  Permission denied
<think>我们正在讨论的是Linux错误码对应的符号名称。在Linux系统中,错误码errno)是一个整数,每个错误码都有一个对应的符号名称(宏定义),这些符号名称定义在头文件<errno.h>中。例如,错误码2对应的符号名称是ENOENT,表示“没有那个文件或目录”。 用户可能希望了解如何通过错误码找到对应的符号名称,或者反过来通过符号名称找到错误码。此外,用户可能还想知道如何获取错误的描述信息。 根据引用[1],我们可以使用perror或strerror来获取错误描述,但用户现在关心的是错误码对应的符号名称。 下面我将介绍如何获取错误码的符号名称以及如何查找符号名称对应的错误码。 ### 一、错误码与符号名称的对应关系 1. **错误码转符号名称** 在C程序中,我们可以使用预定义的宏来获取错误码的符号名称。但是,标准库并没有直接提供将错误码转换为符号名称字符串的函数。通常,我们需要自己实现一个映射,或者查看<errno.h>头文件中的定义。 例如,在<errno.h>中,我们可以看到: ```c #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ // ... 更多 ``` 因此,如果我们有一个错误码(比如2),我们可以通过查看头文件或者使用条件判断等方式来得到它的符号名称(字符串"ENOENT")。但是,标准库没有提供现成的函数。 2. **符号名称转错误码** 反过来,如果我们有一个符号名称(如"ENOENT"),我们可以直接使用这个宏,它会被替换为对应的错误码(2)。 ### 二、如何查询错误码的符号名称 由于C标准库没有提供将错误码转换为符号名称字符串的函数,我们可以采取以下方法: 1. **使用预定义的宏列表** 我们可以自己定义一个函数,通过switch语句将错误码映射为字符串: ```c #include <stdio.h> #include <string.h> #include <errno.h> const char *errno_to_name(int err) { switch (err) { case EPERM: return "EPERM"; case ENOENT: return "ENOENT"; case ESRCH: return "ESRCH"; // ... 其他错误码 default: return "UNKNOWN"; } } int main() { int err = 2; printf("Error %d: %s\n", err, errno_to_name(err)); // 输出:Error 2: ENOENT return 0; } ``` 注意:这种方法需要手动维护,并且只覆盖了已知的错误码。 2. **使用第三方库或工具** 一些第三方库(如libperl)提供了类似的功能,但在标准C中不提供。 3. **命令行查询** 在Linux系统中,我们可以通过`errno`命令来查询错误码和符号名称的对应关系(需要安装): ```bash # 安装errno命令(以Ubuntu为例) sudo apt install moreutils # 查询所有错误码 errno -l # 查询特定错误码 errno 2 ``` 示例输出: ``` ENOENT 2 No such file or directory ``` ### 三、错误描述获取(引用[1]) 虽然用户主要关心符号名称,但我们也回顾一下如何获取错误描述: - `perror`函数:打印出最近一次函数调用产生的错误描述,同时可以添加自定义前缀。 - `strerror`函数:将错误码转换为描述字符串。 示例: ```c #include <stdio.h> #include <string.h> #include <errno.h> int main() { FILE *fp = fopen("non_existent_file.txt", "r"); if (fp == NULL) { int err = errno; printf("错误码: %d\n", err); printf("错误符号: %s\n", errno_to_name(err)); // 假设有上面的函数 perror("打开文件失败"); printf("错误描述: %s\n", strerror(err)); } return 0; } ``` 输出示例: ``` 错误码: 2 错误符号: ENOENT 打开文件失败: No such file or directory 错误描述: No such file or directory ``` ### 四、常见错误码及其符号名称(部分) 以下是部分常见错误码及其符号名称和含义: | 错误码 | 符号名称 | 含义 | |--------|---------------|--------------------------| | 1 | EPERM | 操作不允许 | | 2 | ENOENT | 没有那个文件或目录 | | 3 | ESRCH | 没有那个进程 | | 4 | EINTR | 系统调用被中断 | | 5 | EIO | 输入输出错误 | | 6 | ENXIO | 没有那个设备或地址 | | 7 | E2BIG | 参数列表过长 | | 8 | ENOEXEC | 可执行文件格式错误 | | 9 | EBADF | 文件描述符错误 | | 10 | ECHILD | 没有子进程 | | ... | ... | ... | 完整的错误码列表可以参考`man errno`。 ### 五、内核中的错误处理(引用[2]) 在Linux内核中,错误处理使用特殊的指针处理函数,如`IS_ERR`、`PTR_ERR`、`ERR_PTR`。这些函数用于将错误码(负值)编码为指针,或者从指针中解码出错误码。但请注意,内核中的错误码与用户空间的错误码是相同的符号名称(如`ENOENT`),只是在内核中错误码通常以负值表示。 例如,在内核中: ```c void *func() { if (error_occurred) { return ERR_PTR(-ENOENT); // 返回一个包含错误码的指针 } // ... 正常返回指针 } // 调用者 void *ptr = func(); if (IS_ERR(ptr)) { int err = PTR_ERR(ptr); // 此时err为-ENOENT(即-2) } ``` ### 六、相关问题 §§相关问题§§ 1. 如何在C程序中实现错误码到符号名称的自动映射(无需手动维护switch)? 2. 在Linux内核模块中如何获取错误码的描述信息? 3. 如何通过系统调用获取错误码的详细信息? 4. 错误码和信号(signal)有什么区别?</think>在 Linux 系统中,错误码与其对应的符号名称定义在头文件 `<errno.h>` 中。这些符号名称是标准化的宏定义,用于表示不同类型的系统错误。以下是常见错误码及其对应的符号名称和含义: ### 常见 Linux 错误码符号名称表 | 错误码 | 符号名称 | 含义描述 | |--------|----------------|------------------------------| | **1** | `EPERM` | 操作不允许(无权限) | | **2** | `ENOENT` | 文件或目录不存在 | | **3** | `ESRCH` | 进程不存在 | | **4** | `EINTR` | 系统调用被中断 | | **5** | `EIO` | 输入/输出错误 | | **6** | `ENXIO` | 设备或地址不存在 | | **7** | `E2BIG` | 参数列表过长 | | **8** | `ENOEXEC` | 可执行文件格式错误 | | **9** | `EBADF` | 文件描述符无效 | | **10** | `ECHILD` | 无子进程 | | **11** | `EAGAIN` | 资源暂时不可用 | | **12** | `ENOMEM` | 内存不足 | | **13** | `EACCES` | 权限不足 | | **14** | `EFAULT` | 错误的内存地址 | | **15** | `ENOTBLK` | 需要块设备 | | **16** | `EBUSY` | 设备或资源忙 | | **17** | `EEXIST` | 文件已存在 | | **18** | `EXDEV` | 跨设备链接 | | **19** | `ENODEV` | 设备不存在 | | **20** | `ENOTDIR` | 不是目录 | | **21** | `EISDIR` | 是目录 | | **22** | `EINVAL` | 无效参数 | | **23** | `ENFILE` | 系统打开文件数过多 | | **24** | `EMFILE` | 进程打开文件数过多 | | **25** | `ENOTTY` | 不适当的 I/O 控制操作 | | **26** | `ETXTBSY` | 文本文件忙 | | **27** | `EFBIG` | 文件过大 | | **28** | `ENOSPC` | 设备无剩余空间 | | **29** | `ESPIPE` | 非法偏移 | | **30** | `EROFS` | 只读文件系统 | | **31** | `EMLINK` | 链接数过多 | | **32** | `EPIPE` | 管道破裂 | | **33** | `EDOM` | 数值超出范围 | | **34** | `ERANGE` | 结果超出范围 | ### 使用示例 1. **在代码中检查错误符号**: ```c #include <stdio.h> #include <errno.h> #include <string.h> int main() { FILE *fp = fopen("non_existent.txt", "r"); if (fp == NULL) { printf("错误码: %d\n", errno); printf("错误符号: %s\n", strerror(errno)); // 输出:No such file or directory printf("错误宏名: "); switch(errno) { case ENOENT: printf("ENOENT\n"); break; case EACCES: printf("EACCES\n"); break; // 其他错误处理... } } return 0; } ``` 2. **命令行查询**: ```bash # 使用 perror 查看错误描述 $ ls /non_existent 2>&1 | cat ls: cannot access '/non_existent': No such file or directory # 使用 errno 命令查询(需安装 moreutils) $ sudo apt install moreutils $ errno 2 ENOENT 2 No such file or directory ``` ### 关键说明 1. **完整列表**:完整错误码列表可在 `/usr/include/asm-generic/errno-base.h`(基础错误)和 `/usr/include/asm-generic/errno.h`(扩展错误)中查看[^1][^2]。 2. **内核错误处理**:在内核开发中,使用 `IS_ERR()`、`PTR_ERR()` 和 `ERR_PTR()` 处理指针错误[^2]: ```c void *ptr = some_kernel_function(); if (IS_ERR(ptr)) { int err = PTR_ERR(ptr); // 从指针提取错误码 printk("错误: %d\n", err); } ``` 3. **错误码范围**: - `1-34`:基础错误(所有系统通用) - `35-133`:扩展错误(Linux 特有) - `>133`:架构相关错误 > 注意:所有错误码均为**正整数**,系统调用返回时通常用 `-1` 表示错误,并通过 `errno` 获取具体错误码[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值