检测打开的文件/设备是不是已被替换/删除

Posted

技术标签:

【中文标题】检测打开的文件/设备是不是已被替换/删除【英文标题】:Detect if an open file/device has been replaced/deleted检测打开的文件/设备是否已被替换/删除 【发布时间】:2011-09-26 05:18:17 【问题描述】:

假设Linux下的情况如下:

一个进程不断地从 USB 串行转换器设备 (/dev/ttyUSB0) 中读取数据。该设备突然拔下并再次插入(或出于某种原因正在重置自身)。进程继续拥有/dev/ttyUSB0 的有效文件句柄,但不会从设备接收任何数据,除非进程重新打开设备(因为 udev 已删除并重新创建设备节点)。

是否有一种直接方法来检测这种情况(即不是间接通过检测数据流超时),以便进程知道它必须重新打开设备?使用stat()监控/dev/ttyUSB0的修改时间可靠吗?

其他细节:

进程使用标准open()函数打开设备文件。

/dev 是由udev 控制的tmpfs

注意:我确实想为此使用任何 udev 规则,并且更喜欢直接在流程中实施的解决方案。

【问题讨论】:

inotify 【参考方案1】:

如果 USB 设备是热拔出的,设备上的操作将开始失败并显示-EIO;您可以检测到这一点并采取适当的措施。

【讨论】:

谢谢,是的,拔掉电源后出现这个错误。我是否可以安全地假设在获取 EIO 时文件描述符已变得无用,或者是否存在导致 临时 EIO 以及文件描述符稍后可以正常工作的情况?目前我已经实现了一个逻辑,它在使用 EIO 进行 read() 之后完全关闭、重新打开和重新初始化设备(调制解调器)。 @Udo: 可能 - 例如,如果您的硬盘出现某种暂时的机械错误,您可能会在一次读取时得到 -EIO,即硬盘恢复,下一次读取成功。但是这不太可能,如果您看到 -EIO,重新初始化设备可能是正确的做法。【参考方案2】:

如果设备节点实际上正在被删除并重新创建(如果您有 udev,我相信是这样),那么您应该能够使用 inode 编号来判断这种情况何时发生。

只需在打开的文件描述符上调用fstat(),在/dev/ttyUSB0 上调用stat(),然后比较两个struct stats 的st_ino 字段。

如果它真的有效,请告诉我。 :-)

【讨论】:

这个策略对我有用。我在 python 中实现了它:github.com/hrchu/python-scsi/blob/… 更新:对于某些设备类型,设备文件的 inode 不会改变。在我的盒子里,USB大容量存储设备的设备文件即使在重新插入后总是具有相同的inode。【参考方案3】:

我认为FAMgamin 会检测到这些事件。

【讨论】:

以上是关于检测打开的文件/设备是不是已被替换/删除的主要内容,如果未能解决你的问题,请参考以下文章

Android检测设备是不是有root权限

如何检测iOS设备是否处于静默模式?

检测浏览器/设备是不是支持双击事件

iOS 开发者账号下100台关联设备UDID如何删除替换

检测android联系人是不是已被删除

从设备中删除单个发送的远程通知