Search code examples
lockingposixglibcflockfcntl

flock() vs. fcntl() semantics in glibc


Related: one, two

It's stated that flock() (BSD-locks) and fcntl() (POSIX record-level locks) gives the user incompatible semantics, particularly, in regards of lock release.

However, in glibc flock() is implemented in terms of POSIX fcntl(). (I checked this on official git repo, here is just a viewable link)

https://code.woboq.org/userspace/glibc/sysdeps/posix/flock.c.html#18

/* This file implements the flock' function in terms of the POSIX.1fcntl' locking mechanism. In 4BSD, these are two incompatible locking mechanisms, perhaps with different semantics? */

How can these facts hold together?


Solution

  • On Linux, flock is a system call. flock locks and fcntl locks are independent and do not interfere with each other (on local file systems at least).

    The glibc source file sysdeps/posix/flock.c is not actually used on Linux. The real implementation is the system call wrapper generated from this line in sysdeps/unix/sysv/linux/syscalls.list:

    flock             -       flock           i:ii    __flock         flock
    

    OFD locks are yet another kind of locks, but they do interact with POSIX record locks. However, they have more reasonable behavior with multiple threads, and closing one descriptor does not release all locks for the same underlying file held by the same process (which makes POSIX record locking so difficult to use in multi-threaded processes).