为什么fopen()或open()使用errno而不是只返回错误代码?

Jee*_*tel 9 c linux errno linux-kernel

在通常情况下, open()返回新的文件描述符,如果发生错误,errno则返回-1,在这种情况下,设置适当.

我不明白为什么errno这里使用这种机制?什么是这里的目的?为什么我们不能用一些否定的回报映射所有错误?

喜欢

fd = open("/dev/tty0", O_RDWR | O_SYNC);
if(fd == -1)
  printf("this is EACCES error");
else if (fd == -2)
    printf("this is EPERM error");
Run Code Online (Sandbox Code Playgroud)

errno 机制有什么好处吗?如果是,那么我想知道/理解然后在其他事情我也可以使用这种机制.

Jen*_*edt 13

因为fopen返回a,FILE*你不能指望它在该指针中返回错误代码:指针的唯一"特殊"值是0.

正如您所观察到的那样,open这种限制并不成立.事实上,作为linux的系统完全按照你在低级别提出的建议.如果出现问题,系统调用将返回负面错误代码.那个(否定的)代码然后errno由浅用户空间包装器插入,然后返回-1指示应用程序的错误.

这样做的原因纯粹是历史性的.在过去很久没有线程,errno仍然只是一个简单的全局变量.那时所选择的策略没有太大的开销,并且似乎是在OS和应用程序之间进行通信的可接受方式.由于这些接口基本上不能在不破坏大量代码的情况下进行更改,因此我们将坚持使用errno作为线程本地的伪变量.

这并不理想,但开销并不像听起来那么糟糕,因为这些显然是错误指示,只能在特殊情况下发生.


fvu*_*fvu 9

对我来说,优点是以这种方式统一获取错误信息,返回一些负值可以正常工作,open因为它返回一个整数,但fopen返回一个,FILE *所以必须在那里使用另一种技术.

  • 一个指针 - 至少在我所知的架构上 - 没有符号的概念,它可以(理论上)覆盖"基础无符号整数"的整个范围(即32位点可以从0x00000000到0xffffffff).并且`NULL`只是表示"嘿,这失败了,看看errno看看出了什么问题" (6认同)