Imagine I have two processes trying to open the same file in read only mode. I want only one process to open the file and the other one to fail (essentialy a file lock). What is the difference between doing
if (open("name", O_RDONLY | O_EXCL | O_NONBLOCK, 0666) == -1 && EWOULDBLOCK == errno) {
...
}
and
int fd = open("name", O_RDONLY | O_EXCL, 0666);
if (flock(fd, LOCK_EX | LOCK_NB, 0666) && EWOULDBLOCK == errno) {
...
}
Is it the same? Does the above work at all as I expect? If not then what does O_EXCL do? Is there a way to make the above one work as I want?
CodePudding user response:
As the question What is the written-out word for O_EXCL cross-referenced by Erdal Küçük in a comment implies (if not states), the O_EXCL
flag is only of relevance if you are creating a file. Your other options to open()
do not create a file, so the use of O_EXCL
is irrelevant (harmless but not useful). Even if you were creating the file, it would not stop another program from opening the file for reading after the file is created but while other processes have the file open. Note that if the other program tries to create the file with O_EXCL
, then that other program will fail to create the file — that's what O_EXCL
is for.
You will need to use one of the advisory locking mechanisms — flock(2)
(found on Linux and BSD systems (and probably others) but not standardized by POSIX), or POSIX functions lockf()
or
fcntl()
.
All the programs accessing the file will need to agree on using the advisory locking. If someone runs cat name
, the cat
command will not pay any attention to the advisory locks on the file name
.
Some systems support mandatory file locking. When supported, this is activated by setting the SGID bit on the file while the group-execute bit is cleared. If the system supports mandatory file locking, it is likely the ls -l
would list an l
in the group-execute bit column; otherwise, it will likely report S
. So the permissions might show as either of these:
-rw-r-lr--
-rw-r-Sr--
The file locking functions should not be confused with flockfile()
which is for locking a single file stream in a multi-threaded program, not for locking files.