打开系统调用失败

时间:2011-02-14 14:15:08

标签: linux

我将open()系统调用称为

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

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

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

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

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

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

4 个答案:

答案 0 :(得分:3)

有些东西正在重置printf中的errno。尝试将其评论出来,你会从perror中看到一些有意义的东西。

答案 1 :(得分:3)

来自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 == ...) { ... }
       }

答案 2 :(得分:1)

从“开放”的联机帮助页

  

返回值

     

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

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

  

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

答案 3 :(得分:0)

最后一次调用的错误代码存储在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");

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