Linux系统中常用error number定义与解释

在没有解释这些错误定义之前,先让我们看看为什么要知道这些常用error number? 对于写C程序的人来说,errno并不是一个陌生的变量,无论你是在用户态还是在内核态。简短来说,errno是用来保存错误信息,这些信息反应了相应错误原因。因此,一个小小errno就可以连接user space programmer 与 kernel space programmers,可见其重要性。但是,我们的programmers确又常常忽略这些,他们往往只看中正确与错误,而不是去访问强大的errno获取更多的信息。对于普通的程序,为此可能仅仅是"没关系,大不了可以重启"。但是,对于一些重要的任务,重启可能意味着灾难的发生,尤其是在重要的领域。为此,这里我想给大家列出常见的errno,提醒大家在处理设备时,"check errno when your routine failed!".

Linux errno 在0.* 版本中大约只有三四十个,但是当Linux kenel飞速膨胀时,errno的数量也在增加,具体,有多少在你的linux版本中,你可以通过 man errno 查看,或者直接打开文件:
  include/linux/errno.h
这里只是列出了常用的或最早期的一些errno:
  
#define EPERM            1      /* Operation not permitted */
拒绝操作,通常是权限的问题,例如普通用户删除root的文件
#define ENOENT           2      /* No such file or directory */
没有相应的文件或目录,例如打开不存的文件
#define ESRCH            3      /* No such process */
没有相应的进程,例如kill掉一个不存在的进程号
#define EINTR            4      /* Interrupted system call */
中断的系统调用
#define EIO              5      /* I/O error */
I/O错误
#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 */
拒绝访问

#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 */
不是一个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 */
错误的seek操作

#define EROFS           30      /* Read-only file system */
只读文件系统

#define EMLINK          31      /* Too many links */
连接太多

#define EPIPE           32      /* Broken pipe */
PIPE崩溃

#define EDOM            33      /* Math argument out of domain of func */
数学参数超出了函数域

#define ERANGE          34      /* Math result not representable */
无法表示数学结果在没有解释这些错误定义之前,先让我们看看为什么要知道这些常用error number? 对于写C程序的人来说,errno并不是一个陌生的变量,无论你是在用户态还是在内核态。简短来说,errno是用来保存错误信息,这些信息反应了相应错误原因。因此,一个小小errno就可以连接user space programmer 与 kernel space programmers,可见其重要性。但是,我们的programmers确又常常忽略这些,他们往往只看中正确与错误,而不是去访问强大的errno获取更多的信息。对于普通的程序,为此可能仅仅是"没关系,大不了可以重启"。但是,对于一些重要的任务,重启可能意味着灾难的发生,尤其是在重要的领域。为此,这里我想给大家列出常见的errno,提醒大家在处理设备时,"check errno when your routine failed!".Linux errno 在0.* 版本中大约只有三四十个,但是当Linux kenel飞速膨胀时,errno的数量也在增加,具体,有多少在你的linux版本中,你可以通过 man errno 查看,或者直接打开文件:  include/linux/errno.h这里只是列出了常用的或最早期的一些errno:   #define EPERM            1      /* Operation not permitted */拒绝操作,通常是权限的问题,例如普通用户删除root的文件#define ENOENT           2      /* No such file or directory */没有相应的文件或目录,例如打开不存的文件#define ESRCH            3      /* No such process */没有相应的进程,例如kill掉一个不存在的进程号#define EINTR            4      /* Interrupted system call */中断的系统调用#define EIO              5      /* I/O error */I/O错误#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 */拒绝访问#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 */不是一个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 */错误的seek操作#define EROFS           30      /* Read-only file system */只读文件系统#define EMLINK          31      /* Too many links */连接太多#define EPIPE           32      /* Broken pipe */PIPE崩溃#define EDOM            33      /* Math argument out of domain of func */数学参数超出了函数域#define ERANGE          34      /* Math result not representable */无法表示数学结果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux内核支持多种不同的文件系统类型,包括ext4、NTFS、FAT、XFS等等。这些文件系统类型的实现代码可以在内核源码找到,并对其进行逐行介绍。 以下是一个示范的文件系统实现,名为"myfs": 1. 首先定义了一些预处理指令,包括头文件和一些常量定义: ``` #include <linux/module.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/buffer_head.h> #define MYFS_MAGIC_NUMBER 0x13131313 #define MYFS_DEFAULT_BLOCK_SIZE 4096 #define MYFS_FILENAME_MAX_LEN 256 ``` 2. 然后定义了一个结构体,用于存储文件系统的元数据信息: ``` struct myfs_sb_info { __u32 magic_number; __u32 block_size; __u64 inode_count; __u64 block_count; __u64 free_blocks; __u64 free_inodes; struct mutex lock; }; ``` 其,magic_number是一个用于标识该文件系统类型的数字;block_size是文件系统使用的块大小;inode_count和block_count分别表示文件系统的inode和block数量;free_blocks和free_inodes表示可用的block和inode数量;lock是用于保护元数据结构的互斥锁。 3. 接下来定义了一个inode结构体,用于表示文件或目录的属性信息: ``` struct myfs_inode_info { __u32 mode; uid_t uid; gid_t gid; __u64 size; __u64 atime; __u64 mtime; __u64 ctime; __u32 block_count; __u32 blocks[MYFS_DEFAULT_BLOCK_SIZE / sizeof(__u32)]; struct inode vfs_inode; }; ``` 其,mode表示文件或目录的访问权限;uid和gid表示文件或目录的所有者和所属组;size表示文件大小;atime、mtime和ctime表示文件或目录的访问、修改和创建时间;block_count表示该文件或目录使用的block数量;blocks数组存储了该文件或目录所使用的所有block的编号;vfs_inode是用于与VFS交互的inode结构体。 4. 接下来定义了一些用于读取和写入磁盘的函数: ``` static int myfs_read_block(struct super_block *sb, void *buf, __u64 block_no); static int myfs_write_block(struct super_block *sb, void *buf, __u64 block_no); ``` 这些函数使用了内核提供的缓冲区头结构体(buffer_head)来读写磁盘块。 5. 定义了用于初始化文件系统的函数: ``` static int myfs_fill_super(struct super_block *sb, void *data, int silent); ``` 该函数用于读取文件系统的元数据信息,并填充超级块结构体(super_block)。 6. 接下来定义了一些用于VFS操作的函数: ``` static struct inode *myfs_inode_lookup(struct inode *parent_inode, struct dentry *child_dentry, unsigned int flags); static int myfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl); static int myfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); static int myfs_rmdir(struct inode *dir, struct dentry *dentry); static int myfs_unlink(struct inode *dir, struct dentry *dentry); static int myfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); static ssize_t myfs_file_read(struct file *filp, char *buf, size_t count, loff_t *pos); static ssize_t myfs_file_write(struct file *filp, const char *buf, size_t count, loff_t *pos); static int myfs_mmap(struct file *filp, struct vm_area_struct *vma); ``` 这些函数实现了VFS的各种操作,例如查找inode、创建和删除文件或目录、读写文件、内存映射等。 7. 最后定义了用于注册文件系统的函数: ``` static struct file_system_type myfs_fs_type = { .owner = THIS_MODULE, .name = "myfs", .mount = myfs_mount, .kill_sb = myfs_kill_sb, }; static int __init myfs_init(void) { int ret = register_filesystem(&myfs_fs_type); if (ret) { printk(KERN_ERR "myfs: Failed to register filesystem (error %d)\n", ret); return ret; } printk(KERN_INFO "myfs: Filesystem registered successfully\n"); return 0; } static void __exit myfs_exit(void) { int ret = unregister_filesystem(&myfs_fs_type); if (ret) { printk(KERN_ERR "myfs: Failed to unregister filesystem (error %d)\n", ret); } printk(KERN_INFO "myfs: Filesystem unregistered successfully\n"); } module_init(myfs_init); module_exit(myfs_exit); ``` 这些函数定义了文件系统类型,注册和注销文件系统。 以上就是一个简单的示范文件系统的实现。在实际的文件系统实现,还需要处理更多的细节和异常情况,例如文件系统的格式化、坏块处理、权限检查、错误恢复等等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值