一、基本介绍
在Linux系统中,每一个错误都对应了一个唯一的错误码,表示了相应错误的类型和错误产生的原因。Linux系统使用负数来表示错误码,在头文件errno.h中定义,通常使用全局变量errno来保存上一次系统调用的错误码。使用perror或strerror函数可以将错误码转换为可读性较强的字符串错误信息。
以下是一些常用的错误码:
#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 /* Argument 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 */ ... // 其他错误码省略
二、常见错误码及其原因
1. EPERM
EPERM表示操作没有被允许,通常是因为权限不足导致的。例如,试图修改root用户的密码时,会返回EPERM错误。
#include#include #include int main() { if(setuid(0) == -1) { perror("setuid"); return errno; } printf("setuid success.\n"); return 0; }
以上代码试图切换当前进程的用户身份为root,如果执行该程序的用户没有足够的权限,setuid函数就会返回-1,并设置errno为EPERM。
2. ENOENT
ENOENT表示文件或目录不存在。例如,试图打开不存在的文件时,会返回该错误。
#include#include int main() { FILE* fp; fp = fopen("/path/to/nonexistent/file", "r"); if(fp == NULL) { perror("fopen"); return errno; } fclose(fp); return 0; }
以上代码试图打开一个不存在的文件,由于该文件不存在,fopen函数会返回NULL,并设置errno为ENOENT。
3. EIO
EIO表示输入/输出错误,通常是因为设备故障或文件系统损坏导致的。
#include#include int main() { FILE* fp; char buffer[1024]; size_t bytes_read; fp = fopen("/path/to/file", "r"); if(fp == NULL) { perror("fopen"); return errno; } bytes_read = fread(buffer, sizeof(char), sizeof(buffer), fp); if(bytes_read == 0) { if(ferror(fp)) { perror("fread"); return errno; } } fclose(fp); return 0; }
以上代码试图读取一个文件,如果读取过程中发生了输入/输出错误,fread函数会返回0,并设置errno为EIO。
三、常用处理方式
1. perror函数
perror函数用于将错误码转换为可读性较强的错误信息输出到标准错误流。例如,使用perror函数输出上面示例程序的错误信息:
#include#include #include int main() { if(setuid(0) == -1) { perror("setuid"); return errno; } printf("setuid success.\n"); return 0; }
执行该程序时,如果当前用户没有充足的权限,perror函数将输出:
setuid: Operation not permitted
2. strerror函数
strerror函数用于将错误码转换为可读性较强的错误信息字符串。
#include#include #include int main() { if(setuid(0) == -1) { printf("setuid failed: %s\n", strerror(errno)); return errno; } printf("setuid success.\n"); return 0; }
执行该程序时,如果当前用户没有充足的权限,strerror函数将输出:
setuid failed: Operation not permitted
四、总结
Linux系统的错误码为我们处理程序中可能出现的错误提供了方便,通过errno.h头文件中定义的错误码,我们可以快速地确定程序中出现的错误类型和错误原因。在编写程序时,我们应该仔细阅读系统调用和库函数对错误码的文档描述,了解每个错误码的具体含义和解决方案,并使用perror和strerror等函数进行错误信息的输出和处理。