开放系统调用失败

在我打开()系统调用之后

fd = open(dir, O_RDONLY, 0); printf("fd=%d\n", fd); if (fd < 0) perror("open"); 

我得到fd = -2和perror(“打开”)打印“成功”!

这是什么意思,为什么发生?

好吧,我决定以不同的方式testing我的代码,如下所示:

 if ((fd = open(dir, O_RDONLY, 0)) >= 0) { /* do smthg */ } else { perror("open"); printf("fd=%d\n", fd); } 

我认为,我build议的代码的最后一部分,不与errno值的中间函数交替冲突,但我仍然得到fd = -2(???)和perror()打印“成功”。 !

有些东西正在重新设置printf中的errno。 尝试评论一下,你会看到一些有意义的东西。

从errno手册页:

一个常见的错误是做

  if (somecall() == -1) { printf("somecall() failed\n"); if (errno == ...) { ... } } 

errno在从somecall()返回时不再需要它的值(也就是说,可能已经被printf(3)改变了)。 如果errno的值应该保存在库调用中,则必须保存它:

  if (somecall() == -1) { int errsv = errno; printf("somecall() failed\n"); if (errsv == ...) { ... } } 

从“开放”

返回值

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

你会注意到-2不是应该在失败时返回的-1,尽管manpage也是这样说的

给定一个文件的路径名,open()返回一个文件描述符,一个小的非负整数,用于后续的系统调用

上次调用的错误代码存储在errno全局变量中。 perror使用此错误代码来查找错误消息字符串。 当你进入perror("open")你正在读取由printf调用设置的错误。 没有打印您的fd=...消息的错误,所以错误代码设置为0,即Success 。 你应该保存这样的错误代码:

 fd = open(dir, O_RDONLY, 0); prev_error = errno; printf("fd=%d\n", fd); errno = prev_error; if (fd < 0) perror("open"); 

或者只是重新排序代码,以便在printf之前调用perror