The goal is to "lock" access to a serial device or other Linux device, to ensure exclusive access to the device while it's in-use. This prevents, for example, two programs both opening the same serial device and "competing" to read bytes from the device.
The advice has been to use SYSV-style UUCP device lock files such as /var/lock/LCK..ttyS1
. That is what is recommended by Linux Serial HOTWO: Locking Out Others. It is also documented in the Filesystem Heirarchy Standard. It is implemented by serial terminal programs such as gtkterm, picocom. There are libraries such as liblockdev
and liblockfile
to support this (although the implementation details differ between these two libraries).
However, I have found Debian bug #734086, which says on Linux, SYSV-style UUCP device locks are deprecated, and flock()
advisory locks should be used instead.
However, I can't find a reliable document source to describe deprecation of these SYSV-style UUCP device locks, and recommendation of flock()
, other than that Debian bug itself.
I've also found ioctl(fd, TIOCEXCL)
which is used by the screen
utility to lock a terminal.
Which is the modern "best practice" for locking serial ports and other devices in Linux? Where can we find up-to-date documentation describing this?
As far as I can tell, using flock(fd, LOCK_EX | LOCK_NB)
locking of serial ports or other devices is probably the best the way to go in Linux, following Debian's lead in Debian bug #734086. Note that the original advocate of this Debian change, Roger Leigh, has moved away from Debian and Linux and onto FreeBSD in 2014/2015 (see his comments here). But Debian seems to be sticking with the flock()
method, so that's worth something.
However given how poorly this change has been communicated to the broader Linux community at this point, it could be good to support the older SYSV-style UUCP device lock files (/var/lock/LCK..ttyS1
) as a compile-time option, for use in systems still using the older lock method.
E.g. picocom has now changed to using the flock()
method, with a compile-time optional selection of SYSV-style UUCP device lock files.
Another answer on StackOverflow describes two methods:
ioctl(fd, TIOCEXCL)
flock(fd, LOCK_EX | LOCK_NB)
methodIt says "An application can choose to do one, or both", further explaining:
The reason to use both, is to detect if another process has already opened the device without putting it into exclusive mode, but has hopefully set the advisory lock. In that case, the
open()
andioctl()
both succeed, but theflock()
fails.
So, it is worth implementing ioctl(fd, TIOCEXCL)
additionally.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With