写给初学者的Linux errno 错误码机制

不同于Java的异常处理机制, 当你使用C更多的接触到是基于错误码的异常机制, 简单来说就是当调用的函数发生异常时, 程序不会跳转到一个统一处理异常的地方, 取而代之的是返回一个整型错误码。

可能会有小伙伴有疑问了, 以打开文件为例该函数定义如下所示

int open(const char *pathname, int flags);

如果打开文件成功, open函数会返回一个文件描述符(该值大于0), 如果失败则返回 -1。对于开发者来说, 只知道文件打开失败了, 而却不知道具体原因, 实际上的原因可能是多种多样的, 如:

  • 文件不存在
  • 当前进程对文件没有读写权限
    [En]

    the current process does not have read and write access to the file*

那么该如何知道具体错误呢? 这就需要借助系统为我们提供的 errno机制了。

errno

errno是一个定义在 errno.h头文件的全局整型变量,表示当前发生的最后一个错误, 只需在代码中引用 errno.h这个头文件边可以获取到这个值。

如以下demo所示, 我们尝试打开一个不存在的文件

#include
#include
#include
#include

int main() {
    int fd;
    fd = open("/test.log", O_RDONLY);
    if (fd == -1) {
        printf("open failed, errno: %d\n", errno);
    }
    return 0;
}

运行该程序, 输出如下所示:

open failed, errno: 2

可以看出,此时错误码为 2, 怎么知道这个错误码代表什么意思呢?

有以下方式

moreutils

  1. 安装moreutils
apt install moreutils
  1. 运行 errno 错误码查看具体的错误信息
    写给初学者的Linux errno 错误码机制

可以验证, 错误码2表示当前文件或目录不存在,与我们的预期一致

perror

使用定义在 stdio.h中的 perror函数可以直接在标准输出上打印错误信息

该函数定义如下所示, 我们可以在错误信息前附加自己定义的错误信息。

void perror(const char *s);

Demo:

int main() {
    int fd;
    fd = open("/test.log", O_RDONLY);
    if (fd == -1) {
        perror("open failed");
    }
    return 0;
}

输出:

写给初学者的Linux errno 错误码机制

strerr

如果我们只需要获取错误码对应的文本以记录日志, 可以使用 strerr函数, 该函数定义在 string.h

Demo:

int main() {
    int fd;
    fd = open("/test.log", O_RDONLY);
    if (fd == -1) {
      char* err_msg = strerror(errno);
      printf("%s\n", err_msg);
    }
    return 0;
}

输出

写给初学者的Linux errno 错误码机制

线程安全的吗?

相信对于并发问题比较敏感的同学已经意识到了一个问题:这 errno是一个整型的全局变量, 那如果多个线程同时执行系统调用, 并且都因为不同的原因失败了, 会不会导致其他线程的错误信息全部被最后一个产生错误的线程给覆盖掉了? 以及会不会有线程安全问题呢?

实际上 errno被定义为了线程局部变量, 概念同Java中的 ThreadLocal, 即每个线程都会有自己的errno变量, 不同线程之间不会互相影响。

Original: https://www.cnblogs.com/kovogo/p/15535780.html
Author: kovogo
Title: 写给初学者的Linux errno 错误码机制

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/524383/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 用python实现markdown转html

    1. 前言 现在markdown已经是非常常用的记录工具了,整齐的排版、代码高亮、图片表格样样齐全,同时也支持html标签,是非常好用的一种工具(语法)。 那么今天来分享一下使用p…

    Linux 2023年6月14日
    0131
  • jenkins pipeline中获取shell命令的输出

    //获取标准输出//第一种result = sh returnStdout: true ,script: ” Original: https://www.cnblogs…

    Linux 2023年5月28日
    093
  • 命令行下Git调用IDEA的diff功能

    本文将介绍, 如何在命令行下, 让git diff命令调用IDEA的diff功能! IDEA diff IDEA虽然是一个图形化工具, 其实也提供了极少一部分命令行接口, 将IDE…

    Linux 2023年6月7日
    0116
  • 三系统删除与恢复引导(windows,Ubuntu,deepin)

    三系统的删除与引导修复 一、情况说明: 相信能找到我这篇随笔的朋友估计也是我和一样作死装了三个系统,例如我的(Window10,Ubuntu,deepin) 从左往右为我装系统的顺…

    Linux 2023年6月14日
    0102
  • 【Python】**kwargs和takes 1 positional argument but 2 were given

    Python的函数定义中可以在参数里添加kwargs——简单来说目的是允许 添加不定参数名称的参数,并作为 字典传递参数。但前提是——你必须提供 参数名**。 例如下述情况: 1 …

    Linux 2023年6月13日
    0113
  • PHP实现无限级分类

    $array = array( array(‘id’ => 1, ‘pid’ => 0, ‘name’ => ‘河北省’), array(‘id’ => 2…

    Linux 2023年6月7日
    069
  • anaconda创建虚拟环境

    anaconda创建虚拟环境 1·查看当前存在的虚拟环境 conda env list 或者 conda info -e 2·创建虚拟环境,环境名重要 conda create -…

    Linux 2023年6月14日
    0101
  • 每天一个 HTTP 状态码 200

    200 OK 表示请求成功,一切安好… 200 OK 话不多说,这个状态码应该是最最最常用的了,无人不知,无人不晓;就是表示请求成功的意思, 你若安好,便是晴天。 摘自…

    Linux 2023年6月7日
    0105
  • KMP分析证明

    引用后缀的目的: “ABBABA” 如果说ABA里面组成的AB是答案组成部分的开头,那么AB后面的字符一定是和模式串开头的第三个字符一样,如果不一样一定不是…

    Linux 2023年6月7日
    067
  • linux三剑客试题汇总

    1、找出/proc/meminfo文件中以s开头的行,至少用三种方式忽略大小写 2、显示etc目录下以root,centos或者user开头的信息 3、找出/etc/init.d/…

    Linux 2023年5月27日
    0112
  • redis订阅关闭异常解决

    redis订阅关闭异常解决 应用程序模块订阅redis运行一段时间出现一直重连Redis服务,日志如下: 2019-04-28 10:06:17,551 ERROR org.spr…

    Linux 2023年5月28日
    0115
  • Java类初始化顺序小结

    第一种情况(单一类) 测试结果 静态变量 静态&…

    Linux 2023年6月7日
    0108
  • gcc/g++与动静库以及gdb

    gcc/g++ 程序转换为二进制 总共需要经过4个大步骤:1.预处理,2.编译,3.汇编,4.链接。 想要更深刻的了解它,可以通过Linux去深刻的了解他们。 先创建.C文件 并且…

    Linux 2023年6月13日
    093
  • Vue3 封装 Element Plus Menu 无限级菜单组件

    本文分别使用 SFC(模板方式)和 tsx 方式对 Element Plus el-menu 组件进行二次封装,实现配置化的菜单,有了配置化的菜单,后续便可以根据路由动态渲染菜单。…

    Linux 2023年6月7日
    0148
  • Xshell配置ssh免密码登录-密钥公钥(Public key)与私钥(Private Key)登录【已成功实例】

    本文转自https://blog.csdn.net/qjc_501165091/article/details/51278696 ssh登录提供两种认证方式:口令(密码)认证方式和…

    Linux 2023年5月28日
    090
  • Tomcat

    Tomcat Tomcat tomcat简介 tomcat的用处 部署tomcat 测试访问 访问Host Manager界面 访问Server Status tomcat简介 T…

    Linux 2023年6月6日
    0137
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球