学习Linux系统编程-Day(6)

1.有些库函数的功能其实是对底层系统调用的进一步封装和优化,使得它们更加方便易用,也有另外一些库函数的实现与系统调用无关

2.在绝大部分Linux上都提供了对GNU C Library的实现(glibc),有多种方法可以查看搭载Linux操作系统的计算机上的glibc版本,其中比较可靠的是使用gnu_get_libc_version()函数来查看glibc版本。
在这里插入图片描述
在这里插入图片描述
最后在终端中输出我的计算机搭载的是2.23版本的glibc。

3.无论如何,除极少部分一定可以成功的系统调用以外(getpid(), exit()),一定要对系统调用失败的场景做异常处理。Linux系统中对于异常处理遵循的惯例是这样的:
(1)系统调用时如果成功则返回一个非负值
(2)如果失败,那么就找到对应失败情况的errno常量将其取反返回一个负值到C语言外壳函数
(3)外壳函数再次取反此常量并用此编号设置errno变量(这是一个全局整型变量,表示当前出错的情况)并返回-1表示调用失败

由此可见,如果想要知道系统调用是否成功以及失败情况下的出错原因,那么就要好好利用errno这样的一个全局变量来判断出错情况到底是哪一种错误。使用时要遵循这样的范式:
在这里插入图片描述
先根据外壳函数返回值是否为-1判断是否调用失败再去找errno来确定失败的具体原因

这样做的原因是errno作为全局变量,只有系统调用失败时它的值会被根据错误情况重置,其他情况下维持上一次出错的情况不变。为了确保异常处理时读取到的errno反映的是当下的错误而非之前的残留错误信息,就必须先确定这次发生了调用失败,即外壳函数返回值是-1。

而有一些特殊的系统调用即使成功了外壳函数也会返回-1,这时候可以提前先将errno置为0,执行调用后发现errno非0,那么就发生了错误。

现在我们获取到了系统调用错误和它对应的编号,下面就是使用errno编号来确定错误的原因。这时候就要用到perrorstrerror函数了。这两个函数的方法都是根据errno的值来返回相应的错误信息,只不过perror自动去获取errno的值,strerror需要编程者手动传入errno的值。详情看这里:perror函数strerror函数

4.库函数的异常处理一部分和上面的系统调用很像,因为
(1)有一部分的库函数其实是对系统调用的封装(wrap)和优化,这部分库函数异常情况下也返回-1,也会设置errno,和系统调用的处理无异。
(2)还有一些库函数虽是对系统调用的封装,但是错误返回的处理有差异,比如返回值不是-1而是NULL(0),但errno也照常设置,这些也可以使用perror和strerror来处理。
(3)还有一些库函数根本不设置errno,这些就不能用perror和strerror来处理了。

猜你喜欢

转载自blog.csdn.net/zzy980511/article/details/115131140