UNIX C 中的错误机制

来源:互联网 发布:windows无法连接到服务 编辑:程序博客网 时间:2024/06/05 09:03

http://www.ibm.com/developerworks/cn/aix/library/au-errnovariable/index.html

看得越多越好奇,UNIX下究竟有哪些错误常量,各代表什么意思呢?

嘿嘿,非常非常喜欢IBM这种方式!哦,蓝色帝国,我的梦想:)

报告故障的两种常用方法:

  • 函数返回错误代码或成功代码;如果是错误代码,则代码本身可用于指出何处出错。
  • 函数返回特定值(或值范围)以指明错误,且设置全局变量 errno 以指明问题的起因。
  • errno全局变量在<errno.h>中定义,其所有的可能值都定义为标准常量。

    第一个类别中的许多函数实际上会返回标准 errno 代码中的一个,但是,如果不检查手册页上的“返回”部分,则无法预知函数的行为方式。如果运气好的话,函数的手册页会列出其可能返回的所有值,以及它们在此特定函数的上下文中所指的含义。

    errno 全局变量由标准 C 库的函数设置.

    标准 C 库定义两个与错误相关的其他全局变量:sys_nerr(类型为 int)和 sys_errlistchar 类型的指针数组)。第一个全局变量是标准错误消息(存储在 sys_errlist 中)的数量。历史应用程序(即很过时的遗留代码)有时会直接引用这些全局变量,但会在编译过程中产生错误,因为它们的声明并不一致。

    标准 errno 值包括:

    • E2BIG:传递给函数的参数列表太长。
    • EACCESS:拒绝访问!运行程序的用户不具有访问文件、目录等的权限。
    • EAGAIN所要求的资源暂时不可用;如果稍后再尝试此操作,则可能会成功。
    • EBADF:函数尝试使用错误的文件描述符(例如,它不引用打开的文件,或者用于尝试写入以只读方式打开的文件)。
    • EBUSY请求的资源不可用。例如,在另一个程序正在读取目录时尝试删除该目录。请注意 EBUSYEAGAIN 之间的模糊性;您显然能够稍后在读取程序完成后删除该目录。
    • ECHILDwait()waitpid() 函数尝试等待退出子进程,但所有子项都已经退出。
    • EDEADLK:如果继续请求,则会出现资源死锁。请注意,这与从多线程代码中获得的死锁类型不同——errno 及其相关项一定能够帮助您跟踪到这些。
    • EDOM:输入参数在数学函数的域之外。
    • EEXIST:文件已存在,且这是问题所在。例如,如果使用指定现有文件或目录的路径调用 mkdir()
    • EFAULT:函数参数之一引用了无效的地址。大部分实现均无法检测到此种情况(相反,程序会接收到 SIGSEGFAULT 信号并退出)。
    • EFBIG:请求会导致文件扩展并超过实现所定义的最大文件大小。所定义的最大文件大小通常约为 2GB,但大部分现代文件系统都支持更大的文件,有时要求 64 位版本的 read()/write()lseek() 函数。
    • EINTR:程序中的信号处理程序捕获到函数的执行被某个信号中断,信号处理程序然后按正常方式返回。
    • EINVAL:向函数传递了无效的参数
    • EIO:发生 I/O 错误;通常会生成此错误以回应硬件问题。
    • EISDIR:您使用了目录参数来调用要求文件参数的函数。
    • ENFILE:已在此进程中打开太多文件。每个进程具有 OPEN_MAX 个文件描述符,您正尝试打开(OPEN_MAX + 1 个)文件。请记住,文件描述符 包括诸如套接字之类的内容。
    • ENLINK:函数调用会导致文件具有超过 LINK_MAX 个的链接。
    • ENAMETOOLONG:您已创建比 PATH_MAX 长的路径名,或者已创建比 NAME_MAX 长的文件名或目录名。
    • ENFILE:系统具有太多同时打开的文件。这应是暂时的情况,且它不太可能发生在现代系统上。
    • ENODEV:没有这样的设备,或者您正尝试在指定设备上执行不适当的操作(例如,不要尝试从旧系列打印机中读取内容)。
    • ENOENT:没有找到这样的文件,或者指定的路径名不存在。
    • ENOEXEC:您已尝试运行无法执行的文件。
    • ENOLCK:没有可用的锁;您已达到系统对文件锁或记录锁的限制范围。
    • ENOMEM:系统内存不足。一般而言,应用程序(和操作系统本身)并不能适当地处理此种情况,因此,需要的 RAM 比预期使用的要多,尤其是在系统无法动态地增加磁盘上交换空间的大小的情况下。
    • ENOSPC:设备上没有剩余空间。您已尝试在已满的设备上写入或创建文件。同样,应用程序和操作系统也不能适当地处理这种情况。
    • ENOSYS:系统不支持该函数。例如,如果在不具有作业控制的系统上调用 setpgid(),则将会接收到 ENOSYS 错误。
    • ENOTDIR:指定的路径名必须为目录,但却不是。此错误与 EISDIR 错误相反。
    • ENOTEMPTY:指定的目录不为空,但它必须为空。请注意, 目录仍包含 . 和 .. 条目。
    • ENOTTY:您已尝试在不支持 I/O 控制操作的文件或特殊文件上执行该操作。例如,不要尝试在目录上设置波特率。
    • ENXIO:您已尝试为不存在的设备在特殊文件上执行 I/O 请求。
    • EPERM:不允许执行此操作;您不具有访问指定资源的权限。
    • EPIPE:您已尝试在不再存在的管道中读取或写入内容。管道链中的程序之一已关闭其流的一部分(例如,通过退出)。
    • ERANGE:您已调用函数,但返回值太大而无法通过返回类型来呈现。例如,如果函数返回 unsigned char 值,但计算的结果为 256 或更多(或者是 -1 或更少),则 errno 将被设置为 ERANGE 且函数会返回一些不相关的值。在此类情况下,检查输入数据以确保其完备性,或在每次调用后检查 errno,这一点很重要。
    • EROFS:您尝试修改存储在只读文件系统(或在只读模式下安装的文件系统)上的文件或目录。
    • ESPIPE:您尝试在管道或“先进先出 (FIFO)”堆栈上查找。
    • ESRCH:您已指定无效的进程 ID 或进程组。
    • EXDEV:您已尝试执行将会跨设备移动链接的操作。例如, UNIX 文件系统并不允许在文件系统之间移动文件(相反,您必须复制文件,然后删除原始文件)。

    错误返回函数: 

     1, perror(): perror() 函数显示了传递给它的字符串,后跟冒号、空格,接着是当前 errno 值的文字表示形式。您可以通过使用 printf() 调用和 strerror() 函数(该函数返回当前 errno 值的文字表示形式的指针)来模拟此程序。perror() 将其消息写入标准错误通道,printf() 调用将写入标准输出通道 (stdout)。

    strerror() 函数并没有必要是线程安全的;对于未知值,该函数在静态缓冲区中设置错误消息的格式并将指针返回到该缓冲区。对 strerror() 的其他调用将会覆盖该缓冲区的内容。POSIX 1003.1 标准定义 strerror_r(),该函数除接受错误值之外,还接受缓冲区中的指针和缓冲区大小。引出标准错误描述的 perror()strerror() 函数来自 sys_errlist 全局变量。

    2,strerror_r(): 在处理标准 errno 值时,perror()strerror()/strerror_r() 函数可能是最常用的错误报告方法。

    显示所有的错误:

    // Print out all known errors on the system.
    void print_errs( void )
    {
        
    int idx = 0;
        
        
    for( idx = 0; idx < sys_nerr; idx++ ) {
            printf( 
    "Error #%3d: %s ", idx, strerror( idx ) );
        }

    }

    原创粉丝点击