tags:

views:

827

answers:

3

I have a program running as root on Linux, talking to a tty (actually an LCD implemented as a tty). The device for what it's worth is /dev/ttyUSB0. I'd like to have my program that writes to this device be able to have exclusive access to the device, so as to not have any interference from other instances of the program running at the same time.

I see that there's a ioctl option called TIOCEXCL which will prevent additonal open's of the device to wit "multiple open() calls to the same file will succeed unless the TIOCEXCL ioctl is issued. This will prevent additional opens except by root-owned processes." I tested this and it works just as advertised: if a non-root user tries to open /dev/ttyUSB0 (once I changed the permissions) then the open fails with something like "device busy" and if a root user tries to open it, it works.

What I ideally want is a way to this exclusive access to the tty to work for root users. So I'd have multiple root users using the program that writes to the LCD, but somehow their access to the LCD (tty) would be serialized. Apparently the TIOCEXCL ioctl option will not work for me since it doesn't stop root users from opening an already-opened tty device.

I guess there are a number of options here, but I am reaching out to all ya'll to see if you might have other thoughts or suggestions.

  1. Maybe I'm missing something about using TIOCEXCL...

  2. Maybe there's some other way via open() or ioctl() or what-not to get exclusive access.

  3. If there was some way I could detect that some other process has the device open, I could just wait and retry. I know about lsof but I'm loath to invoke it from inside this program just to learn this. And there are race conditions with that. (Maybe I can get over that? :) )

  4. I could implement locking like apparently used to be done to get exclusive access to tty devices.

Update 1:

Since the only program writing to the LCD device is mine, I am inclined to do something like the following (pseudo-code) to lock inside the code:

f = open("/dev/ttyUSB0", O_RDWR)
flock(f, LOCK_EX)

// do any ioctl's, etc.

// do any write's

// sleep a tad to not flash messages too fast on LCD
nanosleep({0, 250000000}, NULL)

flock(f, LOCK_UN)
close(f)
+3  A: 

Perhaps this discussion on LKML: [TTY] exclusive mode question can help you!

Johannes Weiß
A: 

Answer: Root always has access. Always.

Perhaps if you said more about what else was grabbing the device, or what you fear might grab the device...

dwc
My write-to-lcd program is potentially called from multiple processes at the same time so there may be multiple instances running at once. Although I am not positive, I think the combo of the LCD device and the Linux TTY support does not reliably deliver all the messages to the LCD in this case.
Chris Markle
A: 

I would encourage you to look into UUCP locking. There should be a library on Linux that implements it, but if not, it's fairly easy to implement. I've used it extensively in similar situations where I don't want multiple instances of the same program to step on each other.

As a side note, perhaps you should rethink the architecture of your solution. The process that accesses the LCD/ttyUSB0 could act as a server and handle messages from the client processes that need to write to the LCD. This would require some form of IPC. It may be overkill for your project.

Keep in mind that any solution you come up with will only work if all processes that access the device conform to the protocol. If you are worried about a rogue process running as root then you may be stuck with hacking the kernel to get the solution you want.

Rob Jones