我有一个应用程序(使用QSerialPort
)从串行端口读取和写入。当我运行这个应用程序时root
用户,然后以非 root 用户身份再次运行它,我不再能够写入串行端口,收到以下错误:
QIODevice::write (QSerialPort): device not open
非 root 用户位于dialout
组,以及权限/dev/tty**
有问题的文件似乎没有改变:
crw-rw---T 1 root dialout ......
最奇怪的是,我确实not当我仅使用 shell 以非 root 用户身份写入文件时出现错误:
$> echo "foo bar baz" >> /dev/ttyS0
$> echo $?
0
我发现唯一可以解决该问题的方法是重新启动机器。
这里可能发生了什么?
我使用的是 Debian 7。
Update:这是 Qt 中的一个错误,将在 5.6.2 版本中修复,该版本将于本月晚些时候发布。
在 Linux 和 Mac 上,QSerialPort
创建一个锁定文件/var/lock/
打开串行端口时。锁文件有权限0644
,即只有文件的创建者可以写入它。
如果打开串行端口的进程死亡或者串行端口通过任何其他方式以某种方式不正确地关闭,则锁定文件将不会被删除。锁文件包含打开串口的进程的PID;如果进程不再运行,Qt 将尝试简单地占有锁,更改文件中的 PID。
然而,由于锁文件有0644
权限,如果不正确关闭的进程是由root
,新进程将无法删除或覆盖锁定文件,从而导致权限错误。
This is 已修复版本 5.6.2 https://bugreports.qt.io/browse/QTBUG-36983.
注意QSerialPortdoes自身清理:当调用其析构函数时,端口将关闭并删除锁定文件。然而,默认情况下,Qtnot调用对象析构函数时SIGTERM
or SIGINT
导致程序退出。 (我个人认为这是also一个错误,但我认识到这更多是一个意见问题。)
另请参阅建议的欺骗问题 https://stackoverflow.com/q/22885116/1858225。从这个问题可以看出,现在的行为其实是一个改进--以前,应用程序只需hang!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)