如何使用Posix / C函数检查串口是否已在Linux中打开?我想检查串口的状态,以检查串口是否打开。
我想知道哪些方法适用于:
检查文件描述符以查看串口是否已打开且
检查串口文件名以查看串口是否已打开,以下示例为" / dev / ttyUSB0"
< / LI> 醇>-
verifyta -u
我想有一个&#34;标准&#34;这样做的方式,这就是我想要达到的目的。
答案 0 :(得分:2)
所述问题有两个方面,实际上需要两种不同的解决方案:
使用串行端口的应用程序或服务守护程序应排除其他进程同时使用该端口。
有两种方法可以执行此操作:独占模式和咨询锁定。应用程序可以选择执行一个或两个。
打开设备后,使用ioctl(fd, TIOCEXCL)
将串口置于独占模式。在描述符关闭或流程问题ioctl(fd, TIOCNXCL)
之前,任何打开设备的尝试都将失败并显示EBUSY
错误代码。
打开设备后,使用flock(fd, LOCK_EX | LOCK_NB)
尝试在打开的设备上放置一个独占咨询锁。其他进程仍然可以正常打开设备,甚至可以读取和写入设备,但尝试在其上放置一个建议群锁将会导致EWOULDBLOCK
失败(或阻止直到解锁或关闭,如果放置没有LOCK_NB
)。
上述两种方法之间的区别在于后者是合作的,允许其他过程打开设备;而前者不允许进一步开放。
使用两者的原因是检测另一个进程是否已经打开设备而不将其置于独占模式,但希望设置咨询锁。在这种情况下,open()和ioctl()都成功,但flock()失败。
(我们可以使用下面讨论的这个问题的第二个方面 - 在打开设备后,将其设置为独占模式,甚至获得对它的独占锁定,以检测其他进程是否有设备打开但不是独占的或者锁定。就个人而言,我不会打扰;我确实希望用户只在他们的系统上使用理智的应用程序。如果他们真的这样做,我希望他们有理由,所以我宁愿允许奇怪的情况。标准实用程序绝对不应该出现。)
应用程序或守护程序可以使用lsof
(来自lsof包)来检查是否有任何进程打开了指定的文件或设备。
我们的想法是使用root权限运行等效的LANG=C LC_ALL=C lsof -F -p DEVICE
。输出将包含零个或多个行。以p
开头的行(紧接着是PID和换行符\n
)指定了DEVICE
打开的进程。 (每个这样的行后跟一行或多行以f
开头,描述该进程中的哪个描述符引用该设备。)
如果应用程序或守护程序没有root权限,则需要安装setuid root的帮助程序。它提供有一个或多个设备名称。帮助程序使用stat()
和S_IFCHR(st_mode)
验证每个人是一个字符设备(以避免在安全漏洞中使用帮助程序);如果是,则执行上述命令。在Linux中,此类帮助程序通常安装在/usr/lib/APPLICATION/
中,其中APPLICATION
是应用程序或守护程序的名称。
应用程序或守护程序本身可以通过popen("/path/to/helper 2>/dev/null", "r")
执行帮助程序,并使用例如fscanf()
读取输入。 (请记住使用pclose()
获取状态,并使用例如(WIFEXITED(status) && !WEXITSTATUS(status))
来验证命令是否成功。
请注意,辅助程序方法允许从Linux更容易地移植到其他POSIXy系统,只需将辅助程序替换为适合新系统的程序即可。即使它没有作为setuid root安装,它也为系统维护者提供了一个简单的钩子来修改应用程序或服务的行为,如果需要的话。我个人热烈推荐帮助方法。