如何使用Posix/C函数检查Linux中是否已经打开了串口?我想检查串口的状态,以检查串口是否打开。
我想知道哪些方法适用于:
--
// This code is for example purposes only
int open_port()
{
int fd;
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0)
{
perror("open_port: Unable to open /dev/ttyf1 - ");
}
return fd;
} 我想有一种“标准”的方法来做到这一点,这就是我想要达到的目标。
发布于 2018-04-06 07:06:25
所述问题有两个方面,实际上需要两种不同的解决办法:
- After opening the device, use [`ioctl(fd, TIOCEXCL)`](http://man7.org/linux/man-pages/man4/tty_ioctl.4.html) to put the serial port into exclusive mode. Until the descriptor is closed, or the process issues `ioctl(fd, TIOCNXCL)`, any attempt to open the device will fail with `EBUSY` error code.
- After opening the device, use [`flock(fd, LOCK_EX | LOCK_NB)`](http://man7.org/linux/man-pages/man2/flock.2.html) to try and place an exclusive advisory lock on the open device. Other processes can still open the device normally, and even read and write to it, but trying to place an advisory flock lock on it will fail with `EWOULDBLOCK` (or block until unlocked or closed if placed without `LOCK_NB`).上述两种方法的不同之处在于,后者是合作的,允许其他进程打开设备;而前者不允许进一步打开。
使用这两种方式的原因都是为了检测另一个进程是否已经打开了设备,而没有将其设置为独占模式,但希望设置了建议锁。在这种情况下,open()和ioctl()都成功了,但是flock()失败了。
(我们可以使用下面讨论的这个问题的第二个方面-在打开设备之后,将其设置为独占模式,甚至获得对它的排他锁(-),以检测其他进程是否打开了设备,而不是独占或锁定。就我个人而言,我不会费心;我确实希望用户只在他们的系统上使用正常的应用程序。如果他们真的这么做的话,我希望他们有理由这么做,所以我更愿意允许这种奇怪的情况发生。它绝对不应该出现在标准实用程序中。)
lsof (来自lsof包)检查任何进程是否打开了指定的文件或设备。
这样做的目的是以根权限运行等效的LANG=C LC_ALL=C lsof -F -p DEVICE。输出将包含零行或多行。以p开头的行(紧接着是PID和换行符\n)指定了打开DEVICE的进程。(每一行后面都是以f开头的一行或多行,描述该过程中的哪个描述符引用了设备。)
如果应用程序或守护进程没有根权限,则需要安装setuid的助手程序。它提供了一个或多个设备名称。帮助程序验证每个字符设备都是使用stat()和S_IFCHR(st_mode)的字符设备(以避免在安全攻击中使用助手);如果是,则执行上述命令。在Linux中,此类帮助程序通常安装在/usr/lib/APPLICATION/中,其中APPLICATION是应用程序或守护进程的名称。
应用程序或守护进程本身可以通过popen("/path/to/helper 2>/dev/null", "r")执行助手,并使用例如fscanf()读取输入。(请记住使用pclose()获取状态,并使用例如(WIFEXITED(status) && !WEXITSTATUS(status))验证命令是否成功。
请注意,helper程序方法允许更容易地移植到来自Linux的其他POSIXy系统,只需将辅助程序替换为适合新系统的辅助程序。即使它不是作为setuid根安装的,如果需要的话,它也为系统维护人员提供了一个很容易修改应用程序或服务行为的钩子。我个人热烈推荐帮助者的方法。https://stackoverflow.com/questions/49636520
复制相似问题