当前位置: 首页 > 文档资料 > FreeBSD 开发手册 >

11.4 返回值

优质
小牛编辑
119浏览
2023-12-01

如果系统调用没有返回一些数值, 那么在很多情况下并没有太多用处。这些返回值包括: 一个打开的文件的文件描述符、 一个从缓存里读取的字节, 或者系统时间等等。

此外, 如果错误出现, 系统需要通知我们。 这些错误包括: 文件不存在、系统资源耗尽,或者我们传递了一个错误的参数等等。

11.4.1 联机手册

传统情况下,寻找 UNIX® 下不同系统调用的地方是手册页。 FreeBSD 会在手册页的第2节描述系统调用,有的时候会在第三节。

例如, open(2) 所描述的:

如果执行成功, open() 将返回一个表示文件描述符的非负整数。 如果执行失败, 它会返回 -1 并且设置 errno 来标识错误。

刚刚接触 UNIX 和 FreeBSD的汇编程序员或许会马上提出一个难题: 那些 errno 在哪里?我怎么才能找得到它们?

注意: 这些在手册页中展示的信息仅针对 C 语言。 汇编程序员则需要更多的信息。

11.4.2 返回值在哪里?

很不幸, 它有依赖性。。。 大部分系统调用都使用 EAX 但不是所有的系统调用都会这样。 不过当第一次使用系统调用的时候,直接在 EAX 检查返回值是个不错的查找方法。 如果它不在那里, 你再需要深入调查。

注意: 我知道一个 SYS_fork 的系统调用将返回值存放在 EDX 中。而我曾经用过的其他调用都使用 EAX 存放返回值, 但是我目前还没有用过所有的系统调用。

提示: 如果你哪里都找不到答案, 去学习 libc 代码吧,去看看它如何访问内核的。

11.4.3 哪里可以找到 errno?

实际上,没什么地方。。。

errno 不属于 UNIX 内核, 而是 C 语言中的一部分。 当直接访问内核服务的时候, 错误代码返回到 EAX 中,也就是那个通常用来保存返回值得寄存器。

这个处理方式非常有意义。 如果这里没有错误, 这里就没有错误代码。 如果这里有错误,这里就没有返回值。 使用一个寄存器可以涵盖以上任意一种情况。

11.4.4 判断错误的出现

当使用标准的 FreeBSD 调用规范时,标志位 carry flag 在程序运行成功时被清零,在失败时被置位。

当使用 Linux emulation 模式的时候, EAX 中的有符号数反映了执行结果。 当为非负数时,表示执行成功, 并包含了返回值。 如果失败, 返回值即为负数, 如 -errno