QSerialPort cannot open tty after application has previously been run by `root` [duplicate]

僤鯓⒐⒋嵵緔 提交于 2020-01-16 01:42:49

问题


I have an application (using QSerialPort) that reads and writes from a serial port. When I run this application as the root user, then run it again as a non-root user, I am no longer able to write to the serial port, receiving the following error:

QIODevice::write (QSerialPort): device not open

The non-root user is in the dialout group, and the permissions on the /dev/tty** file in question appear to be unchanged:

crw-rw---T 1 root dialout ......

Weirdest of all, I do not get an error when I simply use my shell to write to the file as the non-root user:

$> echo "foo bar baz" >> /dev/ttyS0
$> echo $?
0

The only thing I've found that appears to fix the problem is rebooting the machine.

What could possibly be going on here?

I'm on Debian 7.


回答1:


Seems, you should remove the lock file from the /var/lock directory (please, search himself), before opening a device with non-root user.




回答2:


Update: this is a bug in Qt, and will be fixed in version 5.6.2, which is due for release later this month.

On Linux and Mac, QSerialPort creates a lock file in /var/lock/ when opening a serial port. The lockfile has permissions 0644, i.e. only the creator of the file can write to it.

If the process that opened the serial port dies or if the serial port is somehow improperly closed by any other means, the lock file will not be deleted. The lockfile contains the PID of the process that opened the serial port; if the process is no longer running, Qt will attempt to simply take possession of the lock, changing the PID in the file.

However, since the lockfile has 0644 permissions, if the improperly-closing process was run by root, the new process will be unable to delete or overwrite the lockfile, resulting in a permissions error.

This is fixed for version 5.6.2.

Note that QSerialPort does clean up after itself: when its destructor is called, the port is closed and the lockfile is deleted. However, by default, Qt does not call object destructors when SIGTERM or SIGINT causes the program to exit. (Personally, I think this is also a bug, but I recognize that this is more a matter of opinion.)

Also see the suggested dupe question. As can be seen from this question, the current behavior is actually an improvement--previously, the application would simply hang!



来源:https://stackoverflow.com/questions/37335986/qserialport-cannot-open-tty-after-application-has-previously-been-run-by-root

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!