stdio 是不是总是设置 errno?

Posted

技术标签:

【中文标题】stdio 是不是总是设置 errno?【英文标题】:Does stdio always set errno?stdio 是否总是设置 errno? 【发布时间】:2012-05-27 04:14:52 【问题描述】:

stdio 流遇到错误(但不是EOF)时,将设置流的错误指示符,以便ferror() 返回非零值。我一直认为errno 提供了更多信息。但是我怎么知道呢?

一些功能的文档[例如。 man fopen under Linux] 表示errno 也将被设置。然而man fgets 根本没有提到errno。 glibc 信息页面令人放心:

除了设置与 流,对流进行操作的函数也在 与对文件进行操作的相应低级函数的方式相同 描述符。

但我不知道这个保证有多强。是C标准要求的吗?在 Visual C/C++ 中会发生什么?

【问题讨论】:

【参考方案1】:

C 标准本身不需要太多使用 errno WRT 到 stdio 函数;它指定了ferror(),但只提到了这一点

7.13.10.3 ferror 函数 ferror 函数测试stream 指向的流的错误指示符。当且仅当为流设置了错误指示符时,ferror 函数才返回非零值。

来自 C99 草案:http://www.vmunix.com/~gabor/c/draft.html。在大多数情况下,使用的任何实际错误代码都是由实现定义的。

不过,Linux 上的 GNU C 库也符合 POSIX 规范:

http://pubs.opengroup.org/onlinepubs/9699919799/toc.htm

在这种情况下,它们的定义要好得多。例如,如果您查看fopen 的页面:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html

您会在错误下看到很多详细信息,包括具体的 errno 代码。

同样,几乎所有普通 linux 系统上使用的 GNU C 库都符合 POSIX 标准,因此您可以信赖这些信息;)。那些(在线)POSIX 手册页通常也比标准的 linux 系统手册页更详细(同时阅读)。

WRT 到其他(非 POSIX)平台上的文件操作,它们将有自己的实现。不幸的是,这样的东西在标准 C 中并不是透明可移植的。不过,C++ 流确实有更标准化的错误处理。

【讨论】:

谢谢。 POSIX 定义非常有用。例如,根据他们的说法,“fgets”确实设置了 errno。我认为针对我的特殊情况的最佳策略是只为 POSIX 编写代码,然后在出现问题时解决 Windows 问题。 虽然 GNU 的 fopen() 设置了 errno,但 fread() 没有,即使 POSIX 指定了(使用 "CX"标签)。任何想法为什么? POSIX man page 至少没有提到这一点。不过,我注意到 linux 手册页根本没有提到 errno。【参考方案2】:

根据 C11 标准第 7.21 章(“stdio.h”),只有 fgetposfsetposftell 在发生错误时写入 errno

【讨论】:

以上是关于stdio 是不是总是设置 errno?的主要内容,如果未能解决你的问题,请参考以下文章

有名管道的非阻塞设置

python socket 超时设置 errno10054

模拟Linux修改实际有效和保存设置标识

Ajax:设置超时是不是总是覆盖浏览器的超时?

errno 在 VxWorks PPC 中总是返回零

为啥当我尝试将主键设置为无符号时出现 errno150