• linux系统编程之错误处理机制


    在讲解liunx错误处理机制之前我们先来看一段代码:

     1 #include<sys/types.h>                                                           
     2 #include<sys/stat.h>
     3 #include<fcntl.h>
     4 #include<stdio.h>
     5 #include<stdlib.h>
     6 
     7 int main(void)
     8 {
     9     int fd; 
    10     fd=open("abc",O_WRONLY);
    11     if(fd<0){
    12         printf("Error:fd=%d
    ",fd);
    13         14     }   
    15 
    16     return 0;
    17 }

    这一段代码是用函数open打开一个名为abc的文件,open函数的帮助文档如下:

    open() return the new file descriptor, or -1 if an error occurred (in which case, errno is set appropriately).

    翻译过来就是open()函数返回一个新的文件描述符,如果出现错误,则返回-1(在出现错误的情况下,errno要被做相应的设置)

    我们上面的代码只是判断了open是否发生了错误,至于是什么错误无法判断。因为可以引起上述代码中open函数错误的原因比较多,例如文件abc不存在,或者文件abc存在,但是没有写的权限。这都会出现错误。那么要怎么样准确的判定是什么引起的open函数处错误的呢?

    从上面的帮助文档我们知道,当open函数出错时,不仅仅会返回一个-1,函数设置errno的值。那么errno是什么类型的呢?我们看一下errno的声明或者定义

    在文件/usr/include/errno.h里面有下面的代码

    #ifndef errno

     extern int errno;
     
    #endif

    从这里我们可以看到errno是一个整型,并且是一个全局的整型变量。

    其实 errno是一个错误编号,当错误发生时,每一个不同的错误都有一个编号,这个编号的值就会被存储在errno中,根据这个编号系统就可以判断是什么错误发生了,既然系统可以判断是什么错误发生,那么就可以把错误的信息打印出来。打印错误信息的函数是perror(),当然还有一些别的打印错误的函数,我们这里就不举例了,如果想查看,可以通过man 2 perror来查看帮助文档。下面我们列举一些错误的定义,错误编号的定义放在/usr/include/asm-generic/目录的errno-base.h 以及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  /* 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 */
    #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 */
                                                                                                            1,1          顶端

    这时我们就可以改写测试程序了

     1 #include<sys/types.h>                                                           
     2 #include<sys/stat.h>
     3 #include<fcntl.h>
     4 #include<stdio.h>
     5 #include<stdlib.h>
     6 
     7 int main(void)
     8 {
     9     int fd; 
    10     fd=open("abc",O_WRONLY);
    11     if(fd<0){
    12         printf("Error:fd=%d
    ",fd);
    13         perror("open file abc");//这一行就是根据系统的编号打印出错误的信息
    14     }   
    15 
    16     return 0;
    17 }
    18 ~       
  • 相关阅读:
    操作系统--怎么实现中断
    操作系统中的描述符和GDT
    使用汇编语言实现memcpy
    Redis命令之setbit
    java webService 服务端的创建 和 客户端代码的生成与使用
    springbooot 项目读取yml配置文件(自定义)
    java自定义注解的使用(校验)
    mysql使用存储过程快速插入百万条数据
    springboot项目集成Mybatisplus配置和使用
    mysql 创建函数的过程和使用
  • 原文地址:https://www.cnblogs.com/cplinux/p/5814341.html
Copyright © 2020-2023  润新知