How do I lock files using fopen()?
I would strongly disagree with the claim that fopen
is prefered over open
. It's impossible to use fopen
safely when writing a file in a directory that's writable by other users due to symlink vulnerabilities/race conditions, since there is no O_EXCL
option. If you need to use stdio on POSIX systems, it's best to use open
and fdopen
rather than calling fopen
directly.
Now, as for locking it depends on what you want to do. POSIX does not have mandatory locking like Windows, but if you just want to ensure you're working with a new file and not clobbering an existing file or following a symlink, use the O_EXCL
and O_NOFOLLOW
options, as appropriate. If you want to do cooperative locking beyond the initial open, use fcntl
locks.
In Linux, if you need a file descriptor (e.g., to pass to a file-locking primitive), you can use fileno(FILE*)
to retrieve it. After retrieving the file descriptor, you can use it as if it had been returned by open
.
For example, instead of
int fd = open("myfile.txt", flags);
int result = flock(fd, LOCK_SH);
you could equally well do this:
FILE* f = fopen("myfile.txt", "r");
int result = flock(fileno(f)), LOCK_SH);
Note that fileno
is defined in the POSIX standard, but not in C or C++ standards.
As for your second question, the Linux open()
man page has this to say:
The solution for performing atomic file locking using a lockfile is to create a unique file on the same file system (e.g., incorporating hostname and pid), use link(2) to make a link to the lockfile. If link() returns 0, the lock is successful. Otherwise, use stat(2) on the unique file to check if its link count has increased to 2, in which case the lock is also successful.