The standard lock-file technique uses options such as O_EXCL
on the open()
call to try and create the file. You store the PID of the process using the lock, so you can determine whether the process still exists (using kill()
to test). You have to worry about concurrency - a lot.
Steps:
- Determine name of lock file based on name of FIFO
- Open lock file if it exists
- Check whether process using it exists
- If other process exists, it has control (exit with error, or wait for it to exit)
- If other process is absent, remove lock file
- At this point, lock file did not exist when last checked.
- Try to create it with
open()
and O_EXCL
amongst the other options.
- If that works, your process created the file - you have permission to go ahead.
- Write your PID to the file; close it.
- Open the FIFO - use it.
- When done (
atexit()
?) remove the lock file.
Worry about what happens if you open the lock file and read no PID...is it that another process just created it and hasn't yet written its PID into it, or did it die before doing so? Probably best to back off - close the file and try again (possibly after a randomized nanosleep()
). If you get the empty file multiple times (say 3 in a row) assume that the process is dead and remove the lock file.
You could consider having the process that owns the file maintain an advisory lock on the file while it has the FIFO open. If the lock is absent, the process has died. There is still a TOCTOU (time of check, time of use) window of vulnerability between opening the file and applying the lock.
Take a good look at the open()
man page on your system to see whether there are any other options to help you. Sometimes, processes use directories (mkdir()
) instead of files because even root can't create a second instance of a given directory name, but then you have issues with how to know the PID of the process with the resource open, etc.