一、基本介绍
在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 <stdio.h>
#include <unistd.h>
#include <errno.h>
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 <stdio.h>
#include <errno.h>
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 <stdio.h>
#include <errno.h>
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 <stdio.h>
#include <unistd.h>
#include <errno.h>
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 <stdio.h>
#include <string.h>
#include <errno.h>
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
等函数进行错误信息的输出和处理。