lseek/write突然返回-1,errno = 9(错误的文件描述符)

Ger*_*nis 5 c file-io handle seek

我的应用程序用于lseek()寻找写入数据的所需位置.该文件使用成功打开open()和我的应用程序能够使用lseek()write()大量的时间.

在给定的时间,对于某些用户而且不易重现,lseek()返回-1,其中errno包含9.文件在此之前未关闭且文件句柄(int)未重置.

在此之后,创建另一个文件; open()再好,lseek()write()再次工作.

更糟糕的是,这个用户再次尝试了完整的序列,一切都很顺利.

所以我的问题是,操作系统可以出于某种原因为我关闭文件句柄吗?什么可能导致这个?某种文件索引器或文件扫描程序?

解决这个问题的最佳方法是什么; 这个伪代码是最好的解决方案吗?(别介意代码布局,会为它创建函数)

int fd=open(...);
if (fd>-1) {
  long result = lseek(fd,....);
  if (result == -1 && errno==9) {
      close(fd..); //make sure we try to close nicely
      fd=open(...);

      result = lseek(fd,....);
  }
}
Run Code Online (Sandbox Code Playgroud)

有人遇到类似的事吗?

总结:对于给定的fd,文件搜索和写入工作正常,并且在没有理由的情况下突然返回errno = 9.

nos*_*nos 7

所以我的问题是,操作系统可以出于某种原因为我关闭文件句柄吗?什么可能导致>这个?某种文件索引器或文件扫描程序?

不,这不会发生.

解决这个问题的最佳方法是什么; 这个伪代码是最好的解决方案吗?(别介意代码布局,会为它创建函数)

不,最好的方法是找到错误并修复它.

有人遇到类似的事吗?

我已经看到fds多次搞砸了,在某些情况下导致了EBADF,而在其他情况下爆炸性地爆发了,它一直是:

  • 缓冲区溢出 - 溢出的东西,并将一个无意义的值写入'int fd;' 变量.
  • 愚蠢的错误,因为某些角落案件有人 if(fd = foo[i].fd)在他们的意思时做了if(fd == foo[i].fd)
  • 线程之间的竞争条件,某些线程关闭了其他线程想要使用的错误文件描述符.

如果您可以找到重现此问题的方法,请在"strace"下运行您的程序,以便了解最新情况.


Spa*_*rky 1

我不知道你有什么类型的设置,但我认为以下场景可以产生这样的效果(或者类似的效果)。我还没有对此进行测试来验证,所以请持保留态度。

如果您要打开的文件/设备作为服务器应用程序(例如 NFS)实现,请考虑如果服务器应用程序宕机/重新启动/重新引导会发生什么情况。文件描述符虽然最初在客户端有效,但可能不再映射到服务器端的有效文件句柄。这可能会导致一系列事件,其中客户端将获得 EBADF。

希望这可以帮助。